{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Highly available configuration of ArcGIS Portal, Server, and DataStore (Ubuntu)",
  "Mappings": {
    "RegionMap" : {
      "ap-east-1": {
        "en": "ami-0a908d32be355f897"
      },
      "ap-northeast-1": {
        "en": "ami-02fce661b938024d2"
      },
      "ap-northeast-2": {
        "en": "ami-018807f597543a2de"
      },
      "ap-south-1": {
        "en": "ami-0060b6c91eb8b1475"
      },
      "ap-southeast-1": {
        "en": "ami-099ecfd42bd5d32a4"
      },
      "ap-southeast-2": {
        "en": "ami-0f0bd2b430af0f5fc"
      },
      "ca-central-1": {
        "en": "ami-0daa2389c645945fc"
      },
      "eu-central-1": {
        "en": "ami-0e73bd30a22a7164d"
      },
      "eu-north-1": {
        "en": "ami-05190f5e864864f6b"
      },
      "eu-west-1": {
        "en": "ami-078bbce609b4fbfcf"
      },
      "eu-west-2": {
        "en": "ami-0ceaf21e7ce2c6bcd"
      },
      "eu-west-3": {
        "en": "ami-00ece6d6c02447765"
      },
      "sa-east-1": {
        "en": "ami-0b413faeb309196a4"
      },
      "us-east-1": {
        "en": "ami-05493378a2ab1d54a"
      },
      "us-east-2": {
        "en": "ami-007adc0d43045782f"
      },
      "us-west-1": {
        "en": "ami-0b6a256e06852866c"
      },
      "us-west-2": {
        "en": "ami-0a5a46fa2b3064aa9"
      },
      "us-gov-east-1": {
        "en": "ami-04d63d15fac7b4729"
      },
      "us-gov-west-1": {
        "en": "ami-0c1bb8e3167200087"
      },
    }
  },
  "Parameters": {
    "DeploymentBucket": {
      "Description": "S3 bucket with authorization files and SSL certificates",
      "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 Web GIS EC2 instance type",
      "Type": "String",
      "AllowedValues": [
        "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.xlarge", "m3.2xlarge",
        "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "m4.16xlarge",
        "m5.xlarge", "m5.2xlarge", "m5.4xlarge", "m5.12xlarge", "m5.24xlarge", "m5.metal",
        "m5a.xlarge", "m5a.2xlarge", "m5a.4xlarge", "m5a.12xlarge", "m5a.24xlarge",
        "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge",
        "r4.xlarge", "r4.2xlarge", "r4.4xlarge", "r4.8xlarge", "r4.16xlarge",
        "r5.xlarge", "r5.2xlarge", "r5.4xlarge", "r5.12xlarge", "r5.24xlarge", "r5.metal",
        "r5a.xlarge", "r5a.2xlarge", "r5a.4xlarge", "r5a.12xlarge", "r5a.24xlarge",
        "t2.xlarge", "t2.2xlarge",
        "t3.xlarge", "t3.2xlarge",
        "x1.16xlarge", "x1.32xlarge",
        "x1e.xlarge", "x1e.2xlarge", "x1e.4xlarge", "x1e.8xlarge", "x1e.16xlarge", "x1e.32xlarge"
      ],
      "Default": "m4.xlarge"
    },
    "BDSInstanceType": {
      "Description": "Spatio-temporal Big Data Store 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": "r5.xlarge"
    },
    "BDSInstances": {
      "Description": "Number of spatio-temporal Big Data Store EC2 instances",
      "Type": "Number",
      "Default": "0",
      "AllowedValues": [0, 1]
    },
    "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"
    },
    "ELBName": {
      "Description": "Name of an existing ELB or 'NEW_ELB' to create and use a new one.",
      "Type": "String",
      "Default": "NEW_ELB"
    },
    "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'."
    },
    "PortalLicenseFile": {
      "Description": "Portal for ArcGIS authorization file (must be uploaded to DeploymentBucket)",
      "Type": "String",
      "AllowedPattern": "^([/\\w\\-\\.]+)+\\.(json)$",
      "ConstraintDescription": "License file name must be alphanumeric. It can contain dash ('-'), dot ('.'), and underscore ('_') characters. The file name must end with '.json'"
    },
    "UserLicenseTypeID": {
      "Description": "Portal administrator user license type ID.",
      "Type": "String",
      "Default": ""
    },
    "SiteAdmin": {
      "Description": "User name for ArcGIS Server site admin and Portal initial admin accounts",
      "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 ArcGIS Server site admin and Portal initial admin accounts",
      "Type": "String",
      "NoEcho": "true",
      "AllowedPattern": "^[a-zA-Z0-9_\\.@]{8,}$",
      "ConstraintDescription": "Password must be 8 or more alphanumeric, underscore (_), at ('@'), or dot (.) characters."
    },
    "SiteDomain": {
      "Description": "The domain name of your Web GIS site",
      "Type": "String",
      "AllowedPattern": "^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([a-zA-Z]|[a-zA-Z][a-zA-Z0-9-]*[a-zA-Z0-9])$",
      "ConstraintDescription": "The domain name is invalid."
    },
    "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", "SiteDomain", "ELBName"]
        },
        {
          "Label": {
            "default": "Amazon EC2 Configuration"
          },
          "Parameters": ["FSInstanceType", "ASInstanceType", "BDSInstanceType", "BDSInstances", "DriveSizeRoot", "KeyName"]
        },
        {
          "Label": {
            "default": "ArcGIS Enterprise Configuration"
          },
          "Parameters": ["DeploymentBucket", "ServerLicenseFile", "PortalLicenseFile", "StoreType", "SiteAdmin", "SiteAdminPassword", "SSLCertificateFile", "SSLCertPassword"]
        }
      ]
    }
  },
  "Conditions": {
    "UseCloudStore": {
      "Fn::Equals": [{
        "Ref": "StoreType"
      }, "CloudStore"]
    },
    "RunPostInstall": {
      "Fn::Not": [{
        "Fn::Equals": [{
          "Ref": "PostInstallationScript"
        }, "none"]
      }]
    },
    "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_webgis_ha_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_webgis_ha_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": "webgis",
        "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"
      }
    },
    "ELBInstance1": {
      "Type": "Custom::ELBInstance",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": ["ELBInstanceFunction", "Arn"]
        },
        "ELBName": {
          "Fn::If": ["NewELB", {
            "Ref": "ELB"
          }, {
            "Ref": "ELBName"
          }]
        },
        "InstanceId": {
          "Ref": "PrimaryServerEC2Instance"
        }
      }
    },
    "ELBInstance2": {
      "Type": "Custom::ELBInstance",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": ["ELBInstanceFunction", "Arn"]
        },
        "ELBName": {
          "Fn::If": ["NewELB", {
            "Ref": "ELB"
          }, {
            "Ref": "ELBName"
          }]
        },
        "InstanceId": {
          "Ref": "SecondaryServerEC2Instance"
        }
      }
    },
    "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"
        }
      }
    },
    "ValidatePortalLicenseFile": {
      "Type": "Custom::ValidateParameters",
      "DependsOn": "ValidateServerLicenseFile",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": ["ValidateParametersFunction", "Arn"]
        },
        "DeploymentBucket": {
          "Ref": "DeploymentBucket"
        },
        "S3Key": {
          "Ref": "PortalLicenseFile"
        }
      }
    },
    "ValidateSSLCertificateFile": {
      "Type": "Custom::ValidateParameters",
      "DependsOn": "ValidatePortalLicenseFile",
      "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"
        }
      }
    },
    "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"
          }]]
        }
      }
    },
    "DeploymentLogs": {
      "Type": "AWS::Logs::LogGroup",
      "DependsOn": "ValidateSSLCertificateFile",
      "Properties": {
        "RetentionInDays": 7
      }
    },
    "ELB": {
      "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
      "Condition": "NewELB",
      "Properties": {
        "Subnets": [{
          "Ref": "Subnet1"
        }, {
          "Ref": "Subnet2"
        }],
        "SecurityGroups": [{
          "Ref": "ELBSecurityGroup"
        }],
        "Scheme": "internet-facing",
        "Listeners": [{
          "LoadBalancerPort": "80",
          "InstancePort": "80",
          "Protocol": "HTTP"
        }, {
          "LoadBalancerPort": "443",
          "InstancePort": "443",
          "Protocol": "TCP",
          "InstanceProtocol": "TCP"
        }],
        "HealthCheck": {
          "Target": "HTTPS:443/server/rest/info/healthcheck",
          "HealthyThreshold": "3",
          "UnhealthyThreshold": "5",
          "Interval": "30",
          "Timeout": "5"
        }
      }
    },
    "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"
        }]
      }
    },
    "IAMRole": {
      "Type": "AWS::IAM::Role",
      "DependsOn": "LambdaExecutionRole",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [{
            "Effect": "Allow",
            "Principal": {
              "Service": ["ec2.amazonaws.com"]
            },
            "Action": ["sts:AssumeRole"]
          }]
        },
        "Path": "/"
      }
    },
    "IAMPolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": "IAMRole",
        "PolicyDocument": {
          "Statement": [{
            "Action": ["s3:*", "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": "80",
          "ToPort": "80",
          "SourceSecurityGroupId": {
            "Fn::If": ["NewELB", {
              "Ref": "ELBSecurityGroup"
            }, {
              "Fn::GetAtt": ["ELBAttributes", "SourceSecurityGroupId"]
            }]
          }
        }, {
          "IpProtocol": "tcp",
          "FromPort": "443",
          "ToPort": "443",
          "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"
        }
      }
    },
    "PortalContent": {
      "Type": "AWS::S3::Bucket",
      "Condition": "UseCloudStore",
      "DeletionPolicy": "Retain",
      "Properties": {
        "Tags": [{
          "Key": "Name",
          "Value": {
            "Ref": "AWS::StackName"
          }
        }, {
          "Key": "Application",
          "Value": "arcgis-allinone-windows"
        }]
      }
    },
    "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": "ASInstanceType"
          },
          "KeyName": {
            "Ref": "KeyName"
          },
          "NetworkInterfaces": [{
            "AssociatePublicIpAddress": true,
            "DeleteOnTermination": true,
            "DeviceIndex": "0",
            "Groups": [{
              "Ref": "SecurityGroup"
            }],
            "SubnetId": {
              "Ref": "Subnet1"
            }
          }]
        }
      }
    },
    "FileServerEC2Instance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "InstanceType": {
          "Ref": "FSInstanceType"
        },
        "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": ["", [
              "#!/bin/bash -v\n",
              "sudo resize2fs /dev/disk/by-label/gisdata || true\n",
              "cfn-init -v -s ", {
                "Ref": "AWS::StackName"
              }, " -r FileServerEC2Instance", " --region ", {
                "Ref": "AWS::Region"
              }, "\n",
              "exitcode=$?\n",
              "wget https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py\n",
              "sudo python3 awslogs-agent-setup.py -n -r ", {
                "Ref": "AWS::Region"
              },
              " -c /tmp/cwlogs/cwlogs.conf || error_exit 'Failed to run CloudWatch Logs agent setup'\n",
              "if [ $exitcode -ne 0 ]; then\n",
              "  cfn-signal -e $exitcode -r 'cfn-init failed. See /var/log/cfn-init.log for details.' '",
              {
                "Ref": "FileServerWaitHandle"
              }, "'\n",
              "  exit $exitcode\n",
              "fi\n",
              "if ", {
                "Fn::If": ["RunPostInstall", "true", "false"]
              }, "; then\n",
              "  cfn-init -v -c post-install-script -s ", {
                "Ref": "AWS::StackName"
              }, " -r FileServerEC2Instance", " --region ", {
                "Ref": "AWS::Region"
              }, "\n",
              "fi\n",
              "chmod 777 /mnt\n",
              "export arcgis_cloud_platform=aws\n",
              "chef-solo -j /etc/chef/node.json -r https://arcgisstore1081.s3.amazonaws.com/14362/cookbooks/arcgis-3.6.0-cookbooks.tar.gz -L /var/log/chef-run.log -l info\n",
              "exitcode=$?\n",
              "if [ $exitcode -ne 0 ]; then\n",
              "  cfn-signal -e $exitcode -r 'Chef run failed. See /var/log/chef-run.log for details.' '", {
                "Ref": "FileServerWaitHandle"
              }, "'\n",
              "  exit $exitcode\n",
              "fi\n",
              "cfn-signal -e 0 -r 'Setup complete' '", {
                "Ref": "FileServerWaitHandle"
              }, "'\n"
            ]]
          }
        }
      },
      "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": {
              "/arcgis/postinstallscripts": {
                "Fn::If": ["RunPostInstall", {
                  "Fn::GetAtt": ["ValidatePostInstallationScript", "S3ObjectURL"]
                }, ""]
              }
            }
          },
          "config": {
            "files": {
              "/tmp/cwlogs/cwlogs.conf": {
                "content": {
                  "Fn::Join": ["", [
                    "[general]\n",
                    "state_file= /var/awslogs/agent-state\n",
                    "[/var/log/cfn-init.log]\n",
                    "file = /var/log/cfn-init.log\n",
                    "log_group_name = ", {
                      "Ref": "DeploymentLogs"
                    }, "\n",
                    "log_stream_name = {instance_id}/cfn-init.log\n",
                    "datetime_format = %d/%b/%Y:%H:%M:%S\n",
                    "[/var/log/chef-run.log]\n",
                    "file = /var/log/chef-run.log\n",
                    "log_group_name = ", {
                      "Ref": "DeploymentLogs"
                    }, "\n",
                    "log_stream_name = {instance_id}/chef-run.log\n",
                    "datetime_format = %Y-%m-%dT%H:%M:%S%z\n",
                    "[/var/lib/tomcat7/logs/catalina.out]\n",
                    "file = /var/lib/tomcat7/logs/catalina.out\n",
                    "log_group_name = ", {
                      "Ref": "DeploymentLogs"
                    }, "\n",
                    "log_stream_name = {instance_id}/catalina.out\n",
                    "datetime_format = %d/%b/%Y:%H:%M:%S"
                  ]]
                },
                "mode": "000755"
              },
              "/etc/chef/node.json": {
                "content": {
                  "Fn::Join": ["", [
                    "{\n",
                    "  \"arcgis\" : {\n",
                    "    \"version\": \"10.8.1\",\n",
                    "    \"post_install_script\" : \"/arcgis/postinstallscripts/deploy.sh\",\n",
                    "    \"server\" : {\n",
                    "      \"local_directories_root\" : \"/gisdata/arcgisserver\"\n",
                    "    },\n",
                    "    \"data_store\" : {\n",
                    "      \"local_backup_dir\" : \"/gisdata/arcgisdatastore/backup\"\n",
                    "    },\n",
                    "    \"portal\" : {\n",
                    "      \"local_content_dir\" : \"/gisdata/arcgisportal/content\"\n",
                    "    }\n",
                    "  },\n",
                    "  \"run_list\" : [\n",
                    "    \"recipe[arcgis-enterprise::system]\",\n",
                    "    \"recipe[arcgis-enterprise::fileserver]\",\n",
                    "    \"recipe[arcgis-enterprise::post_install]\"]\n",
                    "}\n"
                  ]]
                },
                "mode": "000755"
              }
            }
          }
        }
      }
    },
    "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"
          }
        }]
      }
    },
    "FileServerWaitHandle": {
      "Type": "AWS::CloudFormation::WaitConditionHandle",
      "Properties": {}
    },
    "FileServerWaitCondition": {
      "Type": "AWS::CloudFormation::WaitCondition",
      "Properties": {
        "Count": "1",
        "Handle": {
          "Ref": "FileServerWaitHandle"
        },
        "Timeout": "7200"
      }
    },
    "PrimaryServerEC2Instance": {
      "Type": "AWS::EC2::Instance",
      "DependsOn": "FileServerWaitCondition",
      "Properties": {
        "Monitoring": true,
        "LaunchTemplate": {
          "LaunchTemplateId": {
            "Ref": "EC2InstanceLaunchTemplate"
          },
          "Version": {
            "Fn::GetAtt": [
              "EC2InstanceLaunchTemplate",
              "LatestVersionNumber"
            ]
          }
        },
        "Tags": [{
          "Key": "Name",
          "Value": {
            "Fn::Join": ["", [{
              "Ref": "AWS::StackName"
            }, "-primary"]]
          }
        }],
        "UserData": {
          "Fn::Base64": {
            "Fn::Join": ["", [
              "#!/bin/bash -v\n",
              "for i in {1..60}; do ping -c1 $(hostname); if [ $? -eq 0 ]; then break; fi; sleep 10; done\n",
              "ping -c1 $(hostname)\n",
              "exitcode=$?\n",
              "if [ $exitcode -ne 0 ]; then\n",
              "  cfn-signal -e $exitcode -r 'Failed to resolve the host name. Check the VPC settings.' '", {
                "Ref": "PrimaryServerWaitHandle"
              }, "'\n",
              "  exit $exitcode\n",
              "fi\n",
              "echo 'disable unattended upgrades'\n",
              "cp /etc/apt/apt.conf.d/20auto-upgrades /etc/apt/apt.conf.d/20auto-upgrades.original\n",
              "echo -e \"APT::Periodic::Update-Package-Lists \\\"0\\\";\\nAPT::Periodic::Unattended-Upgrade \\\"0\\\";\" > /etc/apt/apt.conf.d/20auto-upgrades\n",
              "/etc/init.d/unattended-upgrades restart\n",
              "lockdetails=$(sudo lsof /var/lib/dpkg/lock)\n",
              "while [ ! -z \"$lockdetails\" ]; do\n",
              "  echo 'Waiting for lock to release'\n",
              "  sleep 1m\n",
              "  lockdetails=$(sudo lsof /var/lib/dpkg/lock)\n",
              "done\n",
              "if ", {
                "Fn::If": ["RunPostInstall", "true", "false"]
              }, "; then\n",
              "  cfn-init -v -c post-install-script -s ", {
                "Ref": "AWS::StackName"
              }, " -r PrimaryServerEC2Instance", " --region ", {
                "Ref": "AWS::Region"
              }, "\n",
              "fi\n",
              "cfn-init -v -c firstpass -s ", {
                "Ref": "AWS::StackName"
              }, " -r PrimaryServerEC2Instance", " --region ", {
                "Ref": "AWS::Region"
              }, "\n",
              "cfn-init -v -c  secondpass -s ", {
                "Ref": "AWS::StackName"
              }, " -r PrimaryServerEC2Instance", " --region ", {
                "Ref": "AWS::Region"
              }, "\n",
              "exitcode=$?\n",
              "wget https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py\n",
              "sudo python3 awslogs-agent-setup.py -n -r ", {
                "Ref": "AWS::Region"
              },
              " -c /tmp/cwlogs/cwlogs.conf || error_exit 'Failed to run CloudWatch Logs agent setup'\n",
              "if [ $exitcode -ne 0 ]; then\n",
              "  cfn-signal -e $exitcode -r 'cfn-init failed. See /var/log/cfn-init.log for details.' '",
              {
                "Ref": "PrimaryServerWaitHandle"
              }, "'\n",
              "  exit $exitcode\n",
              "fi\n",
              "chmod 777 /mnt\n",
              "export arcgis_cloud_platform=aws\n",
              "chef-solo -j /etc/chef/node.json -r https://arcgisstore1081.s3.amazonaws.com/14362/cookbooks/arcgis-3.6.0-cookbooks.tar.gz -L /var/log/chef-run.log -l info\n",
              "exitcode=$?\n",
              "if [ $exitcode -ne 0 ]; then\n",
              "  cfn-signal -e $exitcode -r 'Chef run failed. See /var/log/chef-run.log for details.' '", {
                "Ref": "PrimaryServerWaitHandle"
              }, "'\n",
              "  exit $exitcode\n",
              "fi\n",
              "cfn-signal -e 0 -r 'Setup complete' '", {
                "Ref": "PrimaryServerWaitHandle"
              }, "'\n",
              "echo 'enable unattended upgrades'\n",
              "mv /etc/apt/apt.conf.d/20auto-upgrades.original /etc/apt/apt.conf.d/20auto-upgrades\n",
              "/etc/init.d/unattended-upgrades restart\n"
            ]]
          }
        }
      },
      "Metadata": {
        "AWS::CloudFormation::Authentication": {
          "S3AccessCreds": {
            "type": "S3",
            "buckets": [{
              "Ref": "DeploymentBucket"
            }],
            "roleName": {
              "Ref": "IAMRole"
            }
          }
        },
        "AWS::CloudFormation::Init": {
          "configSets": {
            "firstpass": ["config1"],
            "secondpass": ["config2"],
            "post-install-script": ["post-install-config"]
          },
          "post-install-config": {
            "sources": {
              "/arcgis/postinstallscripts": {
                "Fn::If": ["RunPostInstall", {
                  "Fn::GetAtt": ["ValidatePostInstallationScript", "S3ObjectURL"]
                }, ""]
              }
            }
          },
          "config1": {
            "sources": {
              "/usr/local/lib/python3.6/dist-packages/cfnbootstrap/resources/documents": "https://arcgisstore1061.s3.amazonaws.com/endpoints.tar.gz"
            }
          },
          "config2": {
            "commands": {
              "rename-server-license": {
                "command": {
                  "Fn::Join": ["", [
                    "mkdir -p \"/tmp/", {
                      "Ref": "ServerLicenseFile"
                    },
                    "\"; rmdir \"/tmp/", {
                      "Ref": "ServerLicenseFile"
                    },
                    "\"; mv /tmp/server_license.tmp \"/tmp/", {
                      "Ref": "ServerLicenseFile"
                    }, "\""
                  ]]
                }
              },
              "rename-portal-license": {
                "command": {
                  "Fn::Join": ["", [
                    "mkdir -p \"/tmp/", {
                      "Ref": "PortalLicenseFile"
                    },
                    "\"; rmdir \"/tmp/", {
                      "Ref": "PortalLicenseFile"
                    },
                    "\"; mv /tmp/portal_license.tmp \"/tmp/", {
                      "Ref": "PortalLicenseFile"
                    }, "\""
                  ]]
                }
              }
            },
            "files": {
              "/tmp/cwlogs/cwlogs.conf": {
                "content": {
                  "Fn::Join": ["", [
                    "[general]\n",
                    "state_file= /var/awslogs/agent-state\n",
                    "[/var/log/cfn-init.log]\n",
                    "file = /var/log/cfn-init.log\n",
                    "log_group_name = ", {
                      "Ref": "DeploymentLogs"
                    }, "\n",
                    "log_stream_name = {instance_id}/cfn-init.log\n",
                    "datetime_format = %d/%b/%Y:%H:%M:%S\n",
                    "[/var/log/chef-run.log]\n",
                    "file = /var/log/chef-run.log\n",
                    "log_group_name = ", {
                      "Ref": "DeploymentLogs"
                    }, "\n",
                    "log_stream_name = {instance_id}/chef-run.log\n",
                    "datetime_format = %Y-%m-%dT%H:%M:%S%z\n",
                    "[/var/lib/tomcat7/logs/catalina.out]\n",
                    "file = /var/lib/tomcat7/logs/catalina.out\n",
                    "log_group_name = ", {
                      "Ref": "DeploymentLogs"
                    }, "\n",
                    "log_stream_name = {instance_id}/catalina.out\n",
                    "datetime_format = %d/%b/%Y:%H:%M:%S"
                  ]]
                },
                "mode": "000755"
              },
              "/etc/tomcat7/pkcs12_cert.pfx": {
                "source": {
                  "Fn::GetAtt": ["ValidateSSLCertificateFile", "S3ObjectURL"]
                },
                "authentication": "S3AccessCreds",
                "mode": "000755"
              },
              "/tmp/server_license.tmp": {
                "source": {
                  "Fn::GetAtt": ["ValidateServerLicenseFile", "S3ObjectURL"]
                },
                "authentication": "S3AccessCreds",
                "mode": "000755"
              },
              "/tmp/portal_license.tmp": {
                "source": {
                  "Fn::GetAtt": ["ValidatePortalLicenseFile", "S3ObjectURL"]
                },
                "authentication": "S3AccessCreds",
                "mode": "000755"
              },
              "/etc/chef/node.json": {
                "content": {
                  "Fn::Join": ["", [
                    "{\n",
                    "  \"tomcat\" : {\n",
                    "    \"keystore_file\" : \"/etc/tomcat7/pkcs12_cert.pfx\",\n",
                    "    \"keystore_type\" : \"pkcs12\",\n",
                    "    \"keystore_password\" : \"", {
                      "Ref": "SSLCertPassword"
                    }, "\"\n",
                    "  },\n",
                    "  \"arcgis\" : {\n",
                    "    \"version\": \"10.8.1\",\n",
                    "    \"post_install_script\" : \"/arcgis/postinstallscripts/deploy.sh\",\n",
                    "    \"hosts\" : {\n",
                    "      \"", {
                      "Ref": "SiteDomain"
                    }, "\" : \"\",\n",
                    "      \"FILESERVER\" : \"", {
                      "Fn::GetAtt": ["FileServerEC2Instance", "PrivateIp"]
                    }, "\"\n",
                    "    },\n",
                    "    \"web_server\":{\n",
                    "      \"webapp_dir\":\"/opt/tomcat_arcgis/webapps\"\n",
                    "    },\n",
                    "    \"server\" : {\n",
                    "      \"domain_name\" : \"", {
                      "Ref": "SiteDomain"
                    }, "\",\n",
                    "      \"wa_url\" : \"https://", {
                      "Ref": "SiteDomain"
                    }, "/server\",\n",
                    "      \"private_url\" : \"https://", {
                      "Ref": "SiteDomain"
                    }, "/server\",\n",
                    "      \"admin_username\" : \"", {
                      "Ref": "SiteAdmin"
                    }, "\",\n",
                    "      \"admin_password\" : \"", {
                      "Ref": "SiteAdminPassword"
                    }, "\",\n",
                    "      \"authorization_file\" : \"/tmp/", {
                      "Ref": "ServerLicenseFile"
                    }, "\",\n",
                    "      \"directories_root\" : \"/net/FILESERVER/gisdata/arcgisserver\",\n",
                    "      \"config_store_type\" : \"", {
                      "Fn::If": ["UseCloudStore", "AMAZON", "FILESYSTEM"]
                    }, "\",\n",
                    "      \"config_store_connection_string\" : \"", {
                      "Fn::If": ["UseCloudStore",
                        {
                          "Fn::Join": ["", ["NAMESPACE=", {
                            "Ref": "AWS::StackName"
                          }, ";REGION=", {
                            "Ref": "AWS::Region"
                          }]]
                        },
                        "/net/FILESERVER/gisdata/arcgisserver/config-store"
                      ]
                    }, "\",\n",
                    "      \"install_system_requirements\" : false\n",
                    "    },\n",
                    "    \"data_store\" : {\n",
                    "      \"preferredidentifier\" : \"ip\",\n",
                    "      \"backup_dir\" : \"/net/FILESERVER/gisdata/arcgisdatastore/backup\",\n",
                    "      \"install_system_requirements\" : false\n",
                    "    },\n",
                    "    \"portal\" : {\n",
                    "      \"domain_name\" : \"", {
                      "Ref": "SiteDomain"
                    }, "\",\n",
                    "      \"private_url\" : \"https://", {
                      "Ref": "SiteDomain"
                    }, "/portal\",\n",
                    "      \"web_context_url\" : \"https://", {
                      "Ref": "SiteDomain"
                    }, "/portal\",\n",
                    "      \"admin_username\" : \"", {
                      "Ref": "SiteAdmin"
                    }, "\",\n",
                    "      \"admin_password\" : \"", {
                      "Ref": "SiteAdminPassword"
                    }, "\",\n",
                    "      \"content_store_type\" : \"", {
                      "Fn::If": ["UseCloudStore", "cloudStore", "fileStore"]
                    }, "\",\n",
                    "      \"content_store_provider\" : \"", {
                      "Fn::If": ["UseCloudStore", "Amazon", "FileSystem"]
                    }, "\",\n",
                    "      \"content_store_connection_string\" : ", {
                      "Fn::If": ["UseCloudStore",
                        {
                          "Fn::Join": ["", ["{\"region\": \"", {
                            "Ref": "AWS::Region"
                          }, "\", \"credentialType\": \"IAMRole\"}"]]
                        },
                        "\"/net/FILESERVER/gisdata/arcgisportal/content\""
                      ]
                    }, ",\n",
                    "      \"object_store\" : \"", {
                      "Fn::If": ["UseCloudStore", {
                        "Ref": "PortalContent"
                      }, ""]
                    }, "\",\n",
                    "      \"authorization_file\" : \"/tmp/", {
                      "Ref": "PortalLicenseFile"
                    }, "\",\n",
                    "      \"user_license_type_id\" : \"", {
                      "Ref": "UserLicenseTypeID"
                    }, "\",\n",
                    "      \"install_system_requirements\" : false\n",
                    "    },\n",
                    "    \"web_adaptor\" : {\n",
                    "      \"admin_access\" : true,\n",
                    "      \"reindex_portal_content\" : false\n",
                    "    }\n",
                    "  },\n",
                    "  \"run_list\" : [\n",
                    "    \"recipe[apt]\",\n",
                    "    \"recipe[arcgis-enterprise::system]\",\n",
                    "    \"recipe[esri-tomcat]\",\n",
                    "    \"recipe[iptables]\",\n",
                    "    \"recipe[arcgis-enterprise::iptables]\",\n",
                    "    \"recipe[arcgis-enterprise::portal]\",\n",
                    "    \"recipe[arcgis-enterprise::portal_wa]\",\n",
                    "    \"recipe[arcgis-enterprise::server]\",\n",
                    "    \"recipe[arcgis-enterprise::server_wa]\",\n",
                    "    \"recipe[arcgis-enterprise::datastore]\",\n",
                    "    \"recipe[arcgis-enterprise::post_install]\"]\n",
                    "}\n"
                  ]]
                },
                "mode": "000755"
              }
            }
          }
        }
      }
    },
    "PrimaryServerRecoveryAlarm": {
      "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": "PrimaryServerEC2Instance"
          }
        }]
      }
    },
    "PrimaryServerWaitHandle": {
      "Type": "AWS::CloudFormation::WaitConditionHandle",
      "Properties": {}
    },
    "PrimaryServerWaitCondition": {
      "Type": "AWS::CloudFormation::WaitCondition",
      "Properties": {
        "Count": "1",
        "Handle": {
          "Ref": "PrimaryServerWaitHandle"
        },
        "Timeout": "14400"
      }
    },
    "SecondaryServerEC2Instance": {
      "Type": "AWS::EC2::Instance",
      "DependsOn": "PrimaryServerWaitCondition",
      "Properties": {
        "Monitoring": true,
        "LaunchTemplate": {
          "LaunchTemplateId": {
            "Ref": "EC2InstanceLaunchTemplate"
          },
          "Version": {
            "Fn::GetAtt": [
              "EC2InstanceLaunchTemplate",
              "LatestVersionNumber"
            ]
          }
        },
        "Tags": [{
          "Key": "Name",
          "Value": {
            "Fn::Join": ["", [{
              "Ref": "AWS::StackName"
            }, "-secondary"]]
          }
        }],
        "NetworkInterfaces": [{
          "GroupSet": [{
            "Ref": "SecurityGroup"
          }],
          "AssociatePublicIpAddress": "true",
          "DeviceIndex": "0",
          "DeleteOnTermination": "true",
          "SubnetId": {
            "Ref": "Subnet2"
          }
        }],
        "UserData": {
          "Fn::Base64": {
            "Fn::Join": ["", [
              "#!/bin/bash -v\n",
              "for i in {1..60}; do ping -c1 $(hostname); if [ $? -eq 0 ]; then break; fi; sleep 10; done\n",
              "ping -c1 $(hostname)\n",
              "exitcode=$?\n",
              "if [ $exitcode -ne 0 ]; then\n",
              "  cfn-signal -e $exitcode -r 'Failed to resolve the host name. Check the VPC settings.' '", {
                "Ref": "SecondaryServerWaitHandle"
              }, "'\n",
              "  exit $exitcode\n",
              "fi\n",
              "echo 'disable unattended upgrades'\n",
              "cp /etc/apt/apt.conf.d/20auto-upgrades /etc/apt/apt.conf.d/20auto-upgrades.original\n",
              "echo -e \"APT::Periodic::Update-Package-Lists \\\"0\\\";\\nAPT::Periodic::Unattended-Upgrade \\\"0\\\";\" > /etc/apt/apt.conf.d/20auto-upgrades\n",
              "/etc/init.d/unattended-upgrades restart\n",
              "lockdetails=$(sudo lsof /var/lib/dpkg/lock)\n",
              "while [ ! -z \"$lockdetails\" ]; do\n",
              "  echo 'Waiting for lock to release'\n",
              "  sleep 1m\n",
              "  lockdetails=$(sudo lsof /var/lib/dpkg/lock)\n",
              "done\n",
              "if ", {
                "Fn::If": ["RunPostInstall", "true", "false"]
              }, "; then\n",
              "  cfn-init -v -c post-install-script -s ", {
                "Ref": "AWS::StackName"
              }, " -r SecondaryServerEC2Instance", " --region ", {
                "Ref": "AWS::Region"
              }, "\n",
              "fi\n",
              "cfn-init -v -c firstpass -s ", {
                "Ref": "AWS::StackName"
              }, " -r SecondaryServerEC2Instance", " --region ", {
                "Ref": "AWS::Region"
              }, "\n",
              "cfn-init -v -c secondpass -s ", {
                "Ref": "AWS::StackName"
              }, " -r SecondaryServerEC2Instance", " --region ", {
                "Ref": "AWS::Region"
              }, "\n",
              "exitcode=$?\n",
              "wget https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py\n",
              "sudo python3 awslogs-agent-setup.py -n -r ", {
                "Ref": "AWS::Region"
              },
              " -c /tmp/cwlogs/cwlogs.conf || error_exit 'Failed to run CloudWatch Logs agent setup'\n",
              "if [ $exitcode -ne 0 ]; then\n",
              "  cfn-signal -e $exitcode -r 'cfn-init failed. See /var/log/cfn-init.log for details.' '",
              {
                "Ref": "SecondaryServerWaitHandle"
              }, "'\n",
              "  exit $exitcode\n",
              "fi\n",
              "chmod 777 /mnt\n",
              "export arcgis_cloud_platform=aws\n",
              "chef-solo -j /etc/chef/node.json -r https://arcgisstore1081.s3.amazonaws.com/14362/cookbooks/arcgis-3.6.0-cookbooks.tar.gz -L /var/log/chef-run.log -l info\n",
              "exitcode=$?\n",
              "if [ $exitcode -ne 0 ]; then\n",
              "  cfn-signal -e $exitcode -r 'Chef run failed. See /var/log/chef-run.log for details.' '", {
                "Ref": "SecondaryServerWaitHandle"
              }, "'\n",
              "  exit $exitcode\n",
              "fi\n",
              "cfn-signal -e 0 -r 'Setup complete' '", {
                "Ref": "SecondaryServerWaitHandle"
              }, "'\n",
              "echo 'enable unattended upgrades'\n",
              "mv /etc/apt/apt.conf.d/20auto-upgrades.original /etc/apt/apt.conf.d/20auto-upgrades\n",
              "/etc/init.d/unattended-upgrades restart\n"
            ]]
          }
        }
      },
      "Metadata": {
        "AWS::CloudFormation::Authentication": {
          "S3AccessCreds": {
            "type": "S3",
            "buckets": [{
              "Ref": "DeploymentBucket"
            }],
            "roleName": {
              "Ref": "IAMRole"
            }
          }
        },
        "AWS::CloudFormation::Init": {
          "configSets": {
            "firstpass": ["config1"],
            "secondpass": ["config2"],
            "post-install-script": ["post-install-config"]
          },
          "post-install-config": {
            "sources": {
              "/arcgis/postinstallscripts": {
                "Fn::If": ["RunPostInstall", {
                  "Fn::GetAtt": ["ValidatePostInstallationScript", "S3ObjectURL"]
                }, ""]
              }
            }
          },
          "config1": {
            "sources": {
              "/usr/local/lib/python3.6/dist-packages/cfnbootstrap/resources/documents": "https://arcgisstore1061.s3.amazonaws.com/endpoints.tar.gz"
            }
          },
          "config2": {
            "commands": {
              "rename-server-license": {
                "command": {
                  "Fn::Join": ["", [
                    "mkdir -p \"/tmp/", {
                      "Ref": "ServerLicenseFile"
                    },
                    "\"; rmdir \"/tmp/", {
                      "Ref": "ServerLicenseFile"
                    },
                    "\"; mv /tmp/server_license.tmp \"/tmp/", {
                      "Ref": "ServerLicenseFile"
                    }, "\""
                  ]]
                }
              },
              "rename-portal-license": {
                "command": {
                  "Fn::Join": ["", [
                    "mkdir -p \"/tmp/", {
                      "Ref": "PortalLicenseFile"
                    },
                    "\"; rmdir \"/tmp/", {
                      "Ref": "PortalLicenseFile"
                    },
                    "\"; mv /tmp/portal_license.tmp \"/tmp/", {
                      "Ref": "PortalLicenseFile"
                    }, "\""
                  ]]
                }
              }
            },
            "files": {
              "/tmp/cwlogs/cwlogs.conf": {
                "content": {
                  "Fn::Join": ["", [
                    "[general]\n",
                    "state_file= /var/awslogs/agent-state\n",
                    "[/var/log/cfn-init.log]\n",
                    "file = /var/log/cfn-init.log\n",
                    "log_group_name = ", {
                      "Ref": "DeploymentLogs"
                    }, "\n",
                    "log_stream_name = {instance_id}/cfn-init.log\n",
                    "datetime_format = %d/%b/%Y:%H:%M:%S\n",
                    "[/var/log/chef-run.log]\n",
                    "file = /var/log/chef-run.log\n",
                    "log_group_name = ", {
                      "Ref": "DeploymentLogs"
                    }, "\n",
                    "log_stream_name = {instance_id}/chef-run.log\n",
                    "datetime_format = %Y-%m-%dT%H:%M:%S%z\n",
                    "[/var/lib/tomcat7/logs/catalina.out]\n",
                    "file = /var/lib/tomcat7/logs/catalina.out\n",
                    "log_group_name = ", {
                      "Ref": "DeploymentLogs"
                    }, "\n",
                    "log_stream_name = {instance_id}/catalina.out\n",
                    "datetime_format = %d/%b/%Y:%H:%M:%S"
                  ]]
                },
                "mode": "000755"
              },
              "/etc/tomcat7/pkcs12_cert.pfx": {
                "source": {
                  "Fn::GetAtt": ["ValidateSSLCertificateFile", "S3ObjectURL"]
                },
                "authentication": "S3AccessCreds",
                "mode": "000755"
              },
              "/tmp/server_license.tmp": {
                "source": {
                  "Fn::GetAtt": ["ValidateServerLicenseFile", "S3ObjectURL"]
                },
                "authentication": "S3AccessCreds",
                "mode": "000755"
              },
              "/tmp/portal_license.tmp": {
                "source": {
                  "Fn::GetAtt": ["ValidatePortalLicenseFile", "S3ObjectURL"]
                },
                "authentication": "S3AccessCreds",
                "mode": "000755"
              },
              "/etc/chef/node.json": {
                "content": {
                  "Fn::Join": ["", [
                    "{\n",
                    "  \"tomcat\" : {\n",
                    "    \"keystore_file\" : \"/etc/tomcat7/pkcs12_cert.pfx\",\n",
                    "    \"keystore_type\" : \"pkcs12\",\n",
                    "    \"keystore_password\" : \"", {
                      "Ref": "SSLCertPassword"
                    }, "\"\n",
                    "  },\n",
                    "  \"arcgis\" : {\n",
                    "    \"version\": \"10.8.1\",\n",
                    "    \"post_install_script\" : \"/arcgis/postinstallscripts/deploy.sh\",\n",
                    "    \"hosts\" : {\n",
                    "      \"", {
                      "Ref": "SiteDomain"
                    }, "\" : \"\",\n",
                    "      \"FILESERVER\" : \"", {
                      "Fn::GetAtt": ["FileServerEC2Instance", "PrivateIp"]
                    }, "\"\n",
                    "    },\n",
                    "    \"web_server\":{\n",
                    "      \"webapp_dir\":\"/opt/tomcat_arcgis/webapps\"\n",
                    "    },\n",
                    "    \"server\" : {\n",
                    "      \"domain_name\" : \"", {
                      "Ref": "SiteDomain"
                    }, "\",\n",
                    "      \"admin_username\" : \"", {
                      "Ref": "SiteAdmin"
                    }, "\",\n",
                    "      \"admin_password\" : \"", {
                      "Ref": "SiteAdminPassword"
                    }, "\",\n",
                    "      \"private_url\" : \"https://", {
                      "Ref": "SiteDomain"
                    }, "/server\",\n",
                    "      \"primary_server_url\" : \"https://", {
                      "Fn::GetAtt": ["PrimaryServerEC2Instance", "PrivateIp"]
                    }, ":6443/arcgis\",\n",
                    "      \"use_join_site_tool\" : false,\n",
                    "      \"config_store_type\" : \"", {
                      "Fn::If": ["UseCloudStore", "AMAZON", "FILESYSTEM"]
                    }, "\",\n",
                    "      \"config_store_connection_string\" : \"", {
                      "Fn::If": ["UseCloudStore",
                        {
                          "Fn::Join": ["", ["NAMESPACE=", {
                            "Ref": "AWS::StackName"
                          }, ";REGION=", {
                            "Ref": "AWS::Region"
                          }]]
                        },
                        "/net/FILESERVER/gisdata/arcgisserver/config-store"
                      ]
                    }, "\",\n",
                    "      \"authorization_file\" : \"/tmp/", {
                      "Ref": "ServerLicenseFile"
                    }, "\",\n",
                    "      \"install_system_requirements\" : false\n",
                    "    },\n",
                    "    \"data_store\" : {\n",
                    "      \"preferredidentifier\" : \"ip\",\n",
                    "      \"backup_dir\" : \"/net/FILESERVER/gisdata/arcgisdatastore/backup\",\n",
                    "      \"install_system_requirements\" : false\n",
                    "    },\n",
                    "    \"portal\" : {\n",
                    "      \"domain_name\" : \"", {
                      "Ref": "SiteDomain"
                    }, "\",\n",
                    "      \"primary_machine_url\" : \"https://", {
                      "Fn::GetAtt": ["PrimaryServerEC2Instance", "PrivateIp"]
                    }, ":7443\",\n",
                    "      \"private_url\" : \"https://", {
                      "Ref": "SiteDomain"
                    }, "/portal\",\n",
                    "      \"admin_username\" : \"", {
                      "Ref": "SiteAdmin"
                    }, "\",\n",
                    "      \"admin_password\" : \"", {
                      "Ref": "SiteAdminPassword"
                    }, "\",\n",
                    "      \"authorization_file\" : \"/tmp/", {
                      "Ref": "PortalLicenseFile"
                    }, "\",\n",
                    "      \"user_license_type_id\" : \"", {
                      "Ref": "UserLicenseTypeID"
                    }, "\",\n",
                    "      \"install_system_requirements\" : false\n",
                    "    },\n",
                    "    \"web_adaptor\" : {\n",
                    "      \"admin_access\" : true,\n",
                    "      \"reindex_portal_content\" : false\n",
                    "    }\n",
                    "  },\n",
                    "  \"run_list\" : [\n",
                    "    \"recipe[apt]\",\n",
                    "    \"recipe[arcgis-enterprise::system]\",\n",
                    "    \"recipe[esri-tomcat]\",\n",
                    "    \"recipe[iptables]\",\n",
                    "    \"recipe[arcgis-enterprise::iptables]\",\n",
                    "    \"recipe[arcgis-enterprise::portal_standby]\",\n",
                    "    \"recipe[arcgis-enterprise::portal_wa]\",\n",
                    "    \"recipe[arcgis-enterprise::server_node]\",\n",
                    "    \"recipe[arcgis-enterprise::server_wa]\",\n",
                    "    \"recipe[arcgis-enterprise::datastore_standby]\",\n",
                    "    \"recipe[arcgis-enterprise::federation]\",\n",
                    "    \"recipe[arcgis-enterprise::post_install]\"]\n",
                    "}\n"
                  ]]
                },
                "mode": "000755"
              }
            }
          }
        }
      }
    },
    "SecondaryServerRecoveryAlarm": {
      "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": "SecondaryServerEC2Instance"
          }
        }]
      }
    },
    "SecondaryServerWaitHandle": {
      "Type": "AWS::CloudFormation::WaitConditionHandle",
      "Properties": {}
    },
    "SecondaryServerWaitCondition": {
      "Type": "AWS::CloudFormation::WaitCondition",
      "DependsOn": "PrimaryServerWaitCondition",
      "Properties": {
        "Count": "1",
        "Handle": {
          "Ref": "SecondaryServerWaitHandle"
        },
        "Timeout": "14400"
      }
    },
    "AutoScalingInstanceLaunchTemplate": {
      "Type": "AWS::EC2::LaunchTemplate",
      "DependsOn": "SecondaryServerWaitCondition",
      "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": "BDSInstanceType"
          },
          "KeyName": {
            "Ref": "KeyName"
          },
          "NetworkInterfaces": [{
            "AssociatePublicIpAddress": true,
            "DeleteOnTermination": true,
            "DeviceIndex": "0",
            "Groups": [{
              "Ref": "SecurityGroup"
            }],
            "SubnetId": {
              "Ref": "Subnet1"
            }
          }],
          "UserData": {
            "Fn::Base64": {
              "Fn::Join": ["", [
                "#!/bin/bash -v\n",
                "for i in {1..60}; do ping -c1 $(hostname); if [ $? -eq 0 ]; then break; fi; sleep 10; done\n",
                "ping -c1 $(hostname)\n",
                "exitcode=$?\n",
                "if [ $exitcode -ne 0 ]; then\n",
                "  cfn-signal -e $exitcode -r 'Failed to resolve the host name. Check the VPC settings.' '", {
                  "Ref": "AutoScalingGroupWaitHandle"
                }, "'\n",
                "  exit $exitcode\n",
                "fi\n",
                "if ", {
                  "Fn::If": ["RunPostInstall", "true", "false"]
                }, "; then\n",
                "  cfn-init -v -c post-install-script -s ", {
                  "Ref": "AWS::StackName"
                }, " -r AutoScalingInstanceLaunchTemplate", " --region ", {
                  "Ref": "AWS::Region"
                }, "\n",
                "fi\n",
                "cfn-init -v -c firstpass -s ", {
                  "Ref": "AWS::StackName"
                }, " -r AutoScalingInstanceLaunchTemplate", " --region ", {
                  "Ref": "AWS::Region"
                }, "\n",
                "cfn-init -v -c secondpass -s ", {
                  "Ref": "AWS::StackName"
                }, " -r AutoScalingInstanceLaunchTemplate", " --region ", {
                  "Ref": "AWS::Region"
                }, "\n",
                "exitcode=$?\n",
                "wget https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py\n",
                "pgrep unattended-upgr\n",
                "sudo python3 awslogs-agent-setup.py -n -r ", {
                  "Ref": "AWS::Region"
                },
                " -c /tmp/cwlogs/cwlogs.conf || error_exit 'Failed to run CloudWatch Logs agent setup'\n",
                "if [ $exitcode -ne 0 ]; then\n",
                "  cfn-signal -e $exitcode -r 'cfn-init failed. See /var/log/cfn-init.log for details.' '",
                {
                  "Ref": "AutoScalingGroupWaitHandle"
                }, "'\n",
                "  exit $exitcode\n",
                "fi\n",
                "chmod 777 /mnt\n",
                "export arcgis_cloud_platform=aws\n",
                "chef-solo -j /etc/chef/node.json -r https://arcgisstore1081.s3.amazonaws.com/14362/cookbooks/arcgis-3.6.0-cookbooks.tar.gz -L /var/log/chef-run.log -l info\n",
                "exitcode=$?\n",
                "if [ $exitcode -ne 0 ]; then\n",
                "  cfn-signal -e $exitcode -r 'Chef run failed. See /var/log/chef-run.log for details.' '", {
                  "Ref": "AutoScalingGroupWaitHandle"
                }, "'\n",
                "  exit $exitcode\n",
                "fi\n",
                "cfn-signal -e 0 -r 'Setup complete' '", {
                  "Ref": "AutoScalingGroupWaitHandle"
                }, "'\n"
              ]]
            }
          }
        }
      },
      "Metadata": {
        "AWS::CloudFormation::Authentication": {
          "S3AccessCreds": {
            "type": "S3",
            "buckets": [{
              "Ref": "DeploymentBucket"
            }],
            "roleName": {
              "Ref": "IAMRole"
            }
          }
        },
        "AWS::CloudFormation::Init": {
          "configSets": {
            "firstpass": ["config1"],
            "secondpass": ["config2"],
            "post-install-script": ["post-install-config"]
          },
          "post-install-config": {
            "sources": {
              "/arcgis/postinstallscripts": {
                "Fn::If": ["RunPostInstall", {
                  "Fn::GetAtt": ["ValidatePostInstallationScript", "S3ObjectURL"]
                }, ""]
              }
            }
          },
          "config1": {
            "sources": {
              "/usr/local/lib/python3.6/dist-packages/cfnbootstrap/resources/documents": "https://arcgisstore1061.s3.amazonaws.com/endpoints.tar.gz"
            }
          },
          "config2": {
            "files": {
              "/tmp/cwlogs/cwlogs.conf": {
                "content": {
                  "Fn::Join": ["", [
                    "[general]\n",
                    "state_file= /var/awslogs/agent-state\n",
                    "[/var/log/cfn-init.log]\n",
                    "file = /var/log/cfn-init.log\n",
                    "log_group_name = ", {
                      "Ref": "DeploymentLogs"
                    }, "\n",
                    "log_stream_name = {instance_id}/cfn-init.log\n",
                    "datetime_format = %d/%b/%Y:%H:%M:%S\n",
                    "[/var/log/chef-run.log]\n",
                    "file = /var/log/chef-run.log\n",
                    "log_group_name = ", {
                      "Ref": "DeploymentLogs"
                    }, "\n",
                    "log_stream_name = {instance_id}/chef-run.log\n",
                    "datetime_format = %Y-%m-%dT%H:%M:%S%z\n",
                    "[/var/lib/tomcat7/logs/catalina.out]\n",
                    "file = /var/lib/tomcat7/logs/catalina.out\n",
                    "log_group_name = ", {
                      "Ref": "DeploymentLogs"
                    }, "\n",
                    "log_stream_name = {instance_id}/catalina.out\n",
                    "datetime_format = %d/%b/%Y:%H:%M:%S"
                  ]]
                },
                "mode": "000755"
              },
              "/etc/chef/node.json": {
                "content": {
                  "Fn::Join": ["", [
                    "{\n",
                    "  \"arcgis\" : {\n",
                    "    \"version\": \"10.8.1\",\n",
                    "    \"post_install_script\" : \"/arcgis/postinstallscripts/deploy.sh\",\n",
                    "    \"hosts\" : {\n",
                    "      \"FILESERVER\" : \"", {
                      "Fn::GetAtt": ["FileServerEC2Instance", "PrivateIp"]
                    }, "\"\n",
                    "    },\n",
                    "    \"server\" : {\n",
                    "      \"admin_username\" : \"", {
                      "Ref": "SiteAdmin"
                    }, "\",\n",
                    "      \"admin_password\" : \"", {
                      "Ref": "SiteAdminPassword"
                    }, "\",\n",
                    "      \"domain_name\" : \"", {
                      "Fn::GetAtt": ["PrimaryServerEC2Instance", "PrivateIp"]
                    }, "\",\n",
                    "      \"private_url\" : \"https://", {
                      "Fn::GetAtt": ["PrimaryServerEC2Instance", "PrivateIp"]
                    }, ":6443/arcgis\"\n",
                    "    },\n",
                    "    \"data_store\" : {\n",
                    "      \"types\" : \"spatiotemporal\",\n",
                    "      \"preferredidentifier\" : \"ip\",\n",
                    "      \"backup_dir\" : \"/net/FILESERVER/gisdata/arcgisdatastore/backup\"\n",
                    "    }\n",
                    "  },\n",
                    "  \"run_list\" : [\n",
                    "    \"recipe[apt]\",\n",
                    "    \"recipe[arcgis-enterprise::system]\",\n",
                    "    \"recipe[arcgis-enterprise::datastore]\",\n",
                    "    \"recipe[arcgis-enterprise::post_install]\"]\n",
                    "}\n"
                  ]]
                },
                "mode": "000755"
              }
            }
          }
        }
      }
    },
    "AutoScalingGroup": {
      "Type": "AWS::AutoScaling::AutoScalingGroup",
      "Properties": {
        "VPCZoneIdentifier": [{
          "Ref": "Subnet1"
        }, {
          "Ref": "Subnet2"
        }],
        "Cooldown": "300",
        "MaxSize": {
          "Ref": "BDSInstances"
        },
        "MinSize": {
          "Ref": "BDSInstances"
        },
        "LaunchTemplate": {
          "LaunchTemplateId": {
            "Ref": "AutoScalingInstanceLaunchTemplate"
          },
          "Version": {
            "Fn::GetAtt": [
              "AutoScalingInstanceLaunchTemplate",
              "LatestVersionNumber"
            ]
          }
        },
        "HealthCheckType": "EC2",
        "HealthCheckGracePeriod": "3600",
        "Tags": [{
          "Key": "Name",
          "Value": {
            "Fn::Join": ["", [{
              "Ref": "AWS::StackName"
            }, "-bds"]]
          },
          "PropagateAtLaunch": true
        }]
      },
      "UpdatePolicy": {
        "AutoScalingReplacingUpdate": {
          "WillReplace": "true"
        }
      }
    },
    "AutoScalingGroupWaitHandle": {
      "Type": "AWS::CloudFormation::WaitConditionHandle",
      "Properties": {}
    },
    "AutoScalingGroupWaitCondition": {
      "Type": "AWS::CloudFormation::WaitCondition",
      "DependsOn": "AutoScalingInstanceLaunchTemplate",
      "Properties": {
        "Count": {
          "Ref": "BDSInstances"
        },
        "Handle": {
          "Ref": "AutoScalingGroupWaitHandle"
        },
        "Timeout": "14400"
      }
    },
    "CloudWatchSettings": {
      "Type": "AWS::Logs::MetricFilter",
      "Properties": {
        "LogGroupName": {
          "Ref": "DeploymentLogs"
        },
        "FilterPattern": "[level=FATAL, message]",
        "MetricTransformations": [{
          "MetricValue": "1",
          "MetricNamespace": "ArcGIS/Deployment",
          "MetricName": "ErrorCount"
        }]
      }
    }
  },
  "Outputs": {
    "ManagerURL": {
      "Value": {
        "Fn::Join": ["", ["https://", {
          "Ref": "SiteDomain"
        }, "/server/manager"]]
      },
      "Description": "ArcGIS Server Manager URL"
    },
    "RestURL": {
      "Value": {
        "Fn::Join": ["", ["https://", {
          "Ref": "SiteDomain"
        }, "/server/rest"]]
      },
      "Description": "ArcGIS REST Services Directory URL"
    },
    "PortalURL": {
      "Value": {
        "Fn::Join": ["", ["https://", {
          "Ref": "SiteDomain"
        }, "/portal/home"]]
      },
      "Description": "Portal for ArcGIS Home 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"
    }
  }
}
