﻿{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "ArcGIS CloudFormation Template: Provisions an ArcGIS GeoEvent Server 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-0e9eb268b0c71c5ce"
      },
      "ap-northeast-1": {
        "en": "ami-0c41ff533aff3a952"
      },
      "ap-northeast-2": {
        "en": "ami-0d6afadbb417bd335"
      },
      "ap-south-1": {
        "en": "ami-0c65fae61e689acd0"
      },
      "ap-southeast-1": {
        "en": "ami-019f681bf598e656e"
      },
      "ap-southeast-2": {
        "en": "ami-0d625557b2c392f9e"
      },
      "ca-central-1": {
        "en": "ami-0de61a16068d6ff9d"
      },
      "eu-central-1": {
        "en": "ami-0d9034303d6388660"
      },
      "eu-north-1": {
        "en": "ami-0ad97b20ae3aaaa87"
      },
      "eu-west-1": {
        "en": "ami-051535af5e2dd0cd3"
      },
      "eu-west-2": {
        "en": "ami-013337d1b8e428c9b"
      },
      "eu-west-3": {
        "en": "ami-064cb0c3e7bf5a2fd"
      },
      "sa-east-1": {
        "en": "ami-0f110e729620c5900"
      },
      "us-east-1": {
        "en": "ami-0969f295b1df66324"
      },
      "us-east-2": {
        "en": "ami-0b1f3b9f43efbc688"
      },
      "us-west-1": {
        "en": "ami-01a77a9582812efbd"
      },
      "us-west-2": {
        "en": "ami-04e71f31b515539de"
      },
      "us-gov-east-1": {
        "en": "ami-05d57ed89e87252a8"
      },
      "us-gov-west-1": {
        "en": "ami-0f442609edf61e14a"
      }
    }
  },
  "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.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.xlarge",
      "ConstraintDescription": "Only C3, C4, M3, and R3 instance types are supported"
    },
    "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",
        "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"
    },
    "KeyName": {
      "Description": "EC2 Key Pair to allow RemoteDesktop access to the instances",
      "Type": "AWS::EC2::KeyPair::KeyName"
    },
    "ServerLicenseFile": {
      "Description": "ArcGIS GeoEvent 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"
    },
    "SSLCertificateFile": {
      "Description": "SSL certificate file issued to the site domain (must be uploaded to DeploymentBucket)",
      "Type": "String",
      "AllowedPattern": "^([/\\w\\-\\.]+)+\\.(pfx)$",
      "ConstraintDescription": "Certificate file name must be alphanumeric. It can contain slash ('/'), dash ('-'), dot ('.'), and underscore ('_') characters. The file name must end with '.pfx'"
    },
    "SSLCertPassword": {
      "Description": "SSL certificate file password",
      "Type": "String",
      "NoEcho": "true",
      "AllowedPattern": "[^\\\"]{1,128}",
      "ConstraintDescription": "Password must be between 1 and 128 characters and must not contain backslashes (\\) or quotation marks (\")."
    },
    "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", "DriveSizeRoot", "KeyName"]
        },
        {
          "Label": {
            "default": "ArcGIS Enterprise Configuration"
          },
          "Parameters": ["DeploymentBucket", "ServerLicenseFile", "SiteAdmin", "SiteAdminPassword", "RunAsUserPassword"]
        }
      ]
    }
  },
  "Conditions": {
    "CreateDHCPOptions": {
      "Fn::Equals": [{
        "Ref": "AWS::Region"
      }, "us-east-1"]
    },
    "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": "elbv2_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", {
            "Fn::GetAtt": ["ELB", "LoadBalancerName"]
          }, {
            "Ref": "ELBName"
          }]
        },
        "ELBTemplate": "geoevent",
        "ELBSubnets": [{
          "Ref": "Subnet1"
        }, {
          "Ref": "Subnet2"
        }],
        "TargetGroups": [{
            "Fn::If": ["NewELB", {
              "Fn::GetAtt": ["AGSHttpTarget", "TargetGroupName"]
            }, ""]
          },
          {
            "Fn::If": ["NewELB", {
              "Fn::GetAtt": ["AGSHttpsTarget", "TargetGroupName"]
            }, ""]
          },
          {
            "Fn::If": ["NewELB", {
              "Fn::GetAtt": ["GEEHttpTarget", "TargetGroupName"]
            }, ""]
          },
          {
            "Fn::If": ["NewELB", {
              "Fn::GetAtt": ["GEEHttpsTarget", "TargetGroupName"]
            }, ""]
          }
        ]
      }
    },
    "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": [{
                "Effect": "Allow",
                "Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
                "Resource": "*"
              },
              {
                "Effect": "Allow",
                "Action": ["dynamodb:*"],
                "Resource": "*"
              },
              {
                "Effect": "Allow",
                "Action": ["s3:*"],
                "Resource": "*"
              },
              {
                "Effect": "Allow",
                "Action": ["ec2:*"],
                "Resource": "*"
              },
              {
                "Effect": "Allow",
                "Action": ["cloudformation:*"],
                "Resource": "*"
              },
              {
                "Effect": "Allow",
                "Action": ["autoscaling:*"],
                "Resource": "*"
              },
              {
                "Effect": "Allow",
                "Action": ["elasticloadbalancing:*"],
                "Resource": "*"
              }
            ]
          }
        }]
      }
    },
    "ValidateServerLicenseFile": {
      "Type": "Custom::ValidateParameters",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": ["ValidateParametersFunction", "Arn"]
        },
        "DeploymentBucket": {
          "Ref": "DeploymentBucket"
        },
        "S3Key": {
          "Ref": "ServerLicenseFile"
        }
      }
    },
    "ValidateSSLCertificateFile": {
      "Type": "Custom::ValidateParameters",
      "DependsOn": "ValidateServerLicenseFile",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": ["ValidateParametersFunction", "Arn"]
        },
        "DeploymentBucket": {
          "Ref": "DeploymentBucket"
        },
        "S3Key": {
          "Ref": "SSLCertificateFile"
        }
      }
    },
    "ValidatePostInstallationScript": {
      "Type": "Custom::ValidateParameters",
      "Condition": "RunPostInstall",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": ["ValidateParametersFunction", "Arn"]
        },
        "DeploymentBucket": {
          "Ref": "DeploymentBucket"
        },
        "S3Key": {
          "Ref": "PostInstallationScript"
        }
      }
    },
    "ELB": {
      "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
      "Condition": "NewELB",
      "Properties": {
        "Type": "network",
        "Subnets": [{
          "Ref": "Subnet1"
        }, {
          "Ref": "Subnet2"
        }],
        "Scheme": "internet-facing"
      }
    },
    "AGSHttpListener": {
      "Type": "AWS::ElasticLoadBalancingV2::Listener",
      "Condition": "NewELB",
      "Properties": {
        "DefaultActions": [{
          "TargetGroupArn": {
            "Ref": "AGSHttpTarget"
          },
          "Type": "forward"
        }],
        "LoadBalancerArn": {
          "Ref": "ELB"
        },
        "Port": 80,
        "Protocol": "TCP"
      }
    },
    "AGSHttpsListener": {
      "Type": "AWS::ElasticLoadBalancingV2::Listener",
      "Condition": "NewELB",
      "Properties": {
        "DefaultActions": [{
          "TargetGroupArn": {
            "Ref": "AGSHttpsTarget"
          },
          "Type": "forward"
        }],
        "LoadBalancerArn": {
          "Ref": "ELB"
        },
        "Port": 443,
        "Protocol": "TCP"
      }
    },
    "GEEHttpListener": {
      "Type": "AWS::ElasticLoadBalancingV2::Listener",
      "Condition": "NewELB",
      "Properties": {
        "DefaultActions": [{
          "TargetGroupArn": {
            "Ref": "GEEHttpTarget"
          },
          "Type": "forward"
        }],
        "LoadBalancerArn": {
          "Ref": "ELB"
        },
        "Port": 6180,
        "Protocol": "TCP"
      }
    },
    "GEEHttpsListener": {
      "Type": "AWS::ElasticLoadBalancingV2::Listener",
      "Condition": "NewELB",
      "Properties": {
        "DefaultActions": [{
          "TargetGroupArn": {
            "Ref": "GEEHttpsTarget"
          },
          "Type": "forward"
        }],
        "LoadBalancerArn": {
          "Ref": "ELB"
        },
        "Port": 6143,
        "Protocol": "TCP"
      }
    },
    "AGSHttpTarget": {
      "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
      "Condition": "NewELB",
      "Properties": {
        "HealthCheckIntervalSeconds": 10,
        "HealthCheckPath": "/arcgis/rest/info/healthcheck",
        "HealthCheckPort": 6080,
        "HealthCheckProtocol": "HTTP",
        "HealthyThresholdCount": 3,
        "UnhealthyThresholdCount": 3,
        "Port": 6080,
        "Protocol": "TCP",
        "TargetType": "instance",
        "VpcId": {
          "Ref": "VPCId"
        }
      }
    },
    "AGSHttpsTarget": {
      "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
      "Condition": "NewELB",
      "Properties": {
        "HealthCheckIntervalSeconds": 10,
        "HealthCheckPath": "/arcgis/rest/info/healthcheck",
        "HealthCheckPort": 6443,
        "HealthCheckProtocol": "HTTPS",
        "HealthyThresholdCount": 3,
        "UnhealthyThresholdCount": 3,
        "Port": 6443,
        "Protocol": "TCP",
        "TargetType": "instance",
        "VpcId": {
          "Ref": "VPCId"
        }
      }
    },
    "GEEHttpTarget": {
      "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
      "Condition": "NewELB",
      "Properties": {
        "Port": 6180,
        "Protocol": "TCP",
        "TargetType": "instance",
        "VpcId": {
          "Ref": "VPCId"
        }
      }
    },
    "GEEHttpsTarget": {
      "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
      "Condition": "NewELB",
      "Properties": {
        "Port": 6143,
        "Protocol": "TCP",
        "TargetType": "instance",
        "VpcId": {
          "Ref": "VPCId"
        }
      }
    },
    "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": {
          "Statement": [{
            "Action": ["s3:*", "dynamodb:*", "cloudformation:*", "logs:*", "ssm:*", "ec2messages:*", "ec2:ModifyInstanceMetadataOptions"],
            "Effect": "Allow",
            "Resource": "*"
          }]
        },
        "Roles": [{
          "Ref": "IAMRole"
        }]
      }
    },
    "IAMInstanceProfile": {
      "Type": "AWS::IAM::InstanceProfile",
      "Properties": {
        "Path": "/",
        "Roles": [{
          "Ref": "IAMRole"
        }]
      }
    },
    "SecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": {
          "Ref": "AWS::StackName"
        },
        "VpcId": {
          "Ref": "VPCId"
        },
        "SecurityGroupIngress": [{
          "IpProtocol": "tcp",
          "FromPort": "6080",
          "ToPort": "6080",
          "CidrIp": "0.0.0.0/0"
        }, {
          "IpProtocol": "tcp",
          "FromPort": "6443",
          "ToPort": "6443",
          "CidrIp": "0.0.0.0/0"
        }, {
          "IpProtocol": "tcp",
          "FromPort": "6180",
          "ToPort": "6180",
          "CidrIp": "0.0.0.0/0"
        }, {
          "IpProtocol": "tcp",
          "FromPort": "6143",
          "ToPort": "6143",
          "CidrIp": "0.0.0.0/0"
        }, {
          "IpProtocol": "tcp",
          "FromPort": "80",
          "ToPort": "80",
          "CidrIp": "0.0.0.0/0"
        }, {
          "IpProtocol": "tcp",
          "FromPort": "443",
          "ToPort": "443",
          "CidrIp": "0.0.0.0/0"
        }]
      }
    },
    "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": [
              "",
              [
                "<powershell>\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",
                "</powershell>\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:\\Temp\\keystore.pfx": {
                "source": {
                  "Fn::GetAtt": ["ValidateSSLCertificateFile", "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",
                    "    },\r\n",
                    "    \"server\" : {\r\n",
                    "      \"keystore_file\" : \"C:\\\\Temp\\\\keystore.pfx\",\r\n",
                    "      \"keystore_password\" : \"", {
                      "Ref": "SSLCertPassword"
                    }, "\",\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\" : \"FILESYSTEM\",\r\n",
                    "      \"config_store_connection_string\" : \"\\\\\\\\FILESERVER\\\\config-store\"\r\n",
                    "    }\r\n",
                    "  },\r\n",
                    "  \"run_list\" : [\r\n",
                    "    \"recipe[arcgis-enterprise::system]\",\r\n",
                    "    \"recipe[arcgis-enterprise::fileserver]\",\r\n",
                    "    \"recipe[arcgis-enterprise::server]\",\r\n",
                    "    \"recipe[arcgis-geoevent]\",\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": [
                "",
                [
                  "<powershell>\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",
                  "</powershell>\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:\\Temp\\keystore.pfx": {
                "source": {
                  "Fn::GetAtt": ["ValidateSSLCertificateFile", "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",
                    "    },\r\n",
                    "    \"server\" : {\r\n",
                    "      \"keystore_file\" : \"C:\\\\Temp\\\\keystore.pfx\",\r\n",
                    "      \"keystore_password\" : \"", {
                      "Ref": "SSLCertPassword"
                    }, "\",\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\" : \"FILESYSTEM\",\r\n",
                    "      \"config_store_connection_string\" : \"\\\\\\\\FILESERVER\\\\config-store\"\r\n",
                    "    }\r\n",
                    "  },\r\n",
                    "  \"run_list\" : [\r\n",
                    "    \"recipe[arcgis-enterprise::system]\",\r\n",
                    "    \"recipe[arcgis-enterprise::server_node]\",\r\n",
                    "    \"recipe[arcgis-geoevent]\",\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": 1,
        "MinSize": 1,
        "LaunchTemplate": {
          "LaunchTemplateId": {
            "Ref": "AutoScalingInstanceLaunchTemplate"
          },
          "Version": {
            "Fn::GetAtt": [
              "AutoScalingInstanceLaunchTemplate",
              "LatestVersionNumber"
            ]
          }
        },
        "HealthCheckType": "EC2",
        "HealthCheckGracePeriod": "3600",
        "TargetGroupARNs": {
          "Fn::GetAtt": ["ELBAttributes", "TargetGroupARNs"]
        },
        "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": 1,
        "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"
              }
            }
          }
        }
      }
    },
    "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"]
        }, ":6443/arcgis/manager"]]
      },
      "Description": "ArcGIS Server Manager URL"
    },
    "GeoEventManagerURL": {
      "Value": {
        "Fn::Join": ["", ["https://", {
          "Fn::GetAtt": ["ELBAttributes", "DNSName"]
        }, ":6143/geoevent/manager"]]
      },
      "Description": "ArcGIS GeoEvent 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"
    }
  }
}
