{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "ArcGIS CloudFormation Template: Provisions an ArcGIS Server site on EC2 instances running Windows. **WARNING** You will be billed by AWS for the AWS resources if you create a stack from this template.", "Mappings": { "RegionMap" : { "ap-east-1": { "en": "ami-0aa88e10d78ce527c" }, "ap-northeast-1": { "en": "ami-05e95c556528f8f89" }, "ap-northeast-2": { "en": "ami-0f2b646acbd72af48" }, "ap-south-1": { "en": "ami-0eee586aed21b927a" }, "ap-southeast-1": { "en": "ami-013a09650b08f39d0" }, "ap-southeast-2": { "en": "ami-0bfd7638f066cb155" }, "ca-central-1": { "en": "ami-0d6d699c271a64264" }, "eu-central-1": { "en": "ami-04f6edf4d4cfcf1ce" }, "eu-north-1": { "en": "ami-0edd5a3a6bf63787b" }, "eu-west-1": { "en": "ami-093e765691e9aef92" }, "eu-west-2": { "en": "ami-00de162c597ac79f5" }, "eu-west-3": { "en": "ami-021e97aaf42b71330" }, "sa-east-1": { "en": "ami-0aaba71d72f704a4f" }, "us-east-1": { "en": "ami-08f14f10ad2086612" }, "us-east-2": { "en": "ami-0bbc6320c3794edcc" }, "us-west-1": { "en": "ami-01aa6a661d9093609" }, "us-west-2": { "en": "ami-0464424848fe9173b" }, "us-gov-east-1": { "en": "ami-0eac91fafef2b4e5c" }, "us-gov-west-1": { "en": "ami-02e76301331bd6dba" } }, "DBEngineProperties": { "sqlserver-se": { "MajorVersion": "13.00", "Version": "13.00.4422.0.v1", "License": "license-included" }, "postgres": { "MajorVersion": "9.6", "Version": "9.6.20", "License": "postgresql-license" }, "aurora-postgresql": { "MajorVersion": "9.6", "Version": "9.6.18", "License": "postgresql-license" } } }, "Parameters": { "DeploymentBucket": { "Description": "S3 bucket with software authorization and SSL certificate files", "Type": "String", "AllowedPattern": "^([a-z]|(\\d(?!\\d{0,2}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})))([a-z\\d]|(\\.(?!(\\.|-)))|(-(?!\\.))){1,61}[a-z\\d\\.]$", "ConstraintDescription": "A Bucket's name can be between 6 and 63 characters long, containing lowercase characters, numbers, periods, and dashes and it must start with a lowercase letter or number." }, "DriveSizeRoot": { "Default": "100", "Description": "The size of the C: Drive in GB.", "Type": "Number", "MinValue": "100", "MaxValue": "1024", "ConstraintDescription": "Must be between 100 and 1024 GB." }, "FSInstanceType": { "Description": "The file server EC2 instance type", "Type": "String", "AllowedValues": [ "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "c5.xlarge", "c5.2xlarge", "c5.4xlarge", "c5.9xlarge", "c5.18xlarge", "c5.xlarge", "c5n.xlarge", "c5n.2xlarge", "c5n.4xlarge", "c5n.9xlarge", "c5n.18xlarge", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "m4.16xlarge", "m5.large", "m5.xlarge", "m5.2xlarge", "m5.4xlarge", "m5.12xlarge", "m5.24xlarge", "m5.metal", "m5a.large", "m5a.xlarge", "m5a.2xlarge", "m5a.4xlarge", "m5a.12xlarge", "m5a.24xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "r4.large", "r4.xlarge", "r4.2xlarge", "r4.4xlarge", "r4.8xlarge", "r4.16xlarge", "r5.large", "r5.xlarge", "r5.2xlarge", "r5.4xlarge", "r5.12xlarge", "r5.24xlarge", "r5.metal", "r5a.large", "r5a.xlarge", "r5a.2xlarge", "r5a.4xlarge", "r5a.12xlarge", "r5a.24xlarge", "t2.large", "t2.xlarge", "t2.2xlarge", "t3.large", "t3.xlarge", "t3.2xlarge", "x1.16xlarge", "x1.32xlarge", "x1e.xlarge", "x1e.2xlarge", "x1e.4xlarge", "x1e.8xlarge", "x1e.16xlarge", "x1e.32xlarge" ], "Default": "c4.large" }, "ASInstanceType": { "Description": "The ArcGIS Server EC2 instance type", "Type": "String", "AllowedValues": [ "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "c5.large", "c5.xlarge", "c5.2xlarge", "c5.4xlarge", "c5.9xlarge", "c5.18xlarge", "c5.xlarge", "c5d.2xlarge", "c5d.4xlarge", "c5d.9xlarge", "c5d.18xlarge", "c5n.xlarge", "c5n.2xlarge", "c5n.4xlarge", "c5n.9xlarge", "c5n.18xlarge", "g3s.xlarge", "g3.4xlarge", "g3.8xlarge", "g3.16xlarge", "g4dn.xlarge", "g4dn.2xlarge", "g4dn.4xlarge", "g4dn.8xlarge", "g4dn.16xlarge", "g4dn.12xlarge", "g4dn.metal", "f1.2xlarge", "f1.4xlarge", "f1.16xlarge", "h1.2xlarge", "h1.4xlarge", "h1.8xlarge", "h1.16xlarge", "i3.large", "i3.xlarge", "i3.2xlarge", "i3.4xlarge", "i3.8xlarge", "i3.16xlarge", "i3.metal", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "m5.large", "m5.xlarge", "m5.2xlarge", "m5.4xlarge", "m5.12xlarge", "m5.24xlarge", "m5.metal", "m5d.large", "m5d.xlarge", "m5d.2xlarge", "m5d.4xlarge", "m5d.12xlarge", "m5d.24xlarge", "m5d.metal", "m5a.large", "m5a.xlarge", "m5a.2xlarge", "m5a.4xlarge", "m5a.12xlarge", "m5a.24xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "m4.16xlarge", "p2.xlarge", "p2.8xlarge", "p2.16xlarge", "p3.2xlarge", "p3.8xlarge", "p3.16xlarge", "p3dn.24xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "r4.large", "r4.xlarge", "r4.2xlarge", "r4.4xlarge", "r4.8xlarge", "r4.16xlarge", "r5.large", "r5.xlarge", "r5.2xlarge", "r5.4xlarge", "r5.12xlarge", "r5.24xlarge", "r5.metal", "r5d.large", "r5d.xlarge", "r5d.2xlarge", "r5d.4xlarge", "r5d.12xlarge", "r5d.24xlarge", "r5d.metal", "r5a.large", "r5a.xlarge", "r5a.2xlarge", "r5a.4xlarge", "r5a.12xlarge", "r5a.24xlarge", "t2.large", "t2.xlarge", "t2.2xlarge", "t3.large", "t3.xlarge", "t3.2xlarge", "t3a.large", "t3a.xlarge", "t3a.2xlarge", "u-6tb1.metal", "u-9tb1.metal", "u-12tb1.metal", "x1e.xlarge", "x1e.2xlarge", "x1e.4xlarge", "x1e.8xlarge", "x1e.16xlarge", "x1e.32xlarge", "x1.16xlarge", "x1.32xlarge", "z1d.large", "z1d.xlarge", "z1d.2xlarge", "z1d.3xlarge", "z1d.6xlarge", "z1d.12xlarge", "z1d.metal" ], "Default": "m4.large" }, "ASInstances": { "Description": "Number of ArcGIS Server EC2 instances.", "Type": "Number", "MinValue": "1", "Default": "2" }, "KeyName": { "Description": "EC2 Key Pair to allow RemoteDesktop access to the instances", "Type": "AWS::EC2::KeyPair::KeyName" }, "StoreType": { "Description": "ArcGIS Server config store type", "Type": "String", "AllowedValues": ["CloudStore", "FileSystem"], "Default": "FileSystem" }, "ServerLicenseFile": { "Description": "ArcGIS Server authorization file (must be uploaded to DeploymentBucket)", "Type": "String", "AllowedPattern": "^([/\\w\\-\\.]+)+\\.(ecp|prvc)$", "ConstraintDescription": "License file name must be alphanumeric. It can contain dash ('-'), dot ('.'), and underscore ('_') characters. The file name must end with '.ecp' or '.prvc'." }, "SiteAdmin": { "Description": "User name for ArcGIS Server site admin account", "Type": "String", "Default": "admin", "AllowedPattern": "^[a-zA-Z][a-zA-Z0-9_]{4,}$", "ConstraintDescription": "User name must be 4 or more alphanumeric or underscore (_) characters and must start with a letter." }, "SiteAdminPassword": { "Description": "Password for the site admin account", "Type": "String", "NoEcho": "true", "AllowedPattern": "^[a-zA-Z0-9_\\.@]{8,}$", "ConstraintDescription": "Password must be 8 or more alphanumeric, underscore (_), at ('@'), or dot (.) characters." }, "RunAsUserPassword": { "Description": "Password for ArcGIS Server account", "Type": "String", "NoEcho": "true", "AllowedPattern": "(?!.*arcgis)(?!.*Arc)(?!.*GIS)(?!.*user)(?!.*account)^((?=.*[a-z])(?=.*[A-Z])(?=.*\\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[^A-Za-z0-9])|(?=.*[a-z])(?=.*\\d)(?=.*[^A-Za-z0-9])|(?=.*[A-Z])(?=.*\\d)(?=.*[^A-Za-z0-9]))([A-Za-z\\d@#$%&�*\\-_+=\\[\\]{}|:\\',?~();!]|\\.(?!@)){8,}$", "ConstraintDescription": "Password must be at least eight characters in length and must contain characters from three of the following four categories: English uppercase characters (A through Z), English lowercase characters (a through z), digits (0 through 9), non-alphabetic characters (for example, !, $, #, %). Password must not contain backslashes (\\) or quotation marks (\"). Password must not contain the user's account name (arcgis) or parts of the user's full name (ArcGIS user account) that exceed two consecutive characters." }, "ELBName": { "Description": "Name of an existing ELB or 'NEW_ELB' to create and use a new one.", "Type": "String", "Default": "NEW_ELB" }, "SSLCertificateARN": { "Description": "ARN of the SSL certificate issued to the site domain (not required if an existing ELB is used)", "Type": "String", "Default": "", "ConstraintDescription": "arn:aws:acm:::certificate/" }, "DBEngine": { "Description": "RDS engine", "Type": "String", "AllowedValues": ["none", "sqlserver-se", "postgres", "aurora-postgresql"], "Default": "none" }, "DBInstanceClass": { "Description": "The RDS instance class", "Type": "String", "AllowedValues": [ "db.m3.medium", "db.m3.large", "db.m3.xlarge", "db.m3.2xlarge", "db.m4.large", "db.m4.xlarge", "db.m4.2xlarge", "db.m4.4xlarge", "db.m4.10xlarge", "db.m4.16xlarge", "db.m5.large", "db.m5.xlarge", "db.m5.2xlarge", "db.m5.4xlarge", "db.m5.12xlarge", "db.m5.24xlarge", "db.r3.large", "db.r3.xlarge", "db.r3.2xlarge", "db.r3.4xlarge", "db.r3.8xlarge", "db.r4.large", "db.r4.xlarge", "db.r4.2xlarge", "db.r4.4xlarge", "db.r4.8xlarge", "db.r4.16xlarge", "db.r5.large", "db.r5.xlarge", "db.r5.2xlarge", "db.r5.4xlarge", "db.r5.12xlarge", "db.r5.24xlarge", "db.t2.micro", "db.t2.small", "db.t2.medium", "db.t2.large", "db.t2.xlarge", "db.t2.2xlarge", "db.t3.micro", "db.t3.small", "db.t3.medium", "db.t3.large", "db.t3.xlarge", "db.t3.2xlarge", "db.x1e.xlarge", "db.x1e.2xlarge", "db.x1e.4xlarge", "db.x1e.8xlarge", "db.x1e.16xlarge", "db.x1e.32xlarge" ], "Default": "db.r4.large" }, "DBAllocatedStorage": { "Description": "The allocated storage size of RDS instance specified in gigabytes (GB).", "Default": "200", "Type": "Number", "MinValue": "200", "MaxValue": "4096", "ConstraintDescription": "Must be between 200 and 4096." }, "VPCId": { "Description": "VPC ID", "Type": "AWS::EC2::VPC::Id" }, "Subnet1": { "Description": "Subnet 1", "Type": "AWS::EC2::Subnet::Id" }, "Subnet2": { "Description": "Subnet 2", "Type": "AWS::EC2::Subnet::Id" }, "PostInstallationScript": { "Description": "ZIP archive file with custom post installation script (must be uploaded to DeploymentBucket).", "Type": "String", "AllowedPattern": "[^\"]{1,1024}", "ConstraintDescription": "S3 object key name must be between 1 and 1024 characters.", "Default": "none" } }, "Metadata": { "AWS::CloudFormation::Interface": { "ParameterGroups": [{ "Label": { "default": "Network Configuration" }, "Parameters": ["VPCId", "Subnet1", "Subnet2", "ELBName", "SSLCertificateARN"] }, { "Label": { "default": "Amazon EC2 Configuration" }, "Parameters": ["FSInstanceType", "ASInstanceType", "ASInstances", "DriveSizeRoot", "KeyName", "DBEngine", "DBInstanceClass", "DBAllocatedStorage"] }, { "Label": { "default": "ArcGIS Enterprise Configuration" }, "Parameters": ["DeploymentBucket", "ServerLicenseFile", "StoreType", "SiteAdmin", "SiteAdminPassword", "RunAsUserPassword"] } ] } }, "Conditions": { "CreateDBInstance": { "Fn::Or": [{ "Fn::Equals": [{ "Ref": "DBEngine" }, "sqlserver-se"] }, { "Fn::Equals": [{ "Ref": "DBEngine" }, "postgres"] } ] }, "DBEngineSQLServer": { "Fn::Equals": [{ "Ref": "DBEngine" }, "sqlserver-se"] }, "DBEnginePostgres": { "Fn::Equals": [{ "Ref": "DBEngine" }, "postgres"] }, "DBEngineAurora": { "Fn::Equals": [{ "Ref": "DBEngine" }, "aurora-postgresql"] }, "CreateDHCPOptions": { "Fn::Equals": [{ "Ref": "AWS::Region" }, "us-east-1"] }, "UseCloudStore": { "Fn::Equals": [{ "Ref": "StoreType" }, "CloudStore"] }, "RunPostInstall": { "Fn::Not": [{ "Fn::Equals": [{ "Ref": "PostInstallationScript" }, "none"] }] }, "SSMSupported": { "Fn::Not": [{ "Fn::Or": [{ "Fn::Equals": [{ "Ref": "AWS::Region" }, "eu-west-2"] }, { "Fn::Equals": [{ "Ref": "AWS::Region" }, "ap-south-1"] }, { "Fn::Equals": [{ "Ref": "AWS::Region" }, "ca-central-1"] } ] }] }, "NewELB": { "Fn::Equals": [{ "Ref": "ELBName" }, "NEW_ELB"] } }, "Resources": { "ValidateParametersFunction": { "Type": "AWS::Lambda::Function", "DependsOn": "IAMRole", "Properties": { "Code": { "S3Bucket": { "Fn::Join": ["", ["arcgisstore1081", "-", { "Ref": "AWS::Region" }]] }, "S3Key": "14362/lambda/arcgis-cfn-lambda-python3.zip" }, "Handler": "parameters.handler", "Runtime": "python3.8", "Timeout": "300", "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"] } } }, "StopStackFunction": { "Type": "AWS::Lambda::Function", "DependsOn": "IAMRole", "Properties": { "Code": { "S3Bucket": { "Fn::Join": ["", ["arcgisstore1081", "-", { "Ref": "AWS::Region" }]] }, "S3Key": "14362/lambda/arcgis-cfn-lambda-python3.zip" }, "Environment": { "Variables": { "StackName": { "Ref": "AWS::StackName" } } }, "Handler": "stop_start.stop_server_stack", "Runtime": "python3.8", "Timeout": "300", "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"] }, "Description": "Stops all EC2 instances of the CloudFormation stack" } }, "StartStackFunction": { "Type": "AWS::Lambda::Function", "DependsOn": "IAMRole", "Properties": { "Code": { "S3Bucket": { "Fn::Join": ["", ["arcgisstore1081", "-", { "Ref": "AWS::Region" }]] }, "S3Key": "14362/lambda/arcgis-cfn-lambda-python3.zip" }, "Environment": { "Variables": { "StackName": { "Ref": "AWS::StackName" } } }, "Handler": "stop_start.start_server_stack", "Runtime": "python3.8", "Timeout": "300", "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"] }, "Description": "Starts all EC2 instances of the CloudFormation stack" } }, "GetELBAttributesFunction": { "Type": "AWS::Lambda::Function", "DependsOn": "IAMRole", "Properties": { "Code": { "S3Bucket": { "Fn::Join": ["", ["arcgisstore1081", "-", { "Ref": "AWS::Region" }]] }, "S3Key": "14362/lambda/arcgis-cfn-lambda-python3.zip" }, "Handler": "elb_attributes.handler", "Runtime": "python3.8", "Timeout": "300", "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"] }, "Description": "Retrieves DNSName and source security group name for the specified ELB" } }, "ELBAttributes": { "Type": "Custom::ELBAttributes", "Properties": { "ServiceToken": { "Fn::GetAtt": ["GetELBAttributesFunction", "Arn"] }, "ELBName": { "Fn::If": ["NewELB", { "Ref": "ELB" }, { "Ref": "ELBName" }] }, "ELBTemplate": "server", "ELBSubnets": [{ "Ref": "Subnet1" }, { "Ref": "Subnet2" }] } }, "ELBInstanceFunction": { "Type": "AWS::Lambda::Function", "DependsOn": "IAMRole", "Properties": { "Code": { "S3Bucket": { "Fn::Join": ["", ["arcgisstore1081", "-", { "Ref": "AWS::Region" }]] }, "S3Key": "14362/lambda/arcgis-cfn-lambda-python3.zip" }, "Handler": "elb_instance.handler", "Runtime": "python3.8", "Timeout": "300", "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"] }, "Description": "Registers EC2 instance with the specified ELB" } }, "LambdaExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": ["lambda.amazonaws.com"] }, "Action": ["sts:AssumeRole"] }] }, "Path": "/", "Policies": [{ "PolicyName": "root", "PolicyDocument": { "Version": "2012-10-17", "Statement": [{ "Sid": "ConfigStoreS3Bucket", "Action": ["s3:*"], "Effect": "Allow", "Resource": "*" }, { "Sid": "DeploymentS3Bucket", "Action": [ "s3:GetObject", "s3:GetObjectVersion", "s3:GetBucketLocation" ], "Effect": "Allow", "Resource": "*" }, { "Sid": "ConfigStoreDynamoDB", "Action": ["dynamodb:*"], "Effect": "Allow", "Resource": "*" }, { "Sid": "StopStartEC2", "Effect": "Allow", "Action": ["ec2:*"], "Resource": "*", "Condition": { "StringEquals": { "ec2:ResourceTag/aws:cloudformation:stack-name": { "Ref": "AWS::StackName" } } } }, { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "ec2:DescribeSecurityGroups", "ec2:DescribeInstances", "ec2:DescribeInstanceStatus", "cloudformation:DescribeStackResource", "autoscaling:DescribeAutoScalingGroups", "autoscaling:UpdateAutoScalingGroup", "autoscaling:AttachInstances", "autoscaling:DetachInstances", "elasticloadbalancing:DescribeLoadBalancers" ], "Resource": "*" } ] } }] } }, "ValidateServerLicenseFile": { "Type": "Custom::ValidateParameters", "Properties": { "ServiceToken": { "Fn::GetAtt": ["ValidateParametersFunction", "Arn"] }, "DeploymentBucket": { "Ref": "DeploymentBucket" }, "S3Key": { "Ref": "ServerLicenseFile" } } }, "ValidatePostInstallationScript": { "Type": "Custom::ValidateParameters", "Condition": "RunPostInstall", "Properties": { "ServiceToken": { "Fn::GetAtt": ["ValidateParametersFunction", "Arn"] }, "DeploymentBucket": { "Ref": "DeploymentBucket" }, "S3Key": { "Ref": "PostInstallationScript" } } }, "ServerConfigStoreFunction": { "Type": "AWS::Lambda::Function", "DependsOn": "IAMRole", "Properties": { "Code": { "S3Bucket": { "Fn::Join": ["", ["arcgisstore1081", "-", { "Ref": "AWS::Region" }]] }, "S3Key": "14362/lambda/arcgis-cfn-lambda-python3.zip" }, "Handler": "server_config_store.handler", "Runtime": "python3.8", "Timeout": "30", "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"] } } }, "ServerConfigStore": { "Type": "Custom::ServerConfigStore", "Properties": { "ServiceToken": { "Fn::GetAtt": ["ServerConfigStoreFunction", "Arn"] }, "Namespace": { "Fn::Join": ["", [{ "Ref": "AWS::StackName" }]] } } }, "ELB": { "Type": "AWS::ElasticLoadBalancing::LoadBalancer", "Condition": "NewELB", "Properties": { "Subnets": [{ "Ref": "Subnet1" }, { "Ref": "Subnet2" }], "SecurityGroups": [{ "Ref": "ELBSecurityGroup" }], "Scheme": "internet-facing", "Listeners": [{ "LoadBalancerPort": "80", "InstancePort": "6080", "Protocol": "HTTP" }, { "LoadBalancerPort": "443", "InstancePort": "6443", "Protocol": "HTTPS", "InstanceProtocol": "HTTPS", "SSLCertificateId": { "Ref": "SSLCertificateARN" } }], "HealthCheck": { "Target": "HTTPS:6443/arcgis/rest/info/healthcheck", "HealthyThreshold": "3", "UnhealthyThreshold": "5", "Interval": "30", "Timeout": "5" } } }, "IAMRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [{ "Effect": "Allow", "Principal": { "Service": ["ec2.amazonaws.com", "ssm.amazonaws.com"] }, "Action": ["sts:AssumeRole"] }] }, "Path": "/" } }, "IAMPolicy": { "Type": "AWS::IAM::Policy", "DependsOn": "LambdaExecutionRole", "Properties": { "PolicyName": "IAMRole", "PolicyDocument": { "Version": "2012-10-17", "Statement": [{ "Sid": "ConfigStoreS3Bucket", "Action": ["s3:*"], "Effect": "Allow", "Resource": "*" }, { "Sid": "DeploymentS3Bucket", "Action": ["s3:GetObject"], "Effect": "Allow", "Resource": "*" }, { "Sid": "ConfigStoreDynamoDB", "Action": ["dynamodb:*"], "Effect": "Allow", "Resource": "*" }, { "Action": [ "cloudformation:SignalResource", "cloudformation:DescribeStackResource", "ssm:DescribeAssociation", "ssm:GetDeployablePatchSnapshotForInstance", "ssm:GetDocument", "ssm:GetManifest", "ssm:GetParameters", "ssm:ListAssociations", "ssm:ListInstanceAssociations", "ssm:PutInventory", "ssm:PutComplianceItems", "ssm:PutConfigurePackageResult", "ssm:UpdateAssociationStatus", "ssm:UpdateInstanceAssociationStatus", "ssm:UpdateInstanceInformation", "ssmmessages:CreateControlChannel", "ssmmessages:CreateDataChannel", "ssmmessages:OpenControlChannel", "ssmmessages:OpenDataChannel", "ec2messages:AcknowledgeMessage", "ec2messages:DeleteMessage", "ec2messages:FailMessage", "ec2messages:GetEndpoint", "ec2messages:GetMessages", "ec2messages:SendReply", "cloudwatch:PutMetricData", "ec2:DescribeTags", "ec2:DescribeInstances", "ec2:DescribeInstanceStatus", "ec2:ModifyInstanceMetadataOptions", "ds:CreateComputer", "ds:DescribeDirectories", "logs:CreateLogGroup", "logs:CreateLogStream", "logs:DescribeLogGroups", "logs:DescribeLogStreams", "logs:PutLogEvents" ], "Effect": "Allow", "Resource": "*" }, { "Sid": "SSMAgentS3", "Effect": "Allow", "Action": "s3:GetObject", "Resource": "*" } ] }, "Roles": [{ "Ref": "IAMRole" }] } }, "IAMInstanceProfile": { "Type": "AWS::IAM::InstanceProfile", "Properties": { "Path": "/", "Roles": [{ "Ref": "IAMRole" }] } }, "ELBSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Condition": "NewELB", "Properties": { "GroupDescription": { "Ref": "AWS::StackName" }, "VpcId": { "Ref": "VPCId" }, "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" }] } }, "SecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": { "Ref": "AWS::StackName" }, "VpcId": { "Ref": "VPCId" }, "SecurityGroupIngress": [{ "IpProtocol": "tcp", "FromPort": "6080", "ToPort": "6080", "SourceSecurityGroupId": { "Fn::If": ["NewELB", { "Ref": "ELBSecurityGroup" }, { "Fn::GetAtt": ["ELBAttributes", "SourceSecurityGroupId"] }] } }, { "IpProtocol": "tcp", "FromPort": "6443", "ToPort": "6443", "SourceSecurityGroupId": { "Fn::If": ["NewELB", { "Ref": "ELBSecurityGroup" }, { "Fn::GetAtt": ["ELBAttributes", "SourceSecurityGroupId"] }] } }] } }, "SecurityGroupIngress": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "GroupId": { "Ref": "SecurityGroup" }, "IpProtocol": "tcp", "FromPort": "0", "ToPort": "65535", "SourceSecurityGroupId": { "Ref": "SecurityGroup" } } }, "EC2InstanceLaunchTemplate": { "Type": "AWS::EC2::LaunchTemplate", "Properties": { "LaunchTemplateData": { "BlockDeviceMappings": [{ "DeviceName": "/dev/sda1", "Ebs": { "VolumeSize": { "Ref": "DriveSizeRoot" }, "DeleteOnTermination": true, "VolumeType": "gp2" } }], "MetadataOptions": { "HttpEndpoint": "enabled", "HttpTokens": "required" }, "IamInstanceProfile": { "Arn": { "Fn::GetAtt": [ "IAMInstanceProfile", "Arn" ] } }, "ImageId": { "Fn::FindInMap": [ "RegionMap", { "Ref": "AWS::Region" }, "en" ] }, "InstanceType": { "Ref": "FSInstanceType" }, "KeyName": { "Ref": "KeyName" }, "NetworkInterfaces": [{ "AssociatePublicIpAddress": true, "DeleteOnTermination": true, "DeviceIndex": "0", "Groups": [{ "Ref": "SecurityGroup" }], "SubnetId": { "Ref": "Subnet1" } }] } } }, "FileServerEC2Instance": { "Type": "AWS::EC2::Instance", "Properties": { "Monitoring": true, "LaunchTemplate": { "LaunchTemplateId": { "Ref": "EC2InstanceLaunchTemplate" }, "Version": { "Fn::GetAtt": [ "EC2InstanceLaunchTemplate", "LatestVersionNumber" ] } }, "Tags": [{ "Key": "Name", "Value": { "Fn::Join": ["", [{ "Ref": "AWS::StackName" }, "-fileserver"]] } }], "UserData": { "Fn::Base64": { "Fn::Join": [ "", [ "\r\n", "try \r\n", "{ \r\n", " if (", { "Fn::If": ["RunPostInstall", "$true", "$false"] }, ") {\r\n", " cfn-init -v -c post-install-script -s ", { "Ref": "AWS::StackName" }, " -r CloudWatchSettings", " --region ", { "Ref": "AWS::Region" }, "\r\n", " } \r\n", " $stackName = '", { "Ref": "AWS::StackName" }, "' \r\n", " $region = '", { "Ref": "AWS::Region" }, "' \r\n", " $waitHandle = '", { "Ref": "FileServerWaitHandle" }, "' \r\n", " $InstanceName = 'FileServerEC2Instance' \r\n", " $NodeJSONPath = 'C:\\\\chef\\\\node.json' \r\n", " $ChefLogFile = 'C:\\\\chef\\\\chef-run.log' \r\n", " $execName = \"cfn-init\" \r\n", " $execArgs = \"-v -s $stackName -r CloudWatchSettings --region $region\" \r\n", " $process = Start-Process $execName -PassThru -Wait -ArgumentList $execArgs.Split(' ') \r\n", " if ($process.ExitCode -ne 0) { \r\n", " throw \"Process 'cfn-init' exit code : $($process.ExitCode)\" \r\n", " } \r\n", " \r\n", " $execArgs = \"-v -s $stackName -r $InstanceName --region $region\" \r\n", " $process = Start-Process $execName -PassThru -Wait -ArgumentList $execArgs.Split(' ') \r\n", " if ($process.ExitCode -ne 0) { \r\n", " throw \"Process 'cfn-init' exit code : $($process.ExitCode)\" \r\n", " } \r\n", " \r\n", " $process = Start-Process chef-solo -PassThru -Wait -ArgumentList (\"-j\", $NodeJSONPath, \"-L\",$ChefLogFile, \"-l\", \"info\") \r\n", " if ($process.ExitCode -ne 0) { \r\n", " throw \"Chef run failed. See 'C:\\\\chef\\\\chef-run.log' for details.\" \r\n", " } \r\n", " \r\n", " $process = Start-Process cfn-signal -PassThru -Wait -ArgumentList $waitHandle \r\n", " if ($process.ExitCode -ne 0) { \r\n", " throw \"Process 'cfn-signal' exit code : $($process.ExitCode)\" \r\n", " } \r\n", "} \r\n", "catch \r\n", "{ \r\n", " Write-Output \"ERROR: $($_.Exception.Message)\" \r\n", " cfn-signal -e 1 -r \"$($_.Exception.Message)\" \"$WaitHandle\" \r\n", "} \r\n", "\r\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": ["", [ "md \"C:\\Temp\\", { "Ref": "ServerLicenseFile" }, "\" & rmdir \"C:\\Temp\\", { "Ref": "ServerLicenseFile" }, "\" & move C:\\Temp\\server_license.tmp \"C:\\Temp\\", { "Ref": "ServerLicenseFile" }, "\"" ]] } } }, "files": { "C:\\Temp\\server_license.tmp": { "source": { "Fn::GetAtt": ["ValidateServerLicenseFile", "S3ObjectURL"] }, "authentication": "S3AccessCreds" }, "C:\\chef\\node.json": { "content": { "Fn::Join": ["", [ "{\r\n", " \"arcgis\" : {\r\n", " \"version\": \"10.8.1\",\r\n", " \"run_as_password\" : \"", { "Ref": "RunAsUserPassword" }, "\",\r\n", " \"post_install_script\" : \"C:\\\\PostInstallScripts\\\\deploy.bat\",\r\n", " \"hosts\" : {\r\n", " \"FILESERVER\" : \"\",\r\n", " \"SITEHOST\" : \"\"\r\n", " },\r\n", " \"server\" : {\r\n", " \"admin_username\" : \"", { "Ref": "SiteAdmin" }, "\",\r\n", " \"admin_password\" : \"", { "Ref": "SiteAdminPassword" }, "\",\r\n", " \"authorization_file\" : \"C:\\\\Temp\\\\", { "Ref": "ServerLicenseFile" }, "\",\r\n", " \"log_level\" : \"WARNING\",\r\n", " \"soc_max_heap_size\" : 64,\r\n", " \"local_directories_root\" : \"C:\\\\arcgisserver\",\r\n", " \"directories_root\" : \"\\\\\\\\FILESERVER\",\r\n", " \"log_dir\" : \"C:\\\\arcgisserver\\\\logs\",\r\n", " \"config_store_type\" : \"", { "Fn::If": ["UseCloudStore", "AMAZON", "FILESYSTEM"] }, "\",\r\n", " \"config_store_connection_string\" : \"", { "Fn::If": ["UseCloudStore", { "Fn::Join": ["", ["NAMESPACE=", { "Ref": "AWS::StackName" }, ";REGION=", { "Ref": "AWS::Region" }]] }, "\\\\\\\\FILESERVER\\\\config-store" ] }, "\",\r\n", " \"system_properties\" : {\r\n", " \"machineSuspendThreshold\" : 60,\r\n", " \"suspendedMachineUnregisterThreshold\" : 1440\r\n", " }\r\n", " },\r\n", " \"egdb\" : {\r\n", " \"engine\" : \"", { "Fn::If": ["DBEngineAurora", "postgres", { "Ref": "DBEngine" }] }, "\",\r\n", " \"endpoint\" : \"", { "Fn::If": ["CreateDBInstance", { "Fn::GetAtt": ["DBInstance", "Endpoint.Address"] }, { "Fn::If": ["DBEngineAurora", { "Fn::GetAtt": ["AuroraDBCluster", "Endpoint.Address"] }, ""] } ] }, "\",\r\n", " \"master_username\" : \"EsriRDSAdmin\",\r\n", " \"master_password\" : \"", { "Ref": "SiteAdminPassword" }, "\"\r\n", " }\r\n", " },\r\n", " \"run_list\" : [\r\n", " \"recipe[arcgis-enterprise::system]\",\r\n", " \"recipe[arcgis-enterprise::fileserver]\",\r\n", " \"recipe[esri-iis]\",\r\n", " \"recipe[arcgis-enterprise::server]\",\r\n", " \"recipe[arcgis-egdb::sql_alias]\",\r\n", " \"recipe[arcgis-egdb]\",\r\n", " \"recipe[arcgis-enterprise::stop_server]\",\r\n", " \"recipe[arcgis-enterprise::start_server]\",\r\n", " \"recipe[arcgis-enterprise::post_install]\"]\r\n", "}\r\n" ]] } }, "C:\\chef\\unregister_machine.json": { "content": { "Fn::Join": ["", [ "{\r\n", " \"arcgis\" : {\r\n", " \"version\": \"10.8.1\",\r\n", " \"server\" : {\r\n", " \"admin_username\" : \"", { "Ref": "SiteAdmin" }, "\",\r\n", " \"admin_password\" : \"", { "Ref": "SiteAdminPassword" }, "\"\r\n", " }\r\n", " },\r\n", " \"run_list\" : [\r\n", " \"recipe[arcgis-enterprise::unregister_machine]\"]\r\n", "}\r\n" ]] } } } } } } }, "FileServerRecoveryAlarm": { "Type": "AWS::CloudWatch::Alarm", "Properties": { "AlarmDescription": "Trigger a recovery when instance status check fails for 5 consecutive minutes.", "MetricName": "StatusCheckFailed_System", "Namespace": "AWS/EC2", "Statistic": "Minimum", "Period": "60", "EvaluationPeriods": "5", "Threshold": "0", "ComparisonOperator": "GreaterThanThreshold", "AlarmActions": [{ "Fn::Join": ["", ["arn:", { "Ref": "AWS::Partition" }, ":automate:", { "Ref": "AWS::Region" }, ":ec2:recover"]] }], "Dimensions": [{ "Name": "InstanceId", "Value": { "Ref": "FileServerEC2Instance" } }] } }, "AutoScalingInstanceLaunchTemplate": { "Type": "AWS::EC2::LaunchTemplate", "DependsOn": "FileServerWaitCondition", "Properties": { "LaunchTemplateData": { "BlockDeviceMappings": [{ "DeviceName": "/dev/sda1", "Ebs": { "VolumeSize": { "Ref": "DriveSizeRoot" }, "DeleteOnTermination": true, "VolumeType": "gp2" } }], "MetadataOptions": { "HttpEndpoint": "enabled", "HttpTokens": "required" }, "IamInstanceProfile": { "Arn": { "Fn::GetAtt": [ "IAMInstanceProfile", "Arn" ] } }, "ImageId": { "Fn::FindInMap": [ "RegionMap", { "Ref": "AWS::Region" }, "en" ] }, "InstanceType": { "Ref": "ASInstanceType" }, "KeyName": { "Ref": "KeyName" }, "NetworkInterfaces": [{ "AssociatePublicIpAddress": true, "DeleteOnTermination": true, "DeviceIndex": "0", "Groups": [{ "Ref": "SecurityGroup" }], "SubnetId": { "Ref": "Subnet1" } }], "UserData": { "Fn::Base64": { "Fn::Join": [ "", [ "\r\n", "try \r\n", "{ \r\n", " if (", { "Fn::If": ["RunPostInstall", "$true", "$false"] }, ") {\r\n", " cfn-init -v -c post-install-script -s ", { "Ref": "AWS::StackName" }, " -r CloudWatchSettings", " --region ", { "Ref": "AWS::Region" }, "\r\n", " } \r\n", " $stackName = '", { "Ref": "AWS::StackName" }, "' \r\n", " $region = '", { "Ref": "AWS::Region" }, "' \r\n", " $waitHandle = '", { "Ref": "AutoScalingGroupWaitHandle" }, "' \r\n", " $InstanceName = 'AutoScalingInstanceLaunchTemplate' \r\n", " $NodeJSONPath = 'C:\\\\chef\\\\node.json' \r\n", " $ChefLogFile = 'C:\\\\chef\\\\chef-run.log' \r\n", " $execName = \"cfn-init\" \r\n", " $execArgs = \"-v -s $stackName -r CloudWatchSettings --region $region\" \r\n", " $process = Start-Process $execName -PassThru -Wait -ArgumentList $execArgs.Split(' ') \r\n", " if ($process.ExitCode -ne 0) { \r\n", " throw \"Process 'cfn-init' exit code : $($process.ExitCode)\" \r\n", " } \r\n", " \r\n", " $execArgs = \"-v -s $stackName -r $InstanceName --region $region\" \r\n", " $process = Start-Process $execName -PassThru -Wait -ArgumentList $execArgs.Split(' ') \r\n", " if ($process.ExitCode -ne 0) { \r\n", " throw \"Process 'cfn-init' exit code : $($process.ExitCode)\" \r\n", " } \r\n", " \r\n", " $process = Start-Process chef-solo -PassThru -ArgumentList (\"-j\", $NodeJSONPath, \"-L\",$ChefLogFile, \"-l\", \"info\") \r\n", " $handle = $process.Handle\r\n", " $process.WaitForExit()\r\n", " if ($process.ExitCode -ne 0) { \r\n", " throw \"Chef run failed. See 'C:\\\\chef\\\\chef-run.log' for details.\" \r\n", " } \r\n", " \r\n", " $process = Start-Process cfn-signal -PassThru -Wait -ArgumentList $waitHandle \r\n", " if ($process.ExitCode -ne 0) { \r\n", " throw \"Process 'cfn-signal' exit code : $($process.ExitCode)\" \r\n", " } \r\n", "} \r\n", "catch \r\n", "{ \r\n", " Write-Output \"ERROR: $($_.Exception.Message)\" \r\n", " cfn-signal -e 1 -r \"$($_.Exception.Message)\" \"$WaitHandle\" \r\n", "} \r\n", "\r\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": ["", [ "md \"C:\\Temp\\", { "Ref": "ServerLicenseFile" }, "\" & rmdir \"C:\\Temp\\", { "Ref": "ServerLicenseFile" }, "\" & move C:\\Temp\\server_license.tmp \"C:\\Temp\\", { "Ref": "ServerLicenseFile" }, "\"" ]] } } }, "files": { "C:\\Temp\\server_license.tmp": { "source": { "Fn::GetAtt": ["ValidateServerLicenseFile", "S3ObjectURL"] }, "authentication": "S3AccessCreds" }, "C:\\chef\\node.json": { "content": { "Fn::Join": ["", [ "{\r\n", " \"arcgis\" : {\r\n", " \"version\": \"10.8.1\",\r\n", " \"run_as_password\" : \"", { "Ref": "RunAsUserPassword" }, "\",\r\n", " \"post_install_script\" : \"C:\\\\PostInstallScripts\\\\deploy.bat\",\r\n", " \"hosts\" : {\r\n", " \"FILESERVER\" : \"", { "Fn::GetAtt": ["FileServerEC2Instance", "PrivateIp"] }, "\",\r\n", " \"SITEHOST\" : \"", { "Fn::GetAtt": ["FileServerEC2Instance", "PrivateIp"] }, "\"\r\n", " },\r\n", " \"server\" : {\r\n", " \"admin_username\" : \"", { "Ref": "SiteAdmin" }, "\",\r\n", " \"admin_password\" : \"", { "Ref": "SiteAdminPassword" }, "\",\r\n", " \"authorization_file\" : \"C:\\\\Temp\\\\", { "Ref": "ServerLicenseFile" }, "\",\r\n", " \"use_join_site_tool\" : true,\r\n", " \"soc_max_heap_size\" : 64,\r\n", " \"config_store_type\" : \"", { "Fn::If": ["UseCloudStore", "AMAZON", "FILESYSTEM"] }, "\",\r\n", " \"config_store_connection_string\" : \"", { "Fn::If": ["UseCloudStore", { "Fn::Join": ["", ["NAMESPACE=", { "Ref": "AWS::StackName" }, ";REGION=", { "Ref": "AWS::Region" }]] }, "\\\\\\\\FILESERVER\\\\config-store" ] }, "\"\r\n", " },\r\n", " \"egdb\" : {\r\n", " \"engine\" : \"", { "Fn::If": ["DBEngineAurora", "postgres", { "Ref": "DBEngine" }] }, "\",\r\n", " \"endpoint\" : \"", { "Fn::If": ["CreateDBInstance", { "Fn::GetAtt": ["DBInstance", "Endpoint.Address"] }, { "Fn::If": ["DBEngineAurora", { "Fn::GetAtt": ["AuroraDBCluster", "Endpoint.Address"] }, ""] } ] }, "\"\r\n", " }\r\n", " },\r\n", " \"run_list\" : [\r\n", " \"recipe[arcgis-enterprise::system]\",\r\n", " \"recipe[esri-iis]\",\r\n", " \"recipe[arcgis-egdb::sql_alias]\",\r\n", " \"recipe[arcgis-enterprise::server_node]\",\r\n", " \"recipe[arcgis-enterprise::stop_server]\",\r\n", " \"recipe[arcgis-enterprise::start_server]\",\r\n", " \"recipe[arcgis-enterprise::post_install]\"]\r\n", "}\r\n" ]] } } } } } } }, "AutoScalingGroup": { "Type": "AWS::AutoScaling::AutoScalingGroup", "DependsOn": "FileServerEC2Instance", "Properties": { "VPCZoneIdentifier": [{ "Ref": "Subnet1" }, { "Ref": "Subnet2" }], "Cooldown": "300", "MaxSize": { "Ref": "ASInstances" }, "MinSize": { "Ref": "ASInstances" }, "LaunchTemplate": { "LaunchTemplateId": { "Ref": "AutoScalingInstanceLaunchTemplate" }, "Version": { "Fn::GetAtt": [ "AutoScalingInstanceLaunchTemplate", "LatestVersionNumber" ] } }, "HealthCheckType": "EC2", "HealthCheckGracePeriod": "3600", "LoadBalancerNames": [{ "Fn::If": ["NewELB", { "Ref": "ELB" }, { "Ref": "ELBName" }] }], "Tags": [{ "Key": "Name", "Value": { "Fn::Join": ["", [{ "Ref": "AWS::StackName" }, "-node"]] }, "PropagateAtLaunch": true }] }, "UpdatePolicy": { "AutoScalingReplacingUpdate": { "WillReplace": "true" } } }, "FileServerWaitHandle": { "Type": "AWS::CloudFormation::WaitConditionHandle", "Properties": {} }, "FileServerWaitCondition": { "Type": "AWS::CloudFormation::WaitCondition", "Properties": { "Count": "1", "Handle": { "Ref": "FileServerWaitHandle" }, "Timeout": "7200" } }, "AutoScalingGroupWaitHandle": { "Type": "AWS::CloudFormation::WaitConditionHandle", "Properties": {} }, "AutoScalingGroupWaitCondition": { "Type": "AWS::CloudFormation::WaitCondition", "Properties": { "Count": { "Ref": "ASInstances" }, "Handle": { "Ref": "AutoScalingGroupWaitHandle" }, "Timeout": "10800" } }, "DeploymentLogs": { "Type": "AWS::Logs::LogGroup", "Properties": { "RetentionInDays": 7 } }, "CloudWatchSettings": { "Type": "AWS::Logs::MetricFilter", "Properties": { "LogGroupName": { "Ref": "DeploymentLogs" }, "FilterPattern": "[level=FATAL, message]", "MetricTransformations": [{ "MetricValue": "1", "MetricNamespace": "ArcGIS/Deployment", "MetricName": "ErrorCount" }] }, "Metadata": { "AWS::CloudFormation::Authentication": { "S3AccessCreds": { "type": "S3", "buckets": [{ "Ref": "DeploymentBucket" }], "roleName": { "Ref": "IAMRole" } } }, "AWS::CloudFormation::Init": { "configSets": { "default": ["config"], "post-install-script": ["post-install-config"] }, "post-install-config": { "sources": { "C:\\PostInstallScripts": { "Fn::If": ["RunPostInstall", { "Fn::GetAtt": ["ValidatePostInstallationScript", "S3ObjectURL"] }, ""] } } }, "config": { "sources": { "C:\\chef": "https://arcgisstore1081.s3.amazonaws.com/14362/cookbooks/arcgis-3.6.0-cookbooks.zip", "C:\\Program Files\\Amazon\\cfn-bootstrap": "https://arcgisstore1061.s3.amazonaws.com/endpoints.zip" }, "files": { "C:\\Program Files\\Amazon\\SSM\\Plugins\\awsCloudWatch\\AWS.EC2.Windows.CloudWatch.json": { "content": { "Fn::Join": ["", [ "{\r\n", " \"IsEnabled\" : true,\r\n", " \"EngineConfiguration\": {\r\n", " \"PollInterval\": \"00:00:15\",\r\n", " \"Components\": [\r\n", " {\r\n", " \"Id\": \"CfnInitLogStream\",\r\n", " \"FullName\": \"AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch\",\r\n", " \"Parameters\": {\r\n", " \"Region\": \"", { "Ref": "AWS::Region" }, "\",\r\n", " \"LogGroup\": \"", { "Ref": "DeploymentLogs" }, "\",\r\n", " \"LogStream\": \"{instance_id}/cfn-init.log\"\r\n", " }\r\n", " },\r\n", " {\r\n", " \"Id\": \"ChefRunLogStream\",\r\n", " \"FullName\": \"AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch\",\r\n", " \"Parameters\": {\r\n", " \"Region\": \"", { "Ref": "AWS::Region" }, "\",\r\n", " \"LogGroup\": \"", { "Ref": "DeploymentLogs" }, "\",\r\n", " \"LogStream\": \"{instance_id}/chef-run.log\"\r\n", " }\r\n", " },\r\n", " {\r\n", " \"Id\": \"CfnInitLogs\",\r\n", " \"FullName\": \"AWS.EC2.Windows.CloudWatch.CustomLog.CustomLogInputComponent,AWS.EC2.Windows.CloudWatch\",\r\n", " \"Parameters\": {\r\n", " \"LogDirectoryPath\": \"C:\\\\cfn\\\\log\",\r\n", " \"TimestampFormat\": \"yyyy-MM-dd HH:mm:ss,fff\",\r\n", " \"Encoding\": \"UTF-8\",\r\n", " \"Filter\": \"cfn-init.log\",\r\n", " \"CultureName\": \"en-US\",\r\n", " \"TimeZoneKind\": \"Local\",\r\n", " \"LineCount\": \"1\"\r\n", " }\r\n", " },\r\n", " {\r\n", " \"Id\": \"ChefRunLogs\",\r\n", " \"FullName\": \"AWS.EC2.Windows.CloudWatch.CustomLog.CustomLogInputComponent,AWS.EC2.Windows.CloudWatch\",\r\n", " \"Parameters\": {\r\n", " \"LogDirectoryPath\": \"C:\\\\chef\",\r\n", " \"TimestampFormat\": \"[yyyy-MM-ddTHH:mm:sszzz]\",\r\n", " \"Encoding\": \"UTF-8\",\r\n", " \"Filter\": \"chef-run.log\",\r\n", " \"CultureName\": \"en-US\",\r\n", " \"TimeZoneKind\": \"Local\",\r\n", " \"LineCount\": \"1\"\r\n", " }\r\n", " }],\r\n", " \"Flows\": {\r\n", " \"Flows\":[\"CfnInitLogs,CfnInitLogStream\",\"ChefRunLogs,ChefRunLogStream\"]\r\n", " }\r\n", " }\r\n", "}\r\n" ]] } } }, "commands": { "0-enableSSM": { "command": "powershell.exe -Command \"Set-Service -Name AmazonSSMAgent -StartupType Automatic\" ", "waitAfterCompletion": "0" }, "1-restartSSM": { "command": "powershell.exe -Command \"Restart-Service AmazonSSMAgent \"", "waitAfterCompletion": "30" } } } } } }, "DBSubnetGroup": { "Type": "AWS::RDS::DBSubnetGroup", "Properties": { "DBSubnetGroupDescription": "DB subnet group", "SubnetIds": [{ "Ref": "Subnet1" }, { "Ref": "Subnet2" }], "Tags": [{ "Key": "Name", "Value": { "Fn::Join": ["", [{ "Ref": "AWS::StackName" }, "-db"]] } }] } }, "DBInstance": { "Type": "AWS::RDS::DBInstance", "Condition": "CreateDBInstance", "Properties": { "AllocatedStorage": { "Ref": "DBAllocatedStorage" }, "DBInstanceClass": { "Ref": "DBInstanceClass" }, "Engine": { "Ref": "DBEngine" }, "EngineVersion": { "Fn::FindInMap": ["DBEngineProperties", { "Ref": "DBEngine" }, "Version"] }, "LicenseModel": { "Fn::FindInMap": ["DBEngineProperties", { "Ref": "DBEngine" }, "License"] }, "MultiAZ": { "Fn::If": ["DBEnginePostgres", "true", { "Ref": "AWS::NoValue" }] }, "DBSubnetGroupName": { "Ref": "DBSubnetGroup" }, "VPCSecurityGroups": [{ "Ref": "SecurityGroup" }], "StorageType": "gp2", "MasterUsername": "EsriRDSAdmin", "MasterUserPassword": { "Ref": "SiteAdminPassword" }, "Tags": [{ "Key": "Name", "Value": { "Fn::Join": ["", [{ "Ref": "AWS::StackName" }, "-db"]] } }] } }, "AuroraDBInstance": { "Type": "AWS::RDS::DBInstance", "Condition": "DBEngineAurora", "Properties": { "DBInstanceClass": { "Ref": "DBInstanceClass" }, "DBClusterIdentifier": { "Ref": "AuroraDBCluster" }, "Engine": { "Ref": "DBEngine" }, "Tags": [{ "Key": "Name", "Value": { "Fn::Join": ["", [{ "Ref": "AWS::StackName" }, "-db"]] } }] } }, "AuroraDBCluster": { "Type": "AWS::RDS::DBCluster", "Condition": "DBEngineAurora", "Properties": { "DBSubnetGroupName": { "Ref": "DBSubnetGroup" }, "DBClusterParameterGroupName": { "Ref": "AuroraDBClusterParameterGroup" }, "Engine": { "Ref": "DBEngine" }, "EngineVersion": { "Fn::FindInMap": ["DBEngineProperties", { "Ref": "DBEngine" }, "Version"] }, "MasterUsername": "EsriRDSAdmin", "MasterUserPassword": { "Ref": "SiteAdminPassword" }, "Port": 5432, "Tags": [{ "Key": "Name", "Value": { "Fn::Join": ["", [{ "Ref": "AWS::StackName" }, "-db"]] } }], "VpcSecurityGroupIds": [{ "Ref": "SecurityGroup" }] } }, "AuroraDBClusterParameterGroup": { "Type": "AWS::RDS::DBClusterParameterGroup", "Condition": "DBEngineAurora", "Properties": { "Description": "Aurora postgresql 9.6 engine parameters", "Family": "aurora-postgresql9.6", "Parameters": { "client_encoding": "UTF8" }, "Tags": [{ "Key": "Name", "Value": { "Fn::Join": ["", [{ "Ref": "AWS::StackName" }, "-db"]] } }] } }, "UnregisterMachineCommand": { "Type": "AWS::SSM::Document", "Properties": { "Content": { "schemaVersion": "1.0", "description": "Unregisters the machine from ArcGIS Server site.", "runtimeConfig": { "aws:psModule": { "properties": [{ "runCommand": "chef-solo -j C:\\chef\\unregister_machine.json" }] } } } } }, "UnregisterFileServer": { "Type": "AWS::SSM::Association", "DependsOn": "AutoScalingGroupWaitCondition", "Properties": { "Name": { "Ref": "UnregisterMachineCommand" }, "Targets": [{ "Key": "InstanceIds", "Values": [{ "Ref": "FileServerEC2Instance" }] }] } } }, "Outputs": { "ManagerURL": { "Value": { "Fn::Join": ["", ["https://", { "Fn::GetAtt": ["ELBAttributes", "DNSName"] }, "/arcgis/manager"]] }, "Description": "ArcGIS Server Manager URL" }, "RestURL": { "Value": { "Fn::Join": ["", ["https://", { "Fn::GetAtt": ["ELBAttributes", "DNSName"] }, "/arcgis/rest"]] }, "Description": "ArcGIS REST Services Directory URL" }, "LogsURL": { "Value": { "Fn::Join": ["", ["https://console.aws.amazon.com/cloudwatch/home?region=", { "Ref": "AWS::Region" }, "#logStream:group=", { "Ref": "DeploymentLogs" }]] }, "Description": "Deployment Logs" }, "DNSName": { "Description": "Elastic load balancer DNS name", "Value": { "Fn::GetAtt": ["ELBAttributes", "DNSName"] } }, "StopStackFunction": { "Value": { "Fn::Join": ["", ["https://console.aws.amazon.com/lambda/home?region=", { "Ref": "AWS::Region" }, "#/functions/", { "Ref": "StopStackFunction" }]] }, "Description": "Lambda function used to stop all EC2 instances in the stack." }, "StartStackFunction": { "Value": { "Fn::Join": ["", ["https://console.aws.amazon.com/lambda/home?region=", { "Ref": "AWS::Region" }, "#/functions/", { "Ref": "StartStackFunction" }]] }, "Description": "Lambda function used to start all EC2 instances in the stack." }, "VPCId": { "Value": { "Ref": "VPCId" }, "Description": "VPC ID" }, "Subnet1": { "Value": { "Ref": "Subnet1" }, "Description": "VPC subnet 1" }, "Subnet2": { "Value": { "Ref": "Subnet2" }, "Description": "VPC subnet 2" }, "DeploymentBucket": { "Value": { "Ref": "DeploymentBucket" }, "Description": "Deployment S3 bucket" }, "SecurityGroup": { "Value": { "Ref": "SecurityGroup" }, "Description": "Security group" }, "ELBName": { "Value": { "Fn::If": ["NewELB", { "Ref": "ELB" }, { "Ref": "ELBName" }] }, "Description": "ELB name" }, "FileServerEC2InstancePrivateIp": { "Value": { "Fn::GetAtt": ["FileServerEC2Instance", "PrivateIp"] }, "Description": "Private IP address of the file server EC2 instance" }, "StoreType": { "Value": { "Ref": "StoreType" }, "Description": "ArcGIS Server config store type" } } }