{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Description" : "ArcGIS CloudFormation Template: Provisions a ArcGIS site with Portal for ArcGIS, ArcGIS Server, ArcGIS Data Store and ArcGIS Web Adaptor on an EC2 instance running Ubuntu Linux 14.04 LTS. **WARNING** You will be billed by AWS for the AWS resources if you create a stack from this template.",
  "Mappings" : {
    "RegionMap" : {
      "us-gov-west-1" : { "en" : "ami-f17010d2", "jp" : "ami-f17010d2"}
    }
  },
  "Parameters" : {
    "DeploymentBucket" : {
      "Description" : "S3 bucket for license files and SSL certificates",
      "Type" : "String",
      "AllowedPattern" : "[a-zA-Z][0-9a-zA-Z-_.]{2,62}",
      "ConstraintDescription" : "S3 bucket name must be between 3 and 63 characters and and must start with a letter."
    },
    "InstanceType" : {
      "Description" : "The EC2 instance type",
      "Type" : "String",
      "AllowedValues" : ["m3.medium","m3.large","m3.xlarge","m3.2xlarge",
                         "c3.large","c3.xlarge","c3.2xlarge","c3.4xlarge","c3.8xlarge",
                         "cc2.8xlarge",
                         "r3.large","r3.xlarge","r3.2xlarge","r3.4xlarge","r3.8xlarge",
                         "i2.xlarge","i2.2xlarge","i2.4xlarge","i2.8xlarge","hs1.8xlarge"],
      "Default" : "m3.xlarge"
    },
    "KeyName" : {
      "Description" : "The EC2 KeyPair to allow remote access to the instances",
      "Type" : "AWS::EC2::KeyPair::KeyName"
    },
    "ServerLicenseFile" : {
      "Description" : "ArcGIS for Server authorization file (must be uploaded to DeploymentBucket)",
      "Type" : "String",
      "AllowedPattern" : "[^\"]{1,1024}",
      "ConstraintDescription" : "S3 object key name must be between 1 and 1024 characters."
    },
    "PortalLicenseFile" : {
      "Description" : "Portal for ArcGIS authorization file (must be uploaded to DeploymentBucket)",
      "Type" : "String",
      "AllowedPattern" : "[^\"]{1,1024}",
      "ConstraintDescription" : "S3 object key name must be between 1 and 1024 characters."
    },
    "SiteAdmin" : {
      "Description" : "User name for ArcGIS Server site admin and Portal initial admin accounts",
      "Type" : "String",
      "Default" : "admin",
      "AllowedPattern" : "[0-9a-zA-Z.]{4,24}",
      "ConstraintDescription" : "User name must be between 4 and 24 character and can only contain digits 0 through 9, ASCII letters A through Z (uppercase and lowercase), and a dot (.)."
    },
    "SiteAdminPassword" : {
      "Description" : "Password for the site admin account",
      "Type" : "String",
      "NoEcho" : "true",
      "AllowedPattern" : "[0-9a-zA-Z.]{4,24}",
      "ConstraintDescription" : "Password must be between 4 and 24 character and can only contain digits 0 through 9, ASCII letters A through Z (uppercase and lowercase), and a dot (.)."
    },
    "SiteEIPAllocationID" : {
      "Description" : "Allocation ID of Elastic IP address for VPC (eipalloc-XXXXXXXX)",
      "Type" : "String",
      "AllowedPattern" : "eipalloc-.*"
    },
    "SiteDomain" : {
      "Description" : "The domain name of your ArcGIS site",
      "Type" : "String",
      "AllowedPattern" : "[^\"]{1,1024}",
      "ConstraintDescription" : "The domain name is invalid."
    },
    "SSLCertificateFile" : {
      "Description" : "SSL certificate file issued to the site domain (must be uploaded to DeploymentBucket)",
      "Type" : "String",
      "AllowedPattern" : "[^\"]{1,1024}",
      "ConstraintDescription" : "S3 object key name must be between 1 and 1024 characters."
    },
    "SSLCertPassword" : {
      "Description" : "SSL certificate file password",
      "Type" : "String",
      "NoEcho" : "true",
      "AllowedPattern" : "[^\"]{1,1024}",
      "ConstraintDescription" : "The SSL certificate file password is invalid."
    }
  },
  "Resources" : {
    "VPC" : {
      "Type" : "AWS::EC2::VPC",
      "Properties" : {
        "CidrBlock" : "10.0.0.0/16",
        "Tags" : [{"Key" : "Application", "Value" : {"Ref":"AWS::StackName"}},
                  {"Key" : "Network", "Value" : "Public"}]
      }
    },
    "Subnet1" : {
      "Type" : "AWS::EC2::Subnet",
      "Properties" : {
        "VpcId" : {"Ref" : "VPC"},
        "CidrBlock" : "10.0.0.0/24",
        "AvailabilityZone" : {"Fn::Select" : [0, {"Fn::GetAZs" : ""}]},
        "Tags" : [{"Key" : "Application", "Value" : {"Ref":"AWS::StackName"}},
                  {"Key" : "Network", "Value" : "Public"}]
      }
    },
    "InternetGateway" : {
      "Type" : "AWS::EC2::InternetGateway",
      "Properties" : {
        "Tags" : [ {"Key" : "Application", "Value" : {"Ref":"AWS::StackName"}}, 
                   {"Key" : "Network", "Value" : "Public"} ]
      }
    },
    "AttachGateway" : {
      "Type" : "AWS::EC2::VPCGatewayAttachment",
      "Properties" : {
        "VpcId" : {"Ref":"VPC"},
        "InternetGatewayId" : {"Ref":"InternetGateway"}
      }
    },
    "RouteTable" : {
      "Type" : "AWS::EC2::RouteTable",
      "Properties" : {"VpcId" : {"Ref" : "VPC"},
        "Tags" : [ {"Key" : "Application", "Value" : {"Ref" : "AWS::StackName"}}, 
                   {"Key" : "Network", "Value" : "Public"} ]
      }
    },
    "Route" : {
      "Type" : "AWS::EC2::Route",
      "Properties" : {
        "RouteTableId" : {"Ref":"RouteTable"},
        "DestinationCidrBlock" : "0.0.0.0/0",
        "GatewayId" : {"Ref":"InternetGateway"}
      }
    },
    "Subnet1RouteTableAssociation" : {
      "Type" : "AWS::EC2::SubnetRouteTableAssociation",
      "Properties" : {
        "SubnetId" : {"Ref":"Subnet1"},
        "RouteTableId" : {"Ref" : "RouteTable"}
      }
    },
    "EC2SecurityGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : {"Ref":"AWS::StackName"},
        "VpcId" : {"Ref":"VPC"},
        "SecurityGroupIngress" : [
          {
            "IpProtocol" : "tcp",
            "FromPort" : "80",
            "ToPort" : "80",
            "CidrIp" : "0.0.0.0/0"
          },
          {
            "IpProtocol" : "tcp",
            "FromPort" : "443",
            "ToPort" : "443",
            "CidrIp" : "0.0.0.0/0"
          }
        ]
      }
    },
    "EIPAssociation" : {
      "Type" : "AWS::EC2::EIPAssociation",
      "DependsOn" : "WaitCondition",
      "Properties" : {
        "AllocationId" : {"Ref" : "SiteEIPAllocationID"},
        "InstanceId" : {"Ref" : "AllInOneEC2Instance"}
      }
    },
    "IAMRole" : {
      "Type" : "AWS::IAM::Role",
      "Properties" : {
        "AssumeRolePolicyDocument" : {
          "Statement" : [
            {
              "Effect" : "Allow",
              "Principal" : {"Service" : ["ec2.amazonaws.com"]},
              "Action":["sts:AssumeRole"]
            }
          ]
        },
        "Path" : "/"
      }
    },
    "IAMPolicy" : {
      "Type" : "AWS::IAM::Policy",
      "Properties" : {
        "PolicyName" : "IAMRole",
        "PolicyDocument" : {
          "Statement" : [
            {
              "Action" : ["s3:GetObject"],
              "Effect" : "Allow",
              "Resource" : "arn:aws-us-gov:s3:::*"
            }
          ]
        },
        "Roles":[{"Ref":"IAMRole"}]
      }
    },
    "IAMInstanceProfile" : {
      "Type" : "AWS::IAM::InstanceProfile",
      "Properties" : {
        "Path" : "/",
        "Roles" : [{"Ref":"IAMRole"}]
      }
    },
    "AllInOneEC2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "en"]},
        "InstanceType" : {"Ref":"InstanceType"},
        "KeyName" : {"Ref":"KeyName"},
        "IamInstanceProfile" : {"Ref":"IAMInstanceProfile"},
        "Tags" : [{"Key" : "Name", "Value" : "allinone"}],
        "NetworkInterfaces" : [{
          "PrivateIpAddress" : "10.0.0.5",
          "GroupSet" : [{"Ref" : "EC2SecurityGroup"}],
          "AssociatePublicIpAddress" : "true",
          "DeviceIndex" : "0",
          "DeleteOnTermination" : "true",
          "SubnetId" : {"Ref" : "Subnet1"}}],
        "Monitoring" : true,
        "UserData" : {
          "Fn::Base64" : {
            "Fn::Join" : [
              "",
              [
                "#!/bin/bash -v\n",
                "cfn-init -v -s ", {"Ref" : "AWS::StackName"}, " -r AllInOneEC2Instance", " --region ", {"Ref" : "AWS::Region"}, "\n",
                "exitcode=$?\n",
                "chmod 777 /mnt\n",
                "chef-solo -j /var/chef/node.json -L /var/log/chef-run.log -l info\n",
                "exitcode=$?\n",
                "if [ $exitcode -ne 0 ]; then\n",
                "  sleep 60\n",
                "  cfn-signal -e $exitcode -r 'cfn-init failed.' '", {"Ref" : "WaitHandle"}, "'\n",
                "  exit $exitcode\n",
                "fi\n",
                "cfn-signal -e 0 -r 'Setup complete' '", {"Ref" : "WaitHandle"}, "'\n"
              ]
            ]
          }
        }
      },
      "Metadata" : {
        "AWS::CloudFormation::Authentication": {
          "S3AccessCreds" : {
            "type" : "S3",
            "buckets" : [ {"Ref" : "DeploymentBucket"} ],
            "roleName" : { "Ref": "IAMRole" }
          }
        },
        "AWS::CloudFormation::Init" : {
          "config" : {
            "commands" : {
              "rename-server-license" : {
                "command" : {"Fn::Join" : ["", [ "mv /tmp/server_license.tmp /tmp/", {"Ref" : "ServerLicenseFile"} ]]}
              },
              "rename-portal-license" : {
                "command" : {"Fn::Join" : ["", [ "mv /tmp/portal_license.tmp /tmp/", {"Ref" : "PortalLicenseFile"} ]]}
              }
            }, 
            "sources" : {
              "/var/chef" : "https://s3.amazonaws.com/esriarcgisserverrepository/10.3.1/cookbooks/arcgis-1.1.0-cookbooks.tar.gz"
            },
            "files" : {
              "/tmp/cwlogs/cwlogs.conf": {
                "content": {
                  "Fn::Join": ["",  [
	              "[general]\n",
	              "state_file= /var/awslogs/agent-state\n",
	              "[/var/log/cfn-init.log]\n",
	              "file = /var/log/cfn-init.log\n",
	              "log_stream_name = {instance_id}/cfn-init.log\n",
	              "datetime_format = %d/%b/%Y:%H:%M:%S\n",
	              "[/var/log/chef-run.log]\n",
	              "file = /var/log/chef-run.log\n",
	              "log_stream_name = {instance_id}/chef-run.log\n",
	              "datetime_format = %Y-%m-%dT%H:%M:%S%z\n",
	              "[/var/lib/tomcat7/logs/catalina.out]\n",
	              "file = /var/lib/tomcat7/logs/catalina.out\n",
	              "log_stream_name = {instance_id}/catalina.out\n",
	              "datetime_format = %d/%b/%Y:%H:%M:%S"]]
                }
              },
              "/var/chef/keystore.pfx" : {
                "source" : {"Fn::Join" : ["", [ "https://s3-us-gov-west-1.amazonaws.com/", {"Ref" : "DeploymentBucket"}, "/", {"Ref" : "SSLCertificateFile"} ]]},
                "authentication" : "S3AccessCreds"
              },
              "/tmp/server_license.tmp" : {
                "source" : {"Fn::Join" : ["", [ "https://s3-us-gov-west-1.amazonaws.com/", {"Ref" : "DeploymentBucket"}, "/", {"Ref" : "ServerLicenseFile"} ]]},
                "authentication" : "S3AccessCreds"
              },
              "/tmp/portal_license.tmp" : {
                "source" : {"Fn::Join" : ["", [ "https://s3-us-gov-west-1.amazonaws.com/", {"Ref" : "DeploymentBucket"}, "/", {"Ref" : "PortalLicenseFile"} ]]},
                "authentication" : "S3AccessCreds"
              },
              "/var/chef/node.json" : {
                "content" : { 
                  "Fn::Join" : ["", [
                  "{\n",
                  "  \"java\" : {\n",
                  "  \"install_flavor\" : \"oracle\",\n",
                  "  \"jdk_version\" : \"7\",\n", 
                  "    \"oracle\" : {\n",
			      "      \"accept_oracle_download_terms\" : true\n",
		          "     }\n",
	              "  },\n",
                  "  \"tomcat\" : {\n",
                  "    \"base_version\" : 7,\n",
                  "    \"port\" : 80,\n",
                  "    \"ssl_port\" : 443,\n",
                  "    \"authbind\" : \"yes\",\n",
                  "    \"keystore_file\" : \"../../var/chef/keystore.pfx\",\n",
                  "    \"keystore_type\" : \"pkcs12\",\n",
                  "    \"keystore_password\" : \"", {"Ref" : "SSLCertPassword"}, "\"\n",
                  "  },\n",
                  "  \"server\" : {\n",
                  "    \"domain_name\" : \"", {"Ref" : "SiteDomain"}, "\",\n",
                  "    \"admin_username\" : \"", {"Ref" : "SiteAdmin"}, "\",\n",
                  "    \"admin_password\" : \"", {"Ref" : "SiteAdminPassword"}, "\",\n",
                  "    \"directories_root\" : \"/gisdata/arcgisserver\",\n",
                  "    \"authorization_file\" : \"/tmp/", {"Ref" : "ServerLicenseFile"}, "\"\n",
                  "  },\n",
                  "  \"data_store\" : {\r\n",
                  "    \"data_dir\" : \"/gisdata/arcgisdatastore/data\"\n",
                  "  },\r\n",
                  "  \"portal\" : {\n",
                  "    \"domain_name\" : \"", {"Ref" : "SiteDomain"}, "\",\n",
                  "    \"admin_username\" : \"", {"Ref" : "SiteAdmin"}, "\",\n",
                  "    \"admin_password\" : \"", {"Ref" : "SiteAdminPassword"}, "\",\n",
                  "    \"content_dir\" : \"/gisdata/arcgisportal/content\",\n",                  
                  "    \"authorization_file\" : \"/tmp/", {"Ref" : "PortalLicenseFile"}, "\"\n",
                  "  },\n",
                  "  \"run_list\" : [\n",
                  "    \"recipe[apt]\",\n",
                  "    \"recipe[arcgis::system]\",\n",
                  "    \"recipe[java]\",\n",
                  "    \"recipe[arcgis::authbind]\",\n",
                  "    \"recipe[tomcat]\",\n",
                  "    \"recipe[arcgis::server]\",\n",
                  "    \"recipe[arcgis::server_wa]\",\n",
                  "    \"recipe[arcgis::datastore]\",\n",
                  "    \"recipe[arcgis::portal]\",\n",
                  "    \"recipe[arcgis::portal_wa]\",\n",
                  "    \"recipe[arcgis::federation]\"]\n",
                  "}\n"]]
                }
              }
            }
          }
        }
      }
    },
    "WaitHandle" : {
      "Type" : "AWS::CloudFormation::WaitConditionHandle",
      "Properties" : {}
    },
    "WaitCondition" : {
      "Type" : "AWS::CloudFormation::WaitCondition",
      "DependsOn" : "AllInOneEC2Instance",
      "Properties" : {
        "Handle" : { "Ref" : "WaitHandle" },
        "Timeout" : "7200"
      }
    }
  },
  "Outputs" : {
    "AdminURL" : {
      "Value" : {"Fn::Join":["", ["https://", {"Ref" : "SiteDomain"}, "/server/manager"]]},
      "Description" : "ArcGIS Server Administrator Directory URL"
    },
    "RestURL" : {
      "Value" : {"Fn::Join":["", ["http://", {"Ref" : "SiteDomain"}, "/server/rest"]]},
      "Description":"ArcGIS REST Services Directory URL"
    },
    "PortalURL" : {
      "Value" : {"Fn::Join":["", ["http://", {"Ref" : "SiteDomain"}, "/portal/home"]]},
      "Description" : "Portal for ArcGIS Server Home URL"
    }
    }
}
