{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Description":"Bring up the complete EdX stack in a VPC.",
  "Parameters":{
    "EnvironmentTag":{
      "Type":"String",
      "Description":"A tag value applied to the hosts in the VPC indicating which environment to use during the configuration phase, e.g., stage, prod, sandbox",
      "Default":"sandbox"
    },
    "DeploymentTag":{
      "Type":"String",
      "Description":"A tag value applied to the hosts in the VPC indicating which deployment this is, e.g., edx, edge, <university>, <org>"
    },
    "KeyName":{
      "Type":"String",
      "Description":"Name of an existing EC2 KeyPair to enable SSH access to the web server",
      "Default":"deployment"
    },
    "EdxappInstanceType":{
      "Description":"WebServer EC2 instance type",
      "Type":"String",
      "Default":"m1.small",
      "AllowedValues":[
        "t1.micro",
        "m1.small",
        "m1.medium",
        "m1.large",
        "m1.xlarge",
        "m2.xlarge",
        "m2.2xlarge",
        "m2.4xlarge",
        "m3.xlarge",
        "m3.2xlarge",
        "c1.medium",
        "c1.xlarge",
        "cc1.4xlarge",
        "cc2.8xlarge",
        "cg1.4xlarge"
      ],
      "ConstraintDescription":"must be a valid EC2 instance type."
    },
    "WorkerInstanceType":{
      "Description":"Worker EC2 instance type",
      "Type":"String",
      "Default":"m1.small",
      "AllowedValues":[
        "t1.micro",
        "m1.small",
        "m1.medium",
        "m1.large",
        "m1.xlarge",
        "m2.xlarge",
        "m2.2xlarge",
        "m2.4xlarge",
        "m3.xlarge",
        "m3.2xlarge",
        "c1.medium",
        "c1.xlarge",
        "cc1.4xlarge",
        "cc2.8xlarge",
        "cg1.4xlarge"
      ],
      "ConstraintDescription":"must be a valid EC2 instance type."
    },
    "ForumInstanceType":{
      "Description":"Forum EC2 instance type",
      "Type":"String",
      "Default":"m1.small",
      "AllowedValues":[
        "t1.micro",
        "m1.small",
        "m1.medium",
        "m1.large",
        "m1.xlarge",
        "m2.xlarge",
        "m2.2xlarge",
        "m2.4xlarge",
        "m3.xlarge",
        "m3.2xlarge",
        "c1.medium",
        "c1.xlarge",
        "cc1.4xlarge",
        "cc2.8xlarge",
        "cg1.4xlarge"
      ],
      "ConstraintDescription":"must be a valid EC2 instance type."
    },
    "NotifierInstanceType":{
      "Description":"Notifier EC2 instance type",
      "Type":"String",
      "Default":"m1.small",
      "AllowedValues":[
        "t1.micro",
        "m1.small",
        "m1.medium",
        "m1.large",
        "m1.xlarge",
        "m2.xlarge",
        "m2.2xlarge",
        "m2.4xlarge",
        "m3.xlarge",
        "m3.2xlarge",
        "c1.medium",
        "c1.xlarge",
        "cc1.4xlarge",
        "cc2.8xlarge",
        "cg1.4xlarge"
      ],
      "ConstraintDescription":"must be a valid EC2 instance type."
    },
    "MongoInstanceType":{
      "Description":"Worker EC2 instance type",
      "Type":"String",
      "Default":"m1.small",
      "AllowedValues":[
        "t1.micro",
        "m1.small",
        "m1.medium",
        "m1.large",
        "m1.xlarge",
        "m2.xlarge",
        "m2.2xlarge",
        "m2.4xlarge",
        "m3.xlarge",
        "m3.2xlarge",
        "c1.medium",
        "c1.xlarge",
        "cc1.4xlarge",
        "cc2.8xlarge",
        "cg1.4xlarge"
      ],
      "ConstraintDescription":"must be a valid EC2 instance type."
    },
    "CommonClusterInstanceType":{
      "Description":"The instance type on which common, clustered applications, e.g., RabbitMQ and Elasticsearch are hosted.",
      "Type":"String",
      "Default":"m1.small",
      "AllowedValues":[
        "t1.micro",
        "m1.small",
        "m1.medium",
        "m1.large",
        "m1.xlarge",
        "m2.xlarge",
        "m2.2xlarge",
        "m2.4xlarge",
        "m3.xlarge",
        "m3.2xlarge",
        "c1.medium",
        "c1.xlarge",
        "cc1.4xlarge",
        "cc2.8xlarge",
        "cg1.4xlarge"
      ],
      "ConstraintDescription":"must be a valid EC2 instance type."
    },
    "XserverInstanceType":{
      "Description":"Xserver server EC2 instance type",
      "Type":"String",
      "Default":"m1.small",
      "AllowedValues":[
        "t1.micro",
        "m1.small",
        "m1.medium",
        "m1.large",
        "m1.xlarge",
        "m2.xlarge",
        "m2.2xlarge",
        "m2.4xlarge",
        "m3.xlarge",
        "m3.2xlarge",
        "c1.medium",
        "c1.xlarge",
        "cc1.4xlarge",
        "cc2.8xlarge",
        "cg1.4xlarge"
      ],
      "ConstraintDescription":"must be a valid EC2 instance type."
    },
    "XqueueInstanceType":{
      "Description":"Xqueue server EC2 instance type",
      "Type":"String",
      "Default":"m1.small",
      "AllowedValues":[
        "t1.micro",
        "m1.small",
        "m1.medium",
        "m1.large",
        "m1.xlarge",
        "m2.xlarge",
        "m2.2xlarge",
        "m2.4xlarge",
        "m3.xlarge",
        "m3.2xlarge",
        "c1.medium",
        "c1.xlarge",
        "cc1.4xlarge",
        "cc2.8xlarge",
        "cg1.4xlarge"
      ],
      "ConstraintDescription":"must be a valid EC2 instance type."
    },
    "SSHLocation":{
      "Description":"The IP address range that can be used to SSH to the EC2 instances",
      "Type":"String",
      "MinLength":"9",
      "MaxLength":"18",
      "Default":"0.0.0.0/0",
      "AllowedPattern":"(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription":"must be a valid IP CIDR range of the form x.x.x.x/x."
    },
    "EdxappServerPort":{
      "Description":"The TCP port for the Edxapp Server",
      "Type":"Number",
      "Default":"18000"
    },
    "XqueueServerPort":{
      "Description":"The TCP port for the Xqueue server",
      "Type":"Number",
      "Default":"18040"
    },
    "XserverServerPort":{
      "Description":"The TCP port for the XServer",
      "Type":"Number",
      "Default":"18050"
    },
    "ForumServerPort":{
      "Description":"The TCP port for the Forum Server",
      "Type":"Number",
      "Default":"18080"
    },
    "CacheNodePort":{
      "Description":"The TCP port for the nodes in the Elasticache cluster",
      "Type":"Number",
      "Default":"11211"
    },
    "SSLCertificateARN":{
      "Description":"The ARN for an SSL certificate to use with the edxapp.",
      "Type":"String",
      "Default":"arn:aws:iam::372153017832:server-certificate/dummy"
    },
    "BastionInstanceType":{
      "Description":"Bastion Host EC2 instance type",
      "Type":"String",
      "Default":"m1.small",
      "AllowedValues":[
        "t1.micro",
        "m1.small",
        "m1.medium",
        "m1.large",
        "m1.xlarge",
        "m2.xlarge",
        "m2.2xlarge",
        "m2.4xlarge",
        "m3.xlarge",
        "m3.2xlarge",
        "c1.medium",
        "c1.xlarge",
        "cc1.4xlarge",
        "cc2.8xlarge",
        "cg1.4xlarge"
      ],
      "ConstraintDescription":"must be a valid EC2 instance type."
    },
    "NATInstanceType":{
      "Description":"NET Device EC2 instance type",
      "Type":"String",
      "Default":"m1.small",
      "AllowedValues":[
        "t1.micro",
        "m1.small",
        "m1.medium",
        "m1.large",
        "m1.xlarge",
        "m2.xlarge",
        "m2.2xlarge",
        "m2.4xlarge",
        "m3.xlarge",
        "m3.2xlarge",
        "c1.medium",
        "c1.xlarge",
        "cc1.4xlarge",
        "cc2.8xlarge",
        "cg1.4xlarge"
      ],
      "ConstraintDescription":"must be a valid EC2 instance type."
    },
    "EdxappDesiredCapacity":{
      "Description":"The Auto-scaling group desired capacity for the edxapp hosts",
      "Type":"Number",
      "Default":"2"
    },
    "XqueueDesiredCapacity":{
      "Description":"The Auto-scaling group desired capacity for the xqueue hosts",
      "Type":"Number",
      "Default":"2"
    },
    "XServerDesiredCapacity":{
      "Description":"The Auto-scaling group desired capacity for the xserver hosts",
      "Type":"Number",
      "Default":"2"
    },
    "CommonClusterDesiredCapacity":{
      "Description":"The Auto-scaling group desired capacity for the CommonCluster hosts",
      "Type":"Number",
      "Default":"3"
    },
    "WorkerDesiredCapacity":{
      "Description":"The Auto-scaling group desired capacity for the celery worker hosts",
      "Type":"Number",
      "Default":"2"
    },
    "ForumDesiredCapacity":{
      "Description":"The Auto-scaling group desired capacity for the forums hosts",
      "Type":"Number",
      "Default":"2"
    },
    "NotifierDesiredCapacity":{
      "Description":"The Auto-scaling group desired capacity for the notifier hosts",
      "Type":"Number",
      "Default":"1"
    },
    "MongoDesiredCapacity":{
      "Description":"The Auto-scaling group desired capacity for the mongodb hosts",
      "Type":"Number",
      "Default":"3"
    },
    "CacheNodeType":{
      "Default":"cache.m1.small",
      "Description":"The compute and memory capacity of the nodes in the Cache Cluster",
      "Type":"String",
      "AllowedValues":[
        "cache.t1.micro",
        "cache.m1.small",
        "cache.m1.large",
        "cache.m1.xlarge",
        "cache.m2.xlarge",
        "cache.m2.2xlarge",
        "cache.m2.4xlarge",
        "cache.c1.xlarge"
      ],
      "ConstraintDescription":"must select a valid Cache Node type."
    },
    "NumberOfCacheNodes":{
      "Default":"2",
      "Description":"The number of Cache Nodes the Cache Cluster should have",
      "Type":"Number",
      "MinValue":"1",
      "MaxValue":"10",
      "ConstraintDescription":"must be between 1 and 10."
    },
    "DBName":{
      "Default":"edxapp",
      "Description":"The database name",
      "Type":"String",
      "MinLength":"1",
      "MaxLength":"64",
      "AllowedPattern":"[a-zA-Z][a-zA-Z0-9]*",
      "ConstraintDescription":"must begin with a letter and contain only alphanumeric characters."
    },
    "DBUsername":{
      "Default":"root",
      "NoEcho":"true",
      "Description":"The database admin account username",
      "Type":"String",
      "MinLength":"1",
      "MaxLength":"16",
      "AllowedPattern":"[a-zA-Z][a-zA-Z0-9]*",
      "ConstraintDescription":"must begin with a letter and contain only alphanumeric characters."
    },
    "DBPassword":{
      "Default":"changeme",
      "NoEcho":"true",
      "Description":"The database admin account password",
      "Type":"String",
      "MinLength":"8",
      "MaxLength":"41",
      "ConstraintDescription":"must contain only alphanumeric characters."
    },
    "DBClass":{
      "Default":"db.m1.small",
      "Description":"Database instance class",
      "Type":"String",
      "AllowedValues":[
        "db.m1.micro",
        "db.m1.small",
        "db.m1.large",
        "db.m1.xlarge",
        "db.m2.xlarge",
        "db.m2.2xlarge",
        "db.m2.4xlarge"
      ],
      "ConstraintDescription":"must select a valid database instance type."
    },
    "DBEngineVersion":{
      "Default":"5.6",
      "Description":"Version of MySQL for the RDS",
      "Type":"String",
      "AllowedValues":[
        "5.5",
        "5.6"
      ],
      "ConstraintDescription":"must select a valid database version."
    },
    "DBAllocatedStorage":{
      "Default":"5",
      "Description":"The size of the database (Gb)",
      "Type":"Number",
      "MinValue":"5",
      "MaxValue":"3072",
      "ConstraintDescription":"must be between 5 and 3072Gb."
    },
    "MongoVolumeSize":{
      "Default":"5",
      "Description":"The size of the mongodb volumes(Gb). Because of RAID double the volume size will be available for mongo to use.",
      "Type":"Number",
      "MinValue":"5",
      "MaxValue":"3072",
      "ConstraintDescription":"must be between 5 and 3072Gb."
    }
  },
  "Mappings":{
    "AWSInstanceType2Arch":{
      "t1.micro":        { "Arch":"64" },
      "m1.small":        { "Arch":"64" },
      "m1.medium":       { "Arch":"64" },
      "m1.large":        { "Arch":"64" },
      "m1.xlarge":       { "Arch":"64" },
      "m2.xlarge":       { "Arch":"64" },
      "m2.2xlarge":      { "Arch":"64" },
      "m2.4xlarge":      { "Arch":"64" },
      "m3.xlarge":       { "Arch":"64" },
      "m3.2xlarge":      { "Arch":"64" },
      "c1.medium":       { "Arch":"64" },
      "c1.xlarge":       { "Arch":"64" },
      "cg1.4xlarge":     { "Arch":"64HVM" }
    },
    "AWSRegionArch2AMI":{
      "us-east-1":       { "32":"ami-def89fb7", "64":"ami-d0f89fb9", "64HVM":"ami-b93264d0" },
      "us-west-1":       { "32":"ami-fc002cb9", "64":"ami-fe002cbb" },
      "us-west-2":       { "32":"ami-0ef96e3e", "64":"ami-70f96e40", "64HVM":"ami-6cad335c" },
      "eu-west-1":       { "32":"ami-c27b6fb6", "64":"ami-ce7b6fba", "64HVM":"ami-8c987efb" },
      "sa-east-1":       { "32":"ami-a1da00bc", "64":"ami-a3da00be" },
      "ap-southeast-1":  { "32":"ami-66084734", "64":"ami-64084736" },
      "ap-southeast-2":  { "32":"ami-06ea7a3c", "64":"ami-04ea7a3e" },
      "ap-northeast-1":  { "32":"ami-fc6ceefd", "64":"ami-fe6ceeff" }
    },
    "AWSNATAMI":{
      "us-east-1":       { "AMI":"ami-c6699baf" },
      "us-west-2":       { "AMI":"ami-52ff7262" },
      "us-west-1":       { "AMI":"ami-3bcc9e7e" },
      "eu-west-1":       { "AMI":"ami-0b5b6c7f" },
      "ap-southeast-1":  { "AMI":"ami-02eb9350" },
      "ap-southeast-2":  { "AMI":"ami-ab990e91" },
      "ap-northeast-1":  { "AMI":"ami-14d86d15" },
      "sa-east-1":       { "AMI":"ami-0439e619" }
    },
    "SubnetConfig":{
      "VPC":             { "CIDR":"10.0.0.0/16" },
      "Public01":        { "CIDR":"10.0.0.0/24" },
      "Public02":        { "CIDR":"10.0.1.0/24" },
      "Edxapp01":        { "CIDR":"10.0.10.0/24" },
      "Edxapp02":        { "CIDR":"10.0.11.0/24" },
      "XServerJail01":   { "CIDR":"10.0.20.0/24" },
      "XServerJail02":   { "CIDR":"10.0.21.0/24" },
      "Xqueue01":        { "CIDR":"10.0.30.0/24" },
      "Xqueue02":        { "CIDR":"10.0.31.0/24" },
      "CommonCluster01": { "CIDR":"10.0.46.0/24"},
      "CommonCluster02": { "CIDR":"10.0.47.0/24"},
      "CommonCluster03": { "CIDR":"10.0.48.0/24"},
      "Data01":          { "CIDR":"10.0.50.0/24" },
      "Data02":          { "CIDR":"10.0.51.0/24" },
      "Cache01":         { "CIDR":"10.0.60.0/24" },
      "Cache02":         { "CIDR":"10.0.61.0/24" },
      "Worker01":        { "CIDR":"10.0.70.0/24" },
      "Worker02":        { "CIDR":"10.0.71.0/24" },
      "Forum01":        { "CIDR":"10.0.80.0/24" },
      "Forum02":        { "CIDR":"10.0.81.0/24" },
      "Mongo01":        { "CIDR":"10.0.90.0/24" },
      "Mongo02":        { "CIDR":"10.0.91.0/24" },
      "Mongo03":        { "CIDR":"10.0.92.0/24" },
      "Notifier01":        { "CIDR":"10.0.100.0/24" },
      "Admin":          { "CIDR":"10.0.200.0/24" }
    },
    "MapRegionsToAvailZones":{
      "us-east-1":       { "AZone2":"us-east-1d",      "AZone0":"us-east-1b",      "AZone1":"us-east-1c" },
      "us-west-1":       { "AZone0":"us-west-1a",      "AZone2":"us-west-1b",      "AZone1":"us-west-1c" },
      "us-west-2":       { "AZone0":"us-west-2a",      "AZone1":"us-west-2b",      "AZone2":"us-west-2c" },
      "eu-west-1":       { "AZone0":"eu-west-1a",      "AZone1":"eu-west-1b",      "AZone2":"eu-west-1c" },
      "sa-east-1":       { "AZone0":"sa-east-1a",      "AZone1":"sa-east-1b",      "AZone2":"sa-east-1c" },
      "ap-southeast-1":  { "AZone0":"ap-southeast-1a", "AZone1":"ap-southeast-1b", "AZone2":"ap-southeast-1c" },
      "ap-southeast-2":  { "AZone0":"ap-southeast-2a", "AZone1":"ap-southeast-2b", "AZone2":"ap-southeast-2c" },
      "ap-northeast-1":  { "AZone0":"ap-northeast-1a", "AZone1":"ap-northeast-1b", "AZone2":"ap-northeast-1c" }
    }
  },
  "Resources":{
    "EdxVPC":{
      "Type":"AWS::EC2::VPC",
      "Properties":{
        "EnableDnsSupport" : "true",
        "EnableDnsHostnames" : "true",
        "CidrBlock":"10.0.0.0/16",
        "InstanceTenancy":"default"
      }
    },
    "PublicSubnet01":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Public01",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone0"
          ]
        },
        "Tags":[ 
          { 
            "Key":"immutable_metadata", 
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "external','target':'ec2'}"
				 ]
				]
		    } 
          }
        ]
      }
    },
    "PublicSubnet02":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Public02",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone1"
          ]
        },
        "Tags":[ 
          { 
            "Key":"immutable_metadata",
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "external','target':'ec2'}"
				 ]
				]
		    }  
          } 
        ]
      }
    },
    "AdminSubnet":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Admin",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone0"
          ]
        },
        "Tags":[
          {
            "Key":"Application",
            "Value":"admin"
          },
          {
            "Key":"Network",
            "Value":"Private"
          }
        ]
      }
    },
    "EdxappSubnet01":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Edxapp01",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone0"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"edxapp"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key":"immutable_metadata", 
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-edxapp','target':'ec2'}"
				 ]
				]
		    }  
          }
        ]
      }
    },
    "EdxappSubnet02":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Edxapp02",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone1"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"edxapp"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key":"immutable_metadata", 
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-edxapp','target':'ec2'}"
				 ]
				]
		    }  
          }
        ]
      }
    },
    "XqueueSubnet01":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Xqueue01",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone0"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"xqueue"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata",
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-xqueue','target':'ec2'}"
				 ]
				]
		    }    
          }
        ]
      }
    },
    "XqueueSubnet02":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Xqueue02",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone1"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"xqueue"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata", 
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-xqueue','target':'ec2'}"
				 ]
				]
		    }
          }
        ]
      }
    },
    "CommonClusterSubnet01":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "CommonCluster01",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone0"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"commoncluster"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata", 
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-commoncluster','target':'ec2'}"
				 ]
				]
		    }
          }
        ]
      }
    },
    "CommonClusterSubnet02":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "CommonCluster02",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone1"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"commoncluster"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata",
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-commoncluster','target':'ec2'}"
				 ]
				]
		    } 
          }
        ]
      }
    },
    "CommonClusterSubnet03":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "CommonCluster03",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone2"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"commoncluster"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata",
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-commoncluster','target':'ec2'}"
				 ]
				]
		    } 
          }
        ]
      }
    },
    "XServerSubnet01":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "XServerJail01",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone0"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"xserver"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata", 
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-xserver','target':'ec2'}"
				 ]
				]
		    } 
          }
        ]
      }
    },
    "XServerSubnet02":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "XServerJail02",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone1"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"xserver"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata", 
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-xserver','target':'ec2'}"
				 ]
				]
		    } 
          }
        ]
      }
    },
    "Data01":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Data01",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone0"
          ]
        },
        "Tags":[
          {
            "Key":"Application",
            "Value":"RDS"
          },
          {
            "Key":"Network",
            "Value":"Data"
          }
        ]
      }
    },
    "Data02":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Data02",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone1"
          ]
        },
        "Tags":[
          {
            "Key":"Application",
            "Value":"RDS"
          },
          {
            "Key":"Network",
            "Value":"Data"
          }
        ]
      }
    },
    "Cache01":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Cache01",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone0"
          ]
        },
        "Tags":[
          {
            "Key":"Application",
            "Value":"Elasticache"
          },
          {
            "Key":"Network",
            "Value":"Cache"
          }
        ]
      }
    },
    "Cache02":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Cache02",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone1"
          ]
        },
        "Tags":[
          {
            "Key":"Application",
            "Value":"Elasticache"
          },
          {
            "Key":"Network",
            "Value":"Cache"
          }
        ]
      }
    },
    "WorkerSubnet01":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Worker01",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone0"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"worker"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata", 
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-worker','target':'ec2'}"
				 ]
				]
		    } 
          }
        ]
      }
    },
    "WorkerSubnet02":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Worker02",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone1"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"worker"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata", 
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-worker','target':'ec2'}"
				 ]
				]
		    } 
          }
        ]
      }
    },
    "ForumSubnet01":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Forum01",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone0"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"forum"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata", 
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-forum','target':'ec2'}"
				 ]
				]
		    } 
          }
        ]
      }
    },
    "ForumSubnet02":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Forum02",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone1"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"forum"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata", 
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-forum','target':'ec2'}"
				 ]
				]
		    }
          }
        ]
      }
    },
    "MongoSubnet01":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Mongo01",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone0"
          ]
        },
        "Tags":[
          {
            "Key":"Application",
            "Value":"mongo"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata", 
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-mongo','target':'ec2'}"
				 ]
				]
		    }
          }
        ]
      }
    },
    "MongoSubnet02":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Mongo02",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone1"
          ]
        },
        "Tags":[
          {
            "Key":"Application",
            "Value":"mongo"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata", 
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-mongo','target':'ec2'}"
				 ]
				]
		    }
          }
        ]
      }
    },
    "MongoSubnet03":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Mongo03",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone2"
          ]
        },
        "Tags":[
          {
            "Key":"Application",
            "Value":"mongo"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata",
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-mongo','target':'ec2'}"
				 ]
				]
		    } 
          }
        ]
      }
    },
    "NotifierSubnet01":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "CidrBlock":{
          "Fn::FindInMap":[
            "SubnetConfig",
            "Notifier01",
            "CIDR"
          ]
        },
        "AvailabilityZone":{
          "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone0"
          ]
        },
        "Tags":[
          {
            "Key":"play",
            "Value":"notifier"
          },
          {
            "Key":"Network",
            "Value":"Private"
          },
          {
            "Key" : "immutable_metadata",
            "Value":{"Fn::Join":["",
				 ["{'purpose':'",
				  {"Ref":"EnvironmentTag"},
				  "-",
				  {"Ref":"DeploymentTag"},
				  "-",
				  "internal-notifier','target':'ec2'}"
				 ]
				]
		    }
          }
        ]
      }
    },
    "InternetGateway":{
      "Type":"AWS::EC2::InternetGateway",
      "Properties":{
        "Tags":[
          {
            "Key":"Application",
            "Value":{
              "Ref":"AWS::StackId"
            }
          },
          {
            "Key":"Network",
            "Value":"Public"
          }
        ]
      }
    },
    "GatewayToInternet":{
      "Type":"AWS::EC2::VPCGatewayAttachment",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "InternetGatewayId":{
          "Ref":"InternetGateway"
        }
      }
    },
    "PublicRouteTable":{
      "Type":"AWS::EC2::RouteTable",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "Tags":[
          {
            "Key":"Application",
            "Value":{
              "Ref":"AWS::StackId"
            }
          },
          {
            "Key":"Network",
            "Value":"Public"
          }
        ]
      }
    },
    "PublicRoute":{
      "Type":"AWS::EC2::Route",
      "Properties":{
        "RouteTableId":{
          "Ref":"PublicRouteTable"
        },
        "DestinationCidrBlock":"0.0.0.0/0",
        "GatewayId":{
          "Ref":"InternetGateway"
        }
      }
    },
    "PublicSubnetRouteTableAssociation01":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"PublicSubnet01"
        },
        "RouteTableId":{
          "Ref":"PublicRouteTable"
        }
      }
    },
    "PublicSubnetRouteTableAssociation02":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"PublicSubnet02"
        },
        "RouteTableId":{
          "Ref":"PublicRouteTable"
        }
      }
    },
    "PublicNetworkAcl":{
      "Type":"AWS::EC2::NetworkAcl",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "Tags":[
          {
            "Key":"Application",
            "Value":{
              "Ref":"AWS::StackId"
            }
          },
          {
            "Key":"Network",
            "Value":"Public"
          }
        ]
      }
    },
    "InboundHTTPPublicNetworkAclEntry":{
      "Type":"AWS::EC2::NetworkAclEntry",
      "Properties":{
        "NetworkAclId":{
          "Ref":"PublicNetworkAcl"
        },
        "RuleNumber":"100",
        "Protocol":"6",
        "RuleAction":"allow",
        "Egress":"false",
        "CidrBlock":"0.0.0.0/0",
        "PortRange":{
          "From":"80",
          "To":"80"
        }
      }
    },
    "InboundHTTPSPublicNetworkAclEntry":{
      "Type":"AWS::EC2::NetworkAclEntry",
      "Properties":{
        "NetworkAclId":{
          "Ref":"PublicNetworkAcl"
        },
        "RuleNumber":"101",
        "Protocol":"6",
        "RuleAction":"allow",
        "Egress":"false",
        "CidrBlock":"0.0.0.0/0",
        "PortRange":{
          "From":"443",
          "To":"443"
        }
      }
    },
    "InboundSSHPublicNetworkAclEntry":{
      "Type":"AWS::EC2::NetworkAclEntry",
      "Properties":{
        "NetworkAclId":{
          "Ref":"PublicNetworkAcl"
        },
        "RuleNumber":"102",
        "Protocol":"6",
        "RuleAction":"allow",
        "Egress":"false",
        "CidrBlock":{
          "Ref":"SSHLocation"
        },
        "PortRange":{
          "From":"22",
          "To":"22"
        }
      }
    },
    "InboundEmphemeralPublicNetworkAclEntry":{
      "Type":"AWS::EC2::NetworkAclEntry",
      "Properties":{
        "NetworkAclId":{
          "Ref":"PublicNetworkAcl"
        },
        "RuleNumber":"103",
        "Protocol":"6",
        "RuleAction":"allow",
        "Egress":"false",
        "CidrBlock":"0.0.0.0/0",
        "PortRange":{
          "From":"1024",
          "To":"65535"
        }
      }
    },
    "InboundPingRequestPublicNetworkAclEntry":{
      "Type":"AWS::EC2::NetworkAclEntry",
      "Properties":{
        "NetworkAclId":{
          "Ref":"PublicNetworkAcl"
        },
        "RuleNumber":"104",
        "Protocol":"1",
        "RuleAction":"allow",
        "Egress":"false",
        "CidrBlock":"10.0.0.0/16",
        "Icmp": {
          "Code": "0",
          "Type": "0"
        }
      }
    },
    "InboundPingReplyPublicNetworkAclEntry":{
      "Type":"AWS::EC2::NetworkAclEntry",
      "Properties":{
        "NetworkAclId":{
          "Ref":"PublicNetworkAcl"
        },
        "RuleNumber":"105",
        "Protocol":"1",
        "RuleAction":"allow",
        "Egress":"false",
        "CidrBlock":"10.0.0.0/16",
        "Icmp": {
          "Code": "0",
          "Type": "8"
        }
      }
    },
    "OutboundPublicNetworkAclEntry":{
      "Type":"AWS::EC2::NetworkAclEntry",
      "Properties":{
        "NetworkAclId":{
          "Ref":"PublicNetworkAcl"
        },
        "RuleNumber":"100",
        "Protocol":"6",
        "RuleAction":"allow",
        "Egress":"true",
        "CidrBlock":"0.0.0.0/0",
        "PortRange":{
          "From":"0",
          "To":"65535"
        }
      }
    },
    "OutboundPingRequestPublicNetworkAclEntry":{
      "Type":"AWS::EC2::NetworkAclEntry",
      "Properties":{
        "NetworkAclId":{
          "Ref":"PublicNetworkAcl"
        },
        "RuleNumber":"101",
        "Protocol":"1",
        "RuleAction":"allow",
        "Egress":"true",
        "CidrBlock":"10.0.0.0/16",
        "Icmp": {
          "Code": "0",
          "Type": "0"
        }
      }
    },
    "OutboundPingReplyPublicNetworkAclEntry":{
      "Type":"AWS::EC2::NetworkAclEntry",
      "Properties":{
        "NetworkAclId":{
          "Ref":"PublicNetworkAcl"
        },
        "RuleNumber":"102",
        "Protocol":"1",
        "RuleAction":"allow",
        "Egress":"true",
        "CidrBlock":"10.0.0.0/16",
        "Icmp": {
          "Code": "0",
          "Type": "8"
        }
      }
    },
    "PublicSubnetNetworkAclAssociation01":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"PublicSubnet01"
        },
        "NetworkAclId":{
          "Ref":"PublicNetworkAcl"
        }
      }
    },
    "PublicSubnetNetworkAclAssociation02":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"PublicSubnet02"
        },
        "NetworkAclId":{
          "Ref":"PublicNetworkAcl"
        }
      }
    },
    "PrivateRouteTable":{
      "Type":"AWS::EC2::RouteTable",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "Tags":[
          {
            "Key":"Application",
            "Value":{
              "Ref":"AWS::StackId"
            }
          },
          {
            "Key":"Network",
            "Value":"Private"
          }
        ]
      }
    },
    "PrivateRoute":{
      "Type":"AWS::EC2::Route",
      "Properties":{
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        },
        "DestinationCidrBlock":"0.0.0.0/0",
        "InstanceId":{
          "Ref":"NATDevice"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationAdmin":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"AdminSubnet"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationEdxapp01":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"EdxappSubnet01"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationEdxapp02":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"EdxappSubnet02"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationXqueue01":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"XqueueSubnet01"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationXqueue02":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"XqueueSubnet02"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationCommonCluster01":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"CommonClusterSubnet01"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationCommonCluster02":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"CommonClusterSubnet02"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationCommonCluster03":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"CommonClusterSubnet03"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationXServer01":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"XServerSubnet01"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationXServer02":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"XServerSubnet02"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationData01":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"Data01"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationData02":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"Data02"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationCache01":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"Cache01"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationCache02":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"Cache02"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationWorker01":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"WorkerSubnet01"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationWorker02":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"WorkerSubnet02"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationForum01":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"ForumSubnet01"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationForum02":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"ForumSubnet02"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationNotifier01":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"NotifierSubnet01"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationMongo01":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"MongoSubnet01"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationMongo02":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"MongoSubnet02"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateSubnetRouteTableAssociationMongo03":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"MongoSubnet03"
        },
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        }
      }
    },
    "PrivateNetworkAcl":{
      "Type":"AWS::EC2::NetworkAcl",
      "Properties":{
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "Tags":[
          {
            "Key":"Application",
            "Value":{
              "Ref":"AWS::StackId"
            }
          },
          {
            "Key":"Network",
            "Value":"Private"
          }
        ]
      }
    },
    "InboundPrivateNetworkAclEntry":{
      "Type":"AWS::EC2::NetworkAclEntry",
      "Properties":{
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        },
        "RuleNumber":"100",
        "Protocol":"6",
        "RuleAction":"allow",
        "Egress":"false",
        "CidrBlock":"0.0.0.0/0",
        "PortRange":{
          "From":"0",
          "To":"65535"
        }
      }
    },
    "OutBoundPrivateNetworkAclEntry":{
      "Type":"AWS::EC2::NetworkAclEntry",
      "Properties":{
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        },
        "RuleNumber":"100",
        "Protocol":"6",
        "RuleAction":"allow",
        "Egress":"true",
        "CidrBlock":"0.0.0.0/0",
        "PortRange":{
          "From":"0",
          "To":"65535"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationAdmin":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"AdminSubnet"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationEdxapp01":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"EdxappSubnet01"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationEdxapp02":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"EdxappSubnet02"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationXqueue01":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"XqueueSubnet01"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationXqueue02":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"XqueueSubnet02"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationCommonCluster01":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"CommonClusterSubnet01"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationCommonCluster02":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"CommonClusterSubnet02"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationCommonCluster03":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"CommonClusterSubnet03"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationXServer01":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"XServerSubnet01"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationXServer02":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"XServerSubnet02"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationData01":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"Data01"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationData02":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"Data02"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationCache01":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"Cache01"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationCache02":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"Cache02"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationWorker01":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"WorkerSubnet01"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationWorker02":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"WorkerSubnet02"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationForum01":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"ForumSubnet01"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationForum02":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"ForumSubnet02"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationNotifier01":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"NotifierSubnet01"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationMongo01":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"MongoSubnet01"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationMongo02":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"MongoSubnet02"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "PrivateSubnetNetworkAclAssociationMongo03":{
      "Type":"AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId":{
          "Ref":"MongoSubnet03"
        },
        "NetworkAclId":{
          "Ref":"PrivateNetworkAcl"
        }
      }
    },
    "NATIPAddress":{
      "Type":"AWS::EC2::EIP",
      "Properties":{
        "Domain":"vpc",
        "InstanceId":{
          "Ref":"NATDevice"
        }
      }
    },
    "NATDevice":{
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "InstanceType":{
          "Ref":"NATInstanceType"
        },
        "KeyName":{
          "Ref":"KeyName"
        },
        "SubnetId":{
          "Ref":"PublicSubnet01"
        },
        "SourceDestCheck":"false",
        "ImageId":{
          "Fn::FindInMap":[
            "AWSNATAMI",
            {
              "Ref":"AWS::Region"
            },
            "AMI"
          ]
        },
        "SecurityGroupIds":[
          {
            "Ref":"NATSecurityGroup"
          }
        ]
      }
    },
    "BackupNATIPAddress":{
      "Type":"AWS::EC2::EIP",
      "Properties":{
        "Domain":"vpc",
        "InstanceId":{
          "Ref":"BackupNATDevice"
        }
      }
    },
    "BackupNATDevice":{
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "InstanceType":{
          "Ref":"NATInstanceType"
        },
        "KeyName":{
          "Ref":"KeyName"
        },
        "SubnetId":{
          "Ref":"PublicSubnet02"
        },
        "SourceDestCheck":"false",
        "ImageId":{
          "Fn::FindInMap":[
            "AWSNATAMI",
            {
              "Ref":"AWS::Region"
            },
            "AMI"
          ]
        },
        "SecurityGroupIds":[
          {
            "Ref":"NATSecurityGroup"
          }
        ]
      }
    },
    "NATSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Enable internal access to the NAT device",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "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"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":{
              "Ref":"SSHLocation"
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"9418",
            "ToPort":"9418",
            "CidrIp":"0.0.0.0/0"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"9997",
            "ToPort":"9997",
            "CidrIp":"0.0.0.0/0"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"10016",
            "ToPort":"10016",
            "CidrIp":"0.0.0.0/0"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"11371",
            "ToPort":"11371",
            "CidrIp":"0.0.0.0/0"
          },
          {
            "IpProtocol":"icmp",
            "FromPort":"-1",
            "ToPort":"-1",
            "CidrIp":"0.0.0.0/0"
          }
        ],
        "SecurityGroupEgress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"80",
            "ToPort":"80",
            "CidrIp":"0.0.0.0/0"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"443",
            "ToPort":"443",
            "CidrIp":"0.0.0.0/0"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":{
              "Ref":"SSHLocation"
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"9997",
            "ToPort":"9997",
            "CidrIp":"0.0.0.0/0"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"9418",
            "ToPort":"9418",
            "CidrIp":"0.0.0.0/0"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"10016",
            "ToPort":"10016",
            "CidrIp":"0.0.0.0/0"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"11371",
            "ToPort":"11371",
            "CidrIp":"0.0.0.0/0"
          }
        ]
      }
    },
    "NATMonitorRole": {
       "Type": "AWS::IAM::Role",
       "Properties": {
          "AssumeRolePolicyDocument": {
             "Statement": [ {
                "Effect": "Allow",
                "Principal": {
                   "Service": [ "ec2.amazonaws.com" ]
                },
                "Action": [ "sts:AssumeRole" ]
             } ]
          },
          "Path": "/",
          "Policies": [ {
             "PolicyName": "NAT_Takeover",
             "PolicyDocument": {
                "Statement": [ {
                   "Effect": "Allow",
                   "Action": [
                        "ec2:DescribeInstances",
                        "ec2:DescribeRouteTables",
                        "ec2:CreateRoute",
                        "ec2:ReplaceRoute",
                        "ec2:StartInstances",
                        "ec2:StopInstances"
                   ],
                   "Resource": "*"
                } ]
             }
          } ]
       }
    },
    "NATMonitorRoleProfile": {
       "Type": "AWS::IAM::InstanceProfile",
       "Properties": {
          "Path": "/",
          "Roles": [ {
             "Ref": "NATMonitorRole"
          } ]
       }
    },
    "BastionIPAddress":{
      "Type":"AWS::EC2::EIP",
      "Properties":{
        "Domain":"vpc",
        "InstanceId":{
          "Ref":"BastionHost"
        }
      }
    },
    "BastionHost":{
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "InstanceType":{
          "Ref":"BastionInstanceType"
        },
        "KeyName":{
          "Ref":"KeyName"
        },
        "IamInstanceProfile" : { 
          "Ref" : "NATMonitorRoleProfile"
        },
        "SubnetId":{
          "Ref":"PublicSubnet01"
        },
        "ImageId":{
          "Fn::FindInMap":[
            "AWSRegionArch2AMI",
            {
              "Ref":"AWS::Region"
            },
            {
              "Fn::FindInMap":[
                "AWSInstanceType2Arch",
                {
                  "Ref":"BastionInstanceType"
                },
                "Arch"
              ]
            }
          ]
        },
        "SecurityGroupIds":[
          {
            "Ref":"BastionSecurityGroup"
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"bastion"
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            },
            "PropagateAtLaunch":true
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            },
            "PropagateAtLaunch":true
          }
        ],
        "UserData": { "Fn::Base64" : { "Fn::Join" : ["", [
          "#!/bin/bash -v\n",
          "mkdir -p /opt/edx/bin\n",
          "cd /opt\n",
          "apt-get update\n",
          "apt-get install openjdk-6-jre-headless unzip -y\n",
          "wget http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip\n",
          "unzip ec2-api-tools.zip\n",
          "rm ec2-api-tools.zip\n",
          "ln -sf ec2-api-tools-* ec2-api-tools\n",

          "cat <<'EOF' > /opt/edx/bin/nat_monitor.sh\n",
          "#!/bin/bash\n",
          "# This script will monitor another NAT instance and take over its routes\n",
          "# if communication with the other instance fails\n",
          "\n",
          "# NAT instance variables\n",
          "# Other instance's IP to ping and route to grab if other node goes down\n",
          "PRIMARY_NAT_ID=", { "Ref":"NATDevice" }, "\n",
          "BACKUP_NAT_ID=", { "Ref": "BackupNATDevice" }, "\n",
          "NAT_RT_ID=", { "Ref": "PrivateRouteTable" }, "\n",
          "\n",
          "# Specify the EC2 region that this will be running in (e.g. https://ec2.us-east-1.amazonaws.com)\n",
          "EC2_URL=https://ec2.",{ "Ref": "AWS::Region" },".amazonaws.com\n",
          "\n",
          "# Health Check variables\n",
          "Num_Pings=3\n",
          "Ping_Timeout=1\n",
          "Wait_Between_Pings=2\n",
          "Wait_for_Instance_Stop=60\n",
          "Wait_for_Instance_Start=300\n",
          "\n",
          "# leverage AWS security credentials provided by EC2 roles\n",
          "# Setup environment for ec2 api tools\n",
          "export EC2_HOME=/opt/ec2-api-tools\n",
          "export AWS_IAM_HOME=/opt/IAMCli\n",
          "export JAVA_HOME=/usr/lib/jvm/java-6-openjdk-amd64\n",
          "PATH=/opt/ec2-api-tools/bin:$PATH\n",
          "\n",
          "# Determine the NAT instance private IP so we can ping the other NAT instance, take over\n",
          "# its route, and reboot it.  Requires EC2 DescribeInstances, ReplaceRoute, and Start/RebootInstances\n",
          "# permissions.  The following example EC2 Roles policy will authorize these commands:\n",
          "# {\n",
          "#  \"Statement\": [\n",
          "#    {\n",
          "#      \"Action\": [\n",
          "#        \"ec2:DescribeInstances\",\n",
          "#        \"ec2:CreateRoute\",\n",
          "#        \"ec2:ReplaceRoute\",\n",
          "#        \"ec2:StartInstances\",\n",
          "#        \"ec2:StopInstances\"\n",
          "#      ],\n",
          "#      \"Effect\": \"Allow\",\n",
          "#      \"Resource\": \"*\"\n",
          "#    }\n",
          "#  ]\n",
          "# }\n",
          "\n",
          "# Get the primary NAT instance's IP\n",
          "PRIMARY_NAT_IP=`/opt/ec2-api-tools/bin/ec2-describe-instances $PRIMARY_NAT_ID -U $EC2_URL | grep PRIVATEIPADDRESS -m 1 | awk '{print $2;}'`\n",
          "BACKUP_NAT_IP=`/opt/ec2-api-tools/bin/ec2-describe-instances $BACKUP_NAT_ID -U $EC2_URL | grep PRIVATEIPADDRESS -m 1 | awk '{print $2;}'`\n",
          "\n",
          "echo `date` \"-- Starting NAT monitor\"\n",
          "\n",
          "while [ . ]; do\n",
          "  # Check the health of both instances.\n",
          "  primary_pingresult=`ping -c $Num_Pings -W $Ping_Timeout $PRIMARY_NAT_IP| grep time= | wc -l`\n",
          "\n",
          "  if [ \"$primary_pingresult\" == \"0\" ]; then\n",
          "    backup_pingresult=`ping -c $Num_Pings -W $Ping_Timeout $BACKUP_NAT_IP| grep time= | wc -l`\n",
          "    if [ \"$backup_pingresult\" == \"0\" ]; then\n",
          "      echo `date` \"-- Both NAT devices un reachable.\"\n",
          "      #TODO: Notify alert that both NATs are down.\n",
          "    else #Backup nat is healthy.\n",
          "      # Set HEALTHY variables to unhealthy (0)\n",
          "      ROUTE_HEALTHY=0\n",
          "      NAT_HEALTHY=0\n",
          "      STOPPING_NAT=0\n",
          "      while [ \"$NAT_HEALTHY\" == \"0\" ]; do\n",
          "      # Primary NAT instance is unhealthy, loop while we try to fix it\n",
          "        if [ \"$ROUTE_HEALTHY\" == \"0\" ]; then\n",
          "          echo `date` \"-- NAT($PRIMARY_NAT_ID) heartbeat failed, using $BACKUP_NAT_ID for $NAT_RT_ID default route\"\n",
          "          /opt/ec2-api-tools/bin/ec2-replace-route $NAT_RT_ID -r 0.0.0.0/0 -i $BACKUP_NAT_ID -U $EC2_URL\n",
          "          ROUTE_HEALTHY=1\n",
          "        fi\n",
          "        # Check NAT state to see if we should stop it or start it again\n",
          "        NAT_STATE=`/opt/ec2-api-tools/bin/ec2-describe-instances $PRIMARY_NAT_ID -U $EC2_URL | grep INSTANCE | awk '{print $5;}'`\n",
          "        if [ \"$NAT_STATE\" == \"stopped\" ]; then\n",
          "          echo `date` \"-- NAT($PRIMARY_NAT_ID) instance stopped, starting it back up\"\n",
          "          /opt/ec2-api-tools/bin/ec2-start-instances $PRIMARY_NAT_ID -U $EC2_URL\n",
          "          sleep $Wait_for_Instance_Start\n",
          "        else\n",
          "          if [ \"$STOPPING_NAT\" == \"0\" ]; then\n",
          "            echo `date` \"-- NAT($PRIMARY_NAT_ID) instance $NAT_STATE, attempting to stop for reboot\"\n",
          "            /opt/ec2-api-tools/bin/ec2-stop-instances $PRIMARY_NAT_ID -U $EC2_URL\n",
          "            STOPPING_NAT=1\n",
          "          fi\n",
          "          sleep $Wait_for_Instance_Stop\n",
          "        fi\n",
          "        unhealthy_nat_pingresult=`ping -c $Num_Pings -W $Ping_Timeout $PRIMARY_NAT_IP| grep time= | wc -l`\n",
          "        if [ \"$unhealthy_nat_pingresult\" == \"$Num_Pings\" ]; then\n",
          "          NAT_HEALTHY=1\n",
          "        fi\n",
          "      done\n",
          "\n",
          "      # Backup nat was healthy so we switched to it.  It is now the primary.\n",
          "      if [ \"$ROUTE_HEALTHY\" == \"1\" ]; then\n",
          "        TEMP_NAT_ID=$PRIMARY_NAT_ID\n",
          "        TEMP_NAT_IP=$PRIMARY_NAT_IP\n",
          "\n",
          "        PRIMARY_NAT_ID=$BACKUP_NAT_ID\n",
          "        PRIMARY_NAT_IP=$BACKUP_NAT_IP\n",
          "\n",
          "        BACKUP_NAT_ID=$TEMP_NAT_ID\n",
          "        BACKUP_NAT_IP=$TEMP_NAT_IP\n",
          "      fi\n",
          "    fi\n",
          "  else\n",
          "    sleep $Wait_Between_Pings\n",
          "  fi\n",
          "done\n",
          "EOF\n",
          "chmod u+x /opt/edx/bin/nat_monitor.sh\n",
          "echo '@reboot /opt/edx/bin/nat_monitor.sh > /var/log/nat_monitor.log' | crontab\n",
          "/opt/edx/bin/nat_monitor.sh > /var/log/nat_monitor.log &\n"
        ]]}}
      }
    },
    "BastionSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Enable access to the Bastion host",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":{
              "Ref":"SSHLocation"
            }
          }
        ],
        "SecurityGroupEgress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":"10.0.0.0/16"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"80",
            "ToPort":"80",
            "CidrIp":"0.0.0.0/0"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"443",
            "ToPort":"443",
            "CidrIp":"0.0.0.0/0"
          },
          {
            "IpProtocol":"icmp",
            "FromPort":"-1",
            "ToPort":"-1",
            "CidrIp":"0.0.0.0/0"
          }
        ]
      }
    },
		"EdxappRole": {
				"Type": "AWS::IAM::Role",
        "Properties": {
						"AssumeRolePolicyDocument": {
								"Statement": [ {
										"Effect": "Allow",
										"Principal": {
												"Service": [ "ec2.amazonaws.com" ]
										},
										"Action": [ "sts:AssumeRole" ]
								} ]
            },
            "Path": "/",
            "Policies": [ {
              "PolicyName": "EdxAppBasePolicy",
              "PolicyDocument": {
                "Statement":[
                  {
                    "Effect":"Allow",
                    "Action":[
                      "cloudformation:DescribeStackResource",
                      "s3:Put",
                      "ses:SendEmail",
                      "ses:SendRawEmail",
                      "ses:GetSendQuota"
                    ],
                    "Resource":"*"
                  }
                ]
              }
            } ]
        }
    },
	  "EdxappInstanceProfile": {
        "Type": "AWS::IAM::InstanceProfile",
        "Properties": {
            "Path": "/",
            "Roles": [ {
								"Ref": "EdxappRole"
            } ]
        }
    },
		"XqueueRole": {
				"Type": "AWS::IAM::Role",
        "Properties": {
						"AssumeRolePolicyDocument": {
								"Statement": [ {
										"Effect": "Allow",
										"Principal": {
												"Service": [ "ec2.amazonaws.com" ]
										},
										"Action": [ "sts:AssumeRole" ]
								} ]
            },
            "Path": "/"
        }
    },
	  "XqueueInstanceProfile": {
        "Type": "AWS::IAM::InstanceProfile",
        "Properties": {
            "Path": "/",
            "Roles": [ {
								"Ref": "XqueueRole"
            } ]
        }
    },
		"XServerRole": {
				"Type": "AWS::IAM::Role",
        "Properties": {
						"AssumeRolePolicyDocument": {
								"Statement": [ {
										"Effect": "Allow",
										"Principal": {
												"Service": [ "ec2.amazonaws.com" ]
										},
										"Action": [ "sts:AssumeRole" ]
								} ]
            },
            "Path": "/"
        }
    },
	  "XServerInstanceProfile": {
        "Type": "AWS::IAM::InstanceProfile",
        "Properties": {
            "Path": "/",
            "Roles": [ {
								"Ref": "XServerRole"
            } ]
        }
    },
    "AdminSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Admin Security Group",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":{
              "Ref":"SSHLocation"
            }
          }
        ]
      }
    },
    "EdxappServer":{
      "Type":"AWS::AutoScaling::LaunchConfiguration",
      "Properties":{
				"IamInstanceProfile":{ "Ref":"EdxappInstanceProfile" },
        "SecurityGroups":[
          {
            "Ref":"EdxappServerSecurityGroup"
          }
        ],
        "ImageId":{
          "Fn::FindInMap":[
            "AWSRegionArch2AMI",
            {
              "Ref":"AWS::Region"
            },
            {
              "Fn::FindInMap":[
                "AWSInstanceType2Arch",
                {
                  "Ref":"EdxappInstanceType"
                },
                "Arch"
              ]
            }
          ]
        },
        "UserData":{
          "Fn::Base64":{
            "Fn::Join":[
              "",
              [
                "#!/bin/bash -x\n",
                "exec >> /home/ubuntu/cflog.log\n",
                "exec 2>> /home/ubuntu/cflog.log\n",
                "function error_exit\n",
                "{\n",
                "  cfn-signal -e 1 -r \"$1\" '",
                {
                  "Ref":"EdxServerWaitHandle"
                },
                "'\n",
                "  exit 1\n",
                "}\n",
                "for dev in /dev/xvdc /dev/xvdd; do sudo echo w | fdisk $dev; sudo mkfs -t ext4 $dev;done;\n",
                "sudo mkdir /mnt/logs\n",
                "sudo mount /dev/xvdc /mnt/logs\n",
                "sudo mount /dev/xvdd /opt\n",
                "apt-get -y update\n",
                "apt-get -y install python-setuptools\n",
                "echo \"Python Tools installed\" - `date`\n",
                "easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
                "echo \"Cloudformation Boostrap installed \" - `date`\n",
                "# If all went well, signal success\n",
                "cfn-signal -e $? -r 'Edx Server configuration' '",
                {
                  "Ref":"EdxServerWaitHandle"
                },
                "'\n"
              ]
            ]
          }
        },
        "KeyName":{
          "Ref":"KeyName"
        },
        "InstanceType":{
          "Ref":"EdxappInstanceType"
        },
        "BlockDeviceMappings":[
          {
            "DeviceName":"/dev/xvdc",
            "Ebs":{
              "VolumeSize":"50"
            }
          },
          {
            "DeviceName":"/dev/xvdd",
            "Ebs":{
              "VolumeSize":"50"
            }
          }
        ]
      }
    },
    "EdxappServerASGroup":{
      "Type":"AWS::AutoScaling::AutoScalingGroup",
      "Properties":{
        "AvailabilityZones":[
          {
            "Fn::GetAtt":[
              "EdxappSubnet01",
              "AvailabilityZone"
            ]
          },
          {
            "Fn::GetAtt":[
              "EdxappSubnet02",
              "AvailabilityZone"
            ]
          }
        ],
        "VPCZoneIdentifier":[
          {
            "Ref":"EdxappSubnet01"
          },
          {
            "Ref":"EdxappSubnet02"
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"edxapp",
            "PropagateAtLaunch":true
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            },
            "PropagateAtLaunch":true
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            },
            "PropagateAtLaunch":true
          }
        ],
        "LaunchConfigurationName":{
          "Ref":"EdxappServer"
        },
        "MinSize":{
          "Ref":"EdxappDesiredCapacity"
        },
        "MaxSize":{
          "Ref":"EdxappDesiredCapacity"
        },
        "DesiredCapacity":{
          "Ref":"EdxappDesiredCapacity"
        },
        "LoadBalancerNames":[
          {
            "Ref":"EdxappELB"
          }
        ]
      }
    },
    "EdxappServerScaleUpPolicy":{
      "Type":"AWS::AutoScaling::ScalingPolicy",
      "Properties":{
        "AdjustmentType":"ChangeInCapacity",
        "AutoScalingGroupName":{
          "Ref":"EdxappServerASGroup"
        },
        "Cooldown":"60",
        "ScalingAdjustment":"1"
      }
    },
    "EdxappServerScaleDownPolicy":{
      "Type":"AWS::AutoScaling::ScalingPolicy",
      "Properties":{
        "AdjustmentType":"ChangeInCapacity",
        "AutoScalingGroupName":{
          "Ref":"EdxappServerASGroup"
        },
        "Cooldown":"60",
        "ScalingAdjustment":"-1"
      }
    },
    "EdxappCPUAlarmHigh":{
      "Type":"AWS::CloudWatch::Alarm",
      "Properties":{
        "AlarmDescription":"Scale-up if CPU > 90% for 10 minutes",
        "MetricName":"CPUUtilization",
        "Namespace":"AWS/EC2",
        "Statistic":"Average",
        "Period":"300",
        "EvaluationPeriods":"2",
        "Threshold":"90",
        "AlarmActions":[
          {
            "Ref":"EdxappServerScaleUpPolicy"
          }
        ],
        "Dimensions":[
          {
            "Name":"AutoScalingGroupName",
            "Value":{
              "Ref":"EdxappServerASGroup"
            }
          }
        ],
        "ComparisonOperator":"GreaterThanThreshold"
      }
    },
    "EdxappCPUAlarmLow":{
      "Type":"AWS::CloudWatch::Alarm",
      "Properties":{
        "AlarmDescription":"Scale-down if CPU < 70% for 10 minutes",
        "MetricName":"CPUUtilization",
        "Namespace":"AWS/EC2",
        "Statistic":"Average",
        "Period":"300",
        "EvaluationPeriods":"2",
        "Threshold":"70",
        "AlarmActions":[
          {
            "Ref":"EdxappServerScaleDownPolicy"
          }
        ],
        "Dimensions":[
          {
            "Name":"AutoScalingGroupName",
            "Value":{
              "Ref":"EdxappServerASGroup"
            }
          }
        ],
        "ComparisonOperator":"LessThanThreshold"
      }
    },
    "EdxappELB":{
      "Type":"AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties":{
        "LBCookieStickinessPolicy" : [{
          "PolicyName" : "EdxappStickinessPolicy",
          "CookieExpirationPeriod" : "180"
        } ],
        "SecurityGroups":[
          {
            "Ref":"EdxappELBSecurityGroup"
          }
        ],
        "Listeners":[
          {
            "LoadBalancerPort":"80",
            "InstancePort":{
              "Ref":"EdxappServerPort"
            },
            "Protocol":"HTTP"
          },
          {
            "LoadBalancerPort":"443",
            "InstancePort":{
              "Ref":"EdxappServerPort"
            },
            "Protocol":"HTTPS",
            "InstanceProtocol":"HTTP",
            "SSLCertificateId": {
              "Ref": "SSLCertificateARN"
            }
          }
        ],
        "HealthCheck":{
          "Target": { "Fn::Join":[ "",
            [
              "HTTP:",
              { "Ref": "EdxappServerPort" },
              "/heartbeat"
            ]
          ]},
          "HealthyThreshold":"3",
          "UnhealthyThreshold":"5",
          "Interval":"30",
          "Timeout":"5"
        },
        "Subnets":[
          {
            "Ref":"PublicSubnet01"
          },
          {
            "Ref":"PublicSubnet02"
          }
        ]
      }
    },
    "EdxappELBSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Enable HTTP access on port 80",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "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"
          }
        ],
        "SecurityGroupEgress":[
          {
            "IpProtocol":"tcp",
            "FromPort":{
              "Ref":"EdxappServerPort"
            },
            "ToPort":{
              "Ref":"EdxappServerPort"
            },
            "CidrIp":"0.0.0.0/0"
          }
        ]
      }
    },
    "EdxappServerSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Open up SSH access plus Edx Server required ports",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":{
              "Ref":"SSHLocation"
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":{
              "Ref":"EdxappServerPort"
            },
            "ToPort":{
              "Ref":"EdxappServerPort"
            },
            "CidrIp":"0.0.0.0/0"
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"edxapp"
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            }
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            }
          }
        ]
      }
    },
    "EdxServerWaitHandle":{
      "Type":"AWS::CloudFormation::WaitConditionHandle"
    },
    "EdxServerWaitCondition":{
      "Type":"AWS::CloudFormation::WaitCondition",
      "DependsOn":"EdxappServer",
      "Properties":{
        "Handle":{
          "Ref":"EdxServerWaitHandle"
        },
        "Timeout":"1200"
      }
    },
    "XqueueServer":{
      "Type":"AWS::AutoScaling::LaunchConfiguration",
      "Properties":{
				"IamInstanceProfile":{ "Ref":"XqueueInstanceProfile" },
        "SecurityGroups":[
          {
            "Ref":"XqueueServerSecurityGroup"
          }
        ],
        "ImageId":{
          "Fn::FindInMap":[
            "AWSRegionArch2AMI",
            {
              "Ref":"AWS::Region"
            },
            {
              "Fn::FindInMap":[
                "AWSInstanceType2Arch",
                {
                  "Ref":"XqueueInstanceType"
                },
                "Arch"
              ]
            }
          ]
        },
        "UserData":{
          "Fn::Base64":{
            "Fn::Join":[
              "",
              [
                "#!/bin/bash -x\n",
                "exec >> /home/ubuntu/cflog.log\n",
                "exec 2>> /home/ubuntu/cflog.log\n",
                "function error_exit\n",
                "{\n",
                "  cfn-signal -e 1 -r \"$1\" '",
                {
                  "Ref":"XqueueServerWaitHandle"
                },
                "'\n",
                "  exit 1\n",
                "}\n",
                "apt-get -y update\n",
                "apt-get -y install python-setuptools\n",
                "echo \"Python Tools installed\" - `date`\n",
                "easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
                "echo \"Cloudformation Boostrap installed \" - `date`\n",
                "# If all went well, signal success\n",
                "cfn-signal -e $? -r 'Edx Server configuration' '",
                {
                  "Ref":"XqueueServerWaitHandle"
                },
                "'\n"
              ]
            ]
          }
        },
        "KeyName":{
          "Ref":"KeyName"
        },
        "InstanceType":{
          "Ref":"XqueueInstanceType"
        },
        "BlockDeviceMappings":[
          {
            "DeviceName":"/dev/xvdc",
            "Ebs":{
              "VolumeSize":"50"
            }
          },
          {
            "DeviceName":"/dev/xvdd",
            "Ebs":{
              "VolumeSize":"50"
            }
          }
        ]
      }
    },
    "XqueueServerASGroup":{
      "Type":"AWS::AutoScaling::AutoScalingGroup",
      "Properties":{
        "AvailabilityZones":[
          {
            "Fn::GetAtt":[
              "XqueueSubnet01",
              "AvailabilityZone"
            ]
          },
          {
            "Fn::GetAtt":[
              "XqueueSubnet02",
              "AvailabilityZone"
            ]
          }
        ],
        "VPCZoneIdentifier":[
          {
            "Ref":"XqueueSubnet01"
          },
          {
            "Ref":"XqueueSubnet02"
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"xqueue",
            "PropagateAtLaunch":true
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            },
            "PropagateAtLaunch":true
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            },
            "PropagateAtLaunch":true
          }
        ],
        "LaunchConfigurationName":{
          "Ref":"XqueueServer"
        },
        "MinSize":{
          "Ref":"XqueueDesiredCapacity"
        },
        "MaxSize":{
          "Ref":"XqueueDesiredCapacity"
        },
        "DesiredCapacity":{
          "Ref":"XqueueDesiredCapacity"
        },
        "LoadBalancerNames":[
          {
            "Ref":"XqueueELB"
          }
        ]
      }
    },
    "XqueueScaleUpPolicy":{
      "Type":"AWS::AutoScaling::ScalingPolicy",
      "Properties":{
        "AdjustmentType":"ChangeInCapacity",
        "AutoScalingGroupName":{
          "Ref":"XqueueServerASGroup"
        },
        "Cooldown":"60",
        "ScalingAdjustment":"1"
      }
    },
    "XqueueScaleDownPolicy":{
      "Type":"AWS::AutoScaling::ScalingPolicy",
      "Properties":{
        "AdjustmentType":"ChangeInCapacity",
        "AutoScalingGroupName":{
          "Ref":"XqueueServerASGroup"
        },
        "Cooldown":"60",
        "ScalingAdjustment":"-1"
      }
    },
    "XqueueCPUAlarmHigh":{
      "Type":"AWS::CloudWatch::Alarm",
      "Properties":{
        "AlarmDescription":"Scale-up if CPU > 90% for 10 minutes",
        "MetricName":"CPUUtilization",
        "Namespace":"AWS/EC2",
        "Statistic":"Average",
        "Period":"300",
        "EvaluationPeriods":"2",
        "Threshold":"90",
        "AlarmActions":[
          {
            "Ref":"XqueueScaleUpPolicy"
          }
        ],
        "Dimensions":[
          {
            "Name":"AutoScalingGroupName",
            "Value":{
              "Ref":"XqueueServerASGroup"
            }
          }
        ],
        "ComparisonOperator":"GreaterThanThreshold"
      }
    },
    "XqueueCPUAlarmLow":{
      "Type":"AWS::CloudWatch::Alarm",
      "Properties":{
        "AlarmDescription":"Scale-down if CPU < 70% for 10 minutes",
        "MetricName":"CPUUtilization",
        "Namespace":"AWS/EC2",
        "Statistic":"Average",
        "Period":"300",
        "EvaluationPeriods":"2",
        "Threshold":"70",
        "AlarmActions":[
          {
            "Ref":"XqueueScaleDownPolicy"
          }
        ],
        "Dimensions":[
          {
            "Name":"AutoScalingGroupName",
            "Value":{
              "Ref":"XqueueServerASGroup"
            }
          }
        ],
        "ComparisonOperator":"LessThanThreshold"
      }
    },
    "XqueueELB":{
      "Type":"AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties":{
        "SecurityGroups":[
          {
            "Ref":"XqueueELBSecurityGroup"
          }
        ],
        "Listeners":[
          {
            "LoadBalancerPort":"80",
            "InstancePort": { "Ref": "XqueueServerPort" },
            "Protocol":"HTTP"
          },
          {
            "LoadBalancerPort":"443",
            "InstancePort": { "Ref": "XqueueServerPort" },
            "Protocol":"HTTPS",
            "InstanceProtocol":"HTTP",
            "SSLCertificateId": {
              "Ref": "SSLCertificateARN"
            }
          }
        ],
        "HealthCheck":{
          "Target": { "Fn::Join":[ "",
            [
              "HTTP:",
              { "Ref": "XqueueServerPort" },
              "/xqueue/status/"
            ]
          ]},
          "HealthyThreshold":"3",
          "UnhealthyThreshold":"5",
          "Interval":"30",
          "Timeout":"5"
        },
        "Subnets":[
          {
            "Ref":"PublicSubnet01"
          },
          {
            "Ref":"PublicSubnet02"
          }
        ]
      }
    },
    "XqueueELBSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Enable HTTP access on port 80",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "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"
          }
        ],
        "SecurityGroupEgress":[
          {
            "IpProtocol":"tcp",
            "FromPort": { "Ref": "XqueueServerPort" },
            "ToPort": { "Ref": "XqueueServerPort" },
            "CidrIp":"0.0.0.0/0"
          }
        ]
      }
    },
    "XqueueServerSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Open up SSH access plus Edx Server required ports",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":{
              "Ref":"SSHLocation"
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort": { "Ref": "XqueueServerPort" },
            "ToPort": { "Ref": "XqueueServerPort" },
            "CidrIp":"0.0.0.0/0"
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"xqueue"
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            }
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            }
          }
        ]
      }
    },
    "XqueueServerWaitHandle":{
      "Type":"AWS::CloudFormation::WaitConditionHandle"
    },
    "XqueueServerWaitCondition":{
      "Type":"AWS::CloudFormation::WaitCondition",
      "DependsOn":"XqueueServer",
      "Properties":{
        "Handle":{
          "Ref":"XqueueServerWaitHandle"
        },
        "Timeout":"1200"
      }
    },
    "CommonClusterServer":{
      "Type":"AWS::AutoScaling::LaunchConfiguration",
      "Properties":{
        "SecurityGroups":[
          {
            "Ref":"RabbitMQServerSecurityGroup"
          },
          {
            "Ref":"ElasticsearchServerSecurityGroup"
          }
        ],
        "ImageId":{
          "Fn::FindInMap":[
            "AWSRegionArch2AMI",
            {
              "Ref":"AWS::Region"
            },
            {
              "Fn::FindInMap":[
                "AWSInstanceType2Arch",
                {
                  "Ref":"CommonClusterInstanceType"
                },
                "Arch"
              ]
            }
          ]
        },
        "UserData":{
          "Fn::Base64":{
            "Fn::Join":[
              "",
              [
                "#!/bin/bash -x\n",
                "exec >> /home/ubuntu/cflog.log\n",
                "exec 2>> /home/ubuntu/cflog.log\n",
                "function error_exit\n",
                "{\n",
                "  cfn-signal -e 1 -r \"$1\" '",
                {
                  "Ref":"CommonClusterServerWaitHandle"
                },
                "'\n",
                "  exit 1\n",
                "}\n",
                "apt-get -y update\n",
                "apt-get -y install python-setuptools\n",
                "echo \"Python Tools installed\" - `date` >> /home/ubuntu/cflog.txt\n",
                "easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
                "echo \"Cloudformation Boostrap installed \" - `date` >> /home/ubuntu/cflog.txt\n",
                "# If all went well, signal success\n",
                "cfn-signal -e $? -r 'Edx Server configuration' '",
                {
                  "Ref":"CommonClusterServerWaitHandle"
                },
                "'\n"
              ]
            ]
          }
        },
        "KeyName":{
          "Ref":"KeyName"
        },
        "InstanceType":{
          "Ref":"CommonClusterInstanceType"
        },
        "BlockDeviceMappings":[
          {
            "DeviceName":"/dev/xvdc",
            "Ebs":{
              "VolumeSize":"50"
            }
          },
          {
            "DeviceName":"/dev/xvdd",
            "Ebs":{
              "VolumeSize":"50"
            }
          }
        ]
      }
    },
    "CommonClusterServerASGroup":{
      "Type":"AWS::AutoScaling::AutoScalingGroup",
      "Properties":{
        "AvailabilityZones":[
          {
            "Fn::GetAtt":[
              "CommonClusterSubnet01",
              "AvailabilityZone"
            ]
          },
          {
            "Fn::GetAtt":[
              "CommonClusterSubnet02",
              "AvailabilityZone"
            ]
          },
          {
            "Fn::GetAtt":[
              "CommonClusterSubnet03",
              "AvailabilityZone"
            ]
          }
        ],
        "VPCZoneIdentifier":[
          {
            "Ref":"CommonClusterSubnet01"
          },
          {
            "Ref":"CommonClusterSubnet02"
          },
          {
            "Ref":"CommonClusterSubnet03"
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"commoncluster",
            "PropagateAtLaunch":true
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            },
            "PropagateAtLaunch":true
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            },
            "PropagateAtLaunch":true
          }
        ],
        "LaunchConfigurationName":{
          "Ref":"CommonClusterServer"
        },
        "MinSize":{
          "Ref":"CommonClusterDesiredCapacity"
        },
        "MaxSize":{
          "Ref":"CommonClusterDesiredCapacity"
        },
        "DesiredCapacity":{
          "Ref":"CommonClusterDesiredCapacity"
        },
        "LoadBalancerNames":[
          {
            "Ref":"RabbitMQELB"
          },
          {
            "Ref":"ElasticSearchELB"
          }
        ]
      }
    },
    "CommonClusterCPUAlarmHigh":{
      "Type":"AWS::CloudWatch::Alarm",
      "Properties":{
        "AlarmDescription":"Alarm if CPU > 90% for 10 minutes",
        "MetricName":"CPUUtilization",
        "Namespace":"AWS/EC2",
        "Statistic":"Average",
        "Period":"300",
        "EvaluationPeriods":"2",
        "Threshold":"90",
        "AlarmActions":[],
        "Dimensions":[
          {
            "Name":"AutoScalingGroupName",
            "Value":{
              "Ref":"CommonClusterServerASGroup"
            }
          }
        ],
        "ComparisonOperator":"GreaterThanThreshold"
      }
    },
    "CommonClusterCPUAlarmLow":{
      "Type":"AWS::CloudWatch::Alarm",
      "Properties":{
        "AlarmDescription":"Alarm if CPU < 70% for 10 minutes",
        "MetricName":"CPUUtilization",
        "Namespace":"AWS/EC2",
        "Statistic":"Average",
        "Period":"300",
        "EvaluationPeriods":"2",
        "Threshold":"70",
        "AlarmActions":[],
        "Dimensions":[
          {
            "Name":"AutoScalingGroupName",
            "Value":{
              "Ref":"CommonClusterServerASGroup"
            }
          }
        ],
        "ComparisonOperator":"LessThanThreshold"
      }
    },
    "ElasticSearchELB":{
      "Type":"AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties":{
        "Scheme":"internal",
        "SecurityGroups":[
          {
            "Ref":"ElasticSearchELBSecurityGroup"
          }
        ],
        "Listeners":[
          {
            "LoadBalancerPort":"9200",
            "InstancePort":"9200",
            "Protocol":"TCP"
          },
          {
            "LoadBalancerPort":"9300",
            "InstancePort":"9300",
            "Protocol":"TCP"
          }
        ],
        "HealthCheck":{
          "Target":"TCP:9200",
          "HealthyThreshold":"3",
          "UnhealthyThreshold":"5",
          "Interval":"30",
          "Timeout":"5"
        },
        "Subnets":[
          {
            "Ref":"CommonClusterSubnet01"
          },
          {
            "Ref":"CommonClusterSubnet02"
          },
          {
            "Ref":"CommonClusterSubnet03"
          }
        ]
      }
    },
    "ElasticSearchELBSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Enable TCP access on elasticsearch ports",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"9200",
            "ToPort":"9200",
            "CidrIp":"10.0.0.0/16"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"9300",
            "ToPort":"9300",
            "CidrIp":"10.0.0.0/16"
          }
        ],
        "SecurityGroupEgress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"9200",
            "ToPort":"9200",
            "CidrIp":"10.0.0.0/16"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"9300",
            "ToPort":"9300",
            "CidrIp":"10.0.0.0/16"
          }
        ]
      }
    },
    "ElasticsearchServerSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Open up SSH access plus Edx Server required ports",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":{
              "Ref":"SSHLocation"
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort": 9200,
            "ToPort": 9200,
            "CidrIp":"10.0.0.0/16"
          },
          {
            "IpProtocol":"tcp",
            "FromPort": 9300,
            "ToPort": 9300,
            "CidrIp":"10.0.0.0/16"
          }
        ]
      }
    },
    "RabbitMQELB":{
      "Type":"AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties":{
        "Scheme":"internal",
        "SecurityGroups":[
          {
            "Ref":"RabbitMQELBSecurityGroup"
          }
        ],
        "Listeners":[
          {
            "LoadBalancerPort":"5672",
            "InstancePort":"5672",
            "Protocol":"TCP"
          },
          {
            "LoadBalancerPort":"6163",
            "InstancePort":"6163",
            "Protocol":"TCP"
          }
        ],
        "HealthCheck":{
          "Target":"TCP:5672",
          "HealthyThreshold":"3",
          "UnhealthyThreshold":"5",
          "Interval":"30",
          "Timeout":"5"
        },
        "Subnets":[
          {
            "Ref":"CommonClusterSubnet01"
          },
          {
            "Ref":"CommonClusterSubnet02"
          },
          {
            "Ref":"CommonClusterSubnet03"
          }
        ]
      }
    },
    "RabbitMQELBSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Enable TCP access on rabbit ports",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"5672",
            "ToPort":"5672",
            "CidrIp":"10.0.0.0/16"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"6163",
            "ToPort":"6163",
            "CidrIp":"10.0.0.0/16"
          }
        ],
        "SecurityGroupEgress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"5672",
            "ToPort":"5672",
            "CidrIp":"10.0.0.0/16"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"6163",
            "ToPort":"6163",
            "CidrIp":"10.0.0.0/16"
          }
        ]
      }
    },
    "RabbitMQServerSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Open up SSH access plus Edx Server required ports",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":"10.0.0.0/16"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"5672",
            "ToPort":"5672",
            "SourceSecurityGroupId" : {
                "Ref" : "RabbitMQELBSecurityGroup"
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"6163",
            "ToPort":"6163",
            "SourceSecurityGroupId" : {
                "Ref" : "RabbitMQELBSecurityGroup" 
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"5672",
            "ToPort":"5672",
            "SourceSecurityGroupId" : {
                "Ref" : "XqueueServerSecurityGroup"
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"6163",
            "ToPort":"6163",
            "SourceSecurityGroupId" : {
                "Ref" : "XqueueServerSecurityGroup"
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"0",
            "ToPort":"65535",
            "CidrIp":"10.0.0.0/16"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"15672",
            "ToPort":"15672",
            "SourceSecurityGroupId" : {
                "Ref" : "BastionSecurityGroup"
            }
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"rabbitmq"
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            }
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            }
          }
        ]
      }
    },
    "CommonClusterServerWaitHandle":{
      "Type":"AWS::CloudFormation::WaitConditionHandle"
    },
    "CommonClusterServerWaitCondition":{
      "Type":"AWS::CloudFormation::WaitCondition",
      "DependsOn":"CommonClusterServer",
      "Properties":{
        "Handle":{
          "Ref":"CommonClusterServerWaitHandle"
        },
        "Timeout":"1200"
      }
    },
    "XServer":{
      "Type":"AWS::AutoScaling::LaunchConfiguration",
      "Properties":{
        "IamInstanceProfile":{ "Ref":"XServerInstanceProfile" },
        "SecurityGroups":[
          {
            "Ref":"XServerSecurityGroup"
          }
        ],
        "ImageId":{
          "Fn::FindInMap":[
            "AWSRegionArch2AMI",
            {
              "Ref":"AWS::Region"
            },
            {
              "Fn::FindInMap":[
                "AWSInstanceType2Arch",
                {
                  "Ref":"XserverInstanceType"
                },
                "Arch"
              ]
            }
          ]
        },
        "UserData":{
          "Fn::Base64":{
            "Fn::Join":[
              "",
              [
                "#!/bin/bash -x\n",
                "exec >> /home/ubuntu/cflog.log\n",
                "exec 2>> /home/ubuntu/cflog.log\n",
                "function error_exit\n",
                "{\n",
                "  cfn-signal -e 1 -r \"$1\" '",
                {
                  "Ref":"XServerWaitHandle"
                },
                "'\n",
                "  exit 1\n",
                "}\n",
                "apt-get -y update\n",
                "apt-get -y install python-setuptools\n",
                "echo \"Python Tools installed\" - `date` >> /home/ubuntu/cflog.txt\n",
                "easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
                "echo \"Cloudformation Boostrap installed \" - `date` >> /home/ubuntu/cflog.txt\n",
                "# If all went well, signal success\n",
                "cfn-signal -e $? -r 'Edx Server configuration' '",
                {
                  "Ref":"XServerWaitHandle"
                },
                "'\n"
              ]
            ]
          }
        },
        "KeyName":{
          "Ref":"KeyName"
        },
        "InstanceType":{
          "Ref":"XserverInstanceType"
        },
        "BlockDeviceMappings":[
          {
            "DeviceName":"/dev/xvdc",
            "Ebs":{
              "VolumeSize":"50"
            }
          },
          {
            "DeviceName":"/dev/xvdd",
            "Ebs":{
              "VolumeSize":"50"
            }
          }
        ]
      }
    },
    "XServerASGroup":{
      "Type":"AWS::AutoScaling::AutoScalingGroup",
      "Properties":{
        "AvailabilityZones":[
          {
            "Fn::GetAtt":[
              "XServerSubnet01",
              "AvailabilityZone"
            ]
          },
          {
            "Fn::GetAtt":[
              "XServerSubnet02",
              "AvailabilityZone"
            ]
          }
        ],
        "VPCZoneIdentifier":[
          {
            "Ref":"XServerSubnet01"
          },
          {
            "Ref":"XServerSubnet02"
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"xserver",
            "PropagateAtLaunch":true
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            },
            "PropagateAtLaunch":true
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            },
            "PropagateAtLaunch":true
          }
        ],
        "LaunchConfigurationName":{
          "Ref":"XServer"
        },
        "MinSize":{
          "Ref":"XServerDesiredCapacity"
        },
        "MaxSize":{
          "Ref":"XServerDesiredCapacity"
        },
        "DesiredCapacity":{
          "Ref":"XServerDesiredCapacity"
        },
        "LoadBalancerNames":[
          {
            "Ref":"XServerELB"
          }
        ]
      }
    },
    "XServerScaleUpPolicy":{
      "Type":"AWS::AutoScaling::ScalingPolicy",
      "Properties":{
        "AdjustmentType":"ChangeInCapacity",
        "AutoScalingGroupName":{
          "Ref":"XServerASGroup"
        },
        "Cooldown":"60",
        "ScalingAdjustment":"1"
      }
    },
    "XServerScaleDownPolicy":{
      "Type":"AWS::AutoScaling::ScalingPolicy",
      "Properties":{
        "AdjustmentType":"ChangeInCapacity",
        "AutoScalingGroupName":{
          "Ref":"XServerASGroup"
        },
        "Cooldown":"60",
        "ScalingAdjustment":"-1"
      }
    },
    "XServerCPUAlarmHigh":{
      "Type":"AWS::CloudWatch::Alarm",
      "Properties":{
        "AlarmDescription":"Scale-up if CPU > 90% for 10 minutes",
        "MetricName":"CPUUtilization",
        "Namespace":"AWS/EC2",
        "Statistic":"Average",
        "Period":"300",
        "EvaluationPeriods":"2",
        "Threshold":"90",
        "AlarmActions":[
          {
            "Ref":"XServerScaleUpPolicy"
          }
        ],
        "Dimensions":[
          {
            "Name":"AutoScalingGroupName",
            "Value":{
              "Ref":"XServerASGroup"
            }
          }
        ],
        "ComparisonOperator":"GreaterThanThreshold"
      }
    },
    "XServerCPUAlarmLow":{
      "Type":"AWS::CloudWatch::Alarm",
      "Properties":{
        "AlarmDescription":"Scale-down if CPU < 70% for 10 minutes",
        "MetricName":"CPUUtilization",
        "Namespace":"AWS/EC2",
        "Statistic":"Average",
        "Period":"300",
        "EvaluationPeriods":"2",
        "Threshold":"70",
        "AlarmActions":[
          {
            "Ref":"XServerScaleDownPolicy"
          }
        ],
        "Dimensions":[
          {
            "Name":"AutoScalingGroupName",
            "Value":{
              "Ref":"XServerASGroup"
            }
          }
        ],
        "ComparisonOperator":"LessThanThreshold"
      }
    },
    "XServerELB":{
      "Type":"AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties":{
        "Scheme":"internal",
        "SecurityGroups":[
          {
            "Ref":"XServerELBSecurityGroup"
          }
        ],
        "Listeners":[
          {
            "LoadBalancerPort":"80",
            "InstancePort":{ "Ref": "XserverServerPort" },
            "Protocol":"HTTP"
          }
        ],
        "HealthCheck":{
          "Target": { "Fn::Join":[ "",
            [
              "HTTP:",
              { "Ref": "XserverServerPort" },
              "/"
            ]
          ]},
          "HealthyThreshold":"3",
          "UnhealthyThreshold":"5",
          "Interval":"30",
          "Timeout":"5"
        },
        "Subnets":[
          {
            "Ref":"XServerSubnet01"
          },
          {
            "Ref":"XServerSubnet02"
          }
        ]
      }
    },
    "XServerELBSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Enable TCP access on xserver ports",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"80",
            "ToPort":"80",
            "CidrIp":"10.0.0.0/16"
          }
        ],
        "SecurityGroupEgress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"80",
            "ToPort":"80",
            "CidrIp":"10.0.0.0/16"
          }
        ]
      }
    },
    "XServerSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Open up SSH access plus XServer required ports",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":"10.0.0.0/16"
          },
          {
            "IpProtocol":"tcp",
            "FromPort": { "Ref": "XserverServerPort" },
            "ToPort": { "Ref": "XserverServerPort" },
            "CidrIp":"10.0.0.0/16"
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"80",
            "ToPort":"80",
            "SourceSecurityGroupId" : { 
                "Ref" : "XServerELBSecurityGroup" 
            }
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"xserver"
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            }
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            }
          }
        ]
      }
    },
    "XServerWaitHandle":{
      "Type":"AWS::CloudFormation::WaitConditionHandle"
    },
    "XServerWaitCondition":{
      "Type":"AWS::CloudFormation::WaitCondition",
      "DependsOn":"XServer",
      "Properties":{
        "Handle":{
          "Ref":"XServerWaitHandle"
        },
        "Timeout":"1200"
      }
    },
    "EdxDataSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Open up access to the data subnet",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"3306",
            "ToPort":"3306",
            "CidrIp":"0.0.0.0/0"
          }
        ]
      }
    },
    "EdxDBSubnetGroup":{
      "Type":"AWS::RDS::DBSubnetGroup",
      "Properties":{
        "DBSubnetGroupDescription":"Subnets available for the RDS DB Instance",
        "SubnetIds":[
          {
            "Ref":"Data01"
          },
          {
            "Ref":"Data02"
          }
        ]
      }
    },
    "DBSecurityGroup":{
      "Type":"AWS::RDS::DBSecurityGroup",
      "Properties":{
        "EC2VpcId":{
          "Ref":"EdxVPC"
        },
        "DBSecurityGroupIngress":[
          {
            "EC2SecurityGroupId":{
              "Ref":"EdxappServerSecurityGroup"
            }
          },
          {
            "EC2SecurityGroupId":{
              "Ref":"WorkerServerSecurityGroup"
            }
          },
          {
            "EC2SecurityGroupId":{
              "Ref":"XqueueServerSecurityGroup"
            }
          }
        ],
        "GroupDescription":"Data access"
      }
    },
    "EdxDB":{
      "Type":"AWS::RDS::DBInstance",
      "Properties":{
        "DBName":{
          "Ref":"DBName"
        },
        "AllocatedStorage":{
          "Ref":"DBAllocatedStorage"
        },
        "DBInstanceClass":{
          "Ref":"DBClass"
        },
        "Engine":"MySQL",
        "EngineVersion":{ "Ref": "DBEngineVersion" },
        "MasterUsername":{
          "Ref":"DBUsername"
        },
        "MasterUserPassword":{
          "Ref":"DBPassword"
        },
        "DBSubnetGroupName":{
          "Ref":"EdxDBSubnetGroup"
        },
        "DBSecurityGroups":[
          {
            "Ref":"DBSecurityGroup"
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"rds"
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            }
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            }
          }
        ],
        "MultiAZ":"true"
      }
    },
    "CacheSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Access to the elastic cache cluster",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort": { "Ref":"CacheNodePort" },
            "ToPort": { "Ref":"CacheNodePort" },
            "SourceSecurityGroupId":{
              "Ref":"EdxappServerSecurityGroup"
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort": { "Ref":"CacheNodePort" },
            "ToPort": { "Ref":"CacheNodePort" },
            "SourceSecurityGroupId":{
              "Ref":"WorkerServerSecurityGroup"
            }
          }
        ]
      }
    },
    "WorkerServer":{
      "Type":"AWS::AutoScaling::LaunchConfiguration",
      "Properties":{
        "SecurityGroups":[
          {
            "Ref":"WorkerServerSecurityGroup"
          }
        ],
        "ImageId":{
          "Fn::FindInMap":[
            "AWSRegionArch2AMI",
            {
              "Ref":"AWS::Region"
            },
            {
              "Fn::FindInMap":[
                "AWSInstanceType2Arch",
                {
                  "Ref":"WorkerInstanceType"
                },
                "Arch"
              ]
            }
          ]
        },
        "UserData":{
          "Fn::Base64":{
            "Fn::Join":[
              "",
              [
                "#!/bin/bash -x\n",
                "exec >> /home/ubuntu/cflog.log\n",
                "exec 2>> /home/ubuntu/cflog.log\n",
                "function error_exit\n",
                "{\n",
                "  cfn-signal -e 1 -r \"$1\" '",
                {
                  "Ref":"WorkerServerWaitHandle"
                },
                "'\n",
                "  exit 1\n",
                "}\n",
                "for dev in /dev/xvdc /dev/xvdd; do sudo echo w | fdisk $dev; sudo mkfs -t ext4 $dev;done;\n",
                "sudo mkdir /mnt/logs\n",
                "sudo mount /dev/xvdc /mnt/logs\n",
                "sudo mount /dev/xvdd /opt\n",
                "apt-get -y update\n",
                "apt-get -y install python-setuptools\n",
                "echo \"Python Tools installed\" - `date` >> /home/ubuntu/cflog.txt\n",
                "easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
                "echo \"Cloudformation Boostrap installed \" - `date` >> /home/ubuntu/cflog.txt\n",
                "# If all went well, signal success\n",
                "cfn-signal -e $? -r 'Edx Server configuration' '",
                {
                  "Ref":"WorkerServerWaitHandle"
                },
                "'\n"
              ]
            ]
          }
        },
        "KeyName":{
          "Ref":"KeyName"
        },
        "InstanceType":{
          "Ref":"WorkerInstanceType"
        },
        "BlockDeviceMappings":[
          {
            "DeviceName":"/dev/xvdc",
            "Ebs":{
              "VolumeSize":"50"
            }
          },
          {
            "DeviceName":"/dev/xvdd",
            "Ebs":{
              "VolumeSize":"50"
            }
          }
        ]
      }
    },
    "WorkerServerASGroup":{
      "Type":"AWS::AutoScaling::AutoScalingGroup",
      "Properties":{
        "AvailabilityZones":[
          {
            "Fn::GetAtt":[
              "WorkerSubnet01",
              "AvailabilityZone"
            ]
          },
          {
            "Fn::GetAtt":[
              "WorkerSubnet02",
              "AvailabilityZone"
            ]
          }
        ],
        "VPCZoneIdentifier":[
          {
            "Ref":"WorkerSubnet01"
          },
          {
            "Ref":"WorkerSubnet02"
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"worker",
            "PropagateAtLaunch":true
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            },
            "PropagateAtLaunch":true
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            },
            "PropagateAtLaunch":true
          }
        ],
        "LaunchConfigurationName":{
          "Ref":"WorkerServer"
        },
        "MinSize":{
          "Ref":"WorkerDesiredCapacity"
        },
        "MaxSize":{
          "Ref":"WorkerDesiredCapacity"
        },
        "DesiredCapacity":{
          "Ref":"WorkerDesiredCapacity"
        }
      }
    },
    "WorkerServerScaleUpPolicy":{
      "Type":"AWS::AutoScaling::ScalingPolicy",
      "Properties":{
        "AdjustmentType":"ChangeInCapacity",
        "AutoScalingGroupName":{
          "Ref":"WorkerServerASGroup"
        },
        "Cooldown":"60",
        "ScalingAdjustment":"1"
      }
    },
    "WorkerServerScaleDownPolicy":{
      "Type":"AWS::AutoScaling::ScalingPolicy",
      "Properties":{
        "AdjustmentType":"ChangeInCapacity",
        "AutoScalingGroupName":{
          "Ref":"WorkerServerASGroup"
        },
        "Cooldown":"60",
        "ScalingAdjustment":"-1"
      }
    },
    "WorkerCPUAlarmHigh":{
      "Type":"AWS::CloudWatch::Alarm",
      "Properties":{
        "AlarmDescription":"Scale-up if CPU > 90% for 10 minutes",
        "MetricName":"CPUUtilization",
        "Namespace":"AWS/EC2",
        "Statistic":"Average",
        "Period":"300",
        "EvaluationPeriods":"2",
        "Threshold":"90",
        "AlarmActions":[
          {
            "Ref":"WorkerServerScaleUpPolicy"
          }
        ],
        "Dimensions":[
          {
            "Name":"AutoScalingGroupName",
            "Value":{
              "Ref":"WorkerServerASGroup"
            }
          }
        ],
        "ComparisonOperator":"GreaterThanThreshold"
      }
    },
    "WorkerCPUAlarmLow":{
      "Type":"AWS::CloudWatch::Alarm",
      "Properties":{
        "AlarmDescription":"Scale-down if CPU < 70% for 10 minutes",
        "MetricName":"CPUUtilization",
        "Namespace":"AWS/EC2",
        "Statistic":"Average",
        "Period":"300",
        "EvaluationPeriods":"2",
        "Threshold":"70",
        "AlarmActions":[
          {
            "Ref":"WorkerServerScaleDownPolicy"
          }
        ],
        "Dimensions":[
          {
            "Name":"AutoScalingGroupName",
            "Value":{
              "Ref":"WorkerServerASGroup"
            }
          }
        ],
        "ComparisonOperator":"LessThanThreshold"
      }
    },
    "WorkerServerSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Open up SSH access plus Edx Server required ports",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":{
              "Ref":"SSHLocation"
            }
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"worker"
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            }
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            }
          }
        ]
      }
    },
    "WorkerServerWaitHandle":{
      "Type":"AWS::CloudFormation::WaitConditionHandle"
    },
    "WorkerServerWaitCondition":{
      "Type":"AWS::CloudFormation::WaitCondition",
      "DependsOn":"WorkerServer",
      "Properties":{
        "Handle":{
          "Ref":"WorkerServerWaitHandle"
        },
        "Timeout":"1200"
      }
    },
    "ForumServer":{
      "Type":"AWS::AutoScaling::LaunchConfiguration",
      "Properties":{
        "SecurityGroups":[
          {
            "Ref":"ForumServerSecurityGroup"
          }
        ],
        "ImageId":{
          "Fn::FindInMap":[
            "AWSRegionArch2AMI",
            {
              "Ref":"AWS::Region"
            },
            {
              "Fn::FindInMap":[
                "AWSInstanceType2Arch",
                {
                  "Ref":"ForumInstanceType"
                },
                "Arch"
              ]
            }
          ]
        },
        "UserData":{
          "Fn::Base64":{
            "Fn::Join":[
              "",
              [
                "#!/bin/bash -x\n",
                "exec >> /home/ubuntu/cflog.log\n",
                "exec 2>> /home/ubuntu/cflog.log\n",
                "function error_exit\n",
                "{\n",
                "  cfn-signal -e 1 -r \"$1\" '",
                {
                  "Ref":"ForumServerWaitHandle"
                },
                "'\n",
                "  exit 1\n",
                "}\n",
                "for dev in /dev/xvdc /dev/xvdd; do sudo echo w | fdisk $dev; sudo mkfs -t ext4 $dev;done;\n",
                "sudo mkdir /mnt/logs\n",
                "sudo mount /dev/xvdc /mnt/logs\n",
                "sudo mount /dev/xvdd /opt\n",
                "apt-get -y update\n",
                "apt-get -y install python-setuptools\n",
                "echo \"Python Tools installed\" - `date` >> /home/ubuntu/cflog.txt\n",
                "easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
                "echo \"Cloudformation Boostrap installed \" - `date` >> /home/ubuntu/cflog.txt\n",
                "# If all went well, signal success\n",
                "cfn-signal -e $? -r 'Edx Server configuration' '",
                {
                  "Ref":"ForumServerWaitHandle"
                },
                "'\n"
              ]
            ]
          }
        },
        "KeyName":{
          "Ref":"KeyName"
        },
        "InstanceType":{
          "Ref":"ForumInstanceType"
        },
        "BlockDeviceMappings":[
          {
            "DeviceName":"/dev/xvdc",
            "Ebs":{
              "VolumeSize":"50"
            }
          },
          {
            "DeviceName":"/dev/xvdd",
            "Ebs":{
              "VolumeSize":"50"
            }
          }
        ]
      }
    },
    "ForumServerASGroup":{
      "Type":"AWS::AutoScaling::AutoScalingGroup",
      "Properties":{
        "AvailabilityZones":[
          {
            "Fn::GetAtt":[
              "ForumSubnet01",
              "AvailabilityZone"
            ]
          },
          {
            "Fn::GetAtt":[
              "ForumSubnet02",
              "AvailabilityZone"
            ]
          }
        ],
        "VPCZoneIdentifier":[
          {
            "Ref":"ForumSubnet01"
          },
          {
            "Ref":"ForumSubnet02"
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"forum",
            "PropagateAtLaunch":true
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            },
            "PropagateAtLaunch":true
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            },
            "PropagateAtLaunch":true
          }
        ],
        "LaunchConfigurationName":{
          "Ref":"ForumServer"
        },
        "MinSize":{
          "Ref":"ForumDesiredCapacity"
        },
        "MaxSize":{
          "Ref":"ForumDesiredCapacity"
        },
        "DesiredCapacity":{
          "Ref":"ForumDesiredCapacity"
        },
        "LoadBalancerNames":[
          {
            "Ref":"ForumELB"
          }
        ]
      }
    },
    "ForumServerScaleUpPolicy":{
      "Type":"AWS::AutoScaling::ScalingPolicy",
      "Properties":{
        "AdjustmentType":"ChangeInCapacity",
        "AutoScalingGroupName":{
          "Ref":"ForumServerASGroup"
        },
        "Cooldown":"60",
        "ScalingAdjustment":"1"
      }
    },
    "ForumServerScaleDownPolicy":{
      "Type":"AWS::AutoScaling::ScalingPolicy",
      "Properties":{
        "AdjustmentType":"ChangeInCapacity",
        "AutoScalingGroupName":{
          "Ref":"ForumServerASGroup"
        },
        "Cooldown":"60",
        "ScalingAdjustment":"-1"
      }
    },
    "ForumCPUAlarmHigh":{
      "Type":"AWS::CloudWatch::Alarm",
      "Properties":{
        "AlarmDescription":"Scale-up if CPU > 90% for 10 minutes",
        "MetricName":"CPUUtilization",
        "Namespace":"AWS/EC2",
        "Statistic":"Average",
        "Period":"300",
        "EvaluationPeriods":"2",
        "Threshold":"90",
        "AlarmActions":[
          {
            "Ref":"ForumServerScaleUpPolicy"
          }
        ],
        "Dimensions":[
          {
            "Name":"AutoScalingGroupName",
            "Value":{
              "Ref":"ForumServerASGroup"
            }
          }
        ],
        "ComparisonOperator":"GreaterThanThreshold"
      }
    },
    "ForumCPUAlarmLow":{
      "Type":"AWS::CloudWatch::Alarm",
      "Properties":{
        "AlarmDescription":"Scale-down if CPU < 70% for 10 minutes",
        "MetricName":"CPUUtilization",
        "Namespace":"AWS/EC2",
        "Statistic":"Average",
        "Period":"300",
        "EvaluationPeriods":"2",
        "Threshold":"70",
        "AlarmActions":[
          {
            "Ref":"ForumServerScaleDownPolicy"
          }
        ],
        "Dimensions":[
          {
            "Name":"AutoScalingGroupName",
            "Value":{
              "Ref":"ForumServerASGroup"
            }
          }
        ],
        "ComparisonOperator":"LessThanThreshold"
      }
    },
    "ForumELB":{
      "Type":"AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties":{
        "SecurityGroups":[
          {
            "Ref":"ForumELBSecurityGroup"
          }
        ],
        "Listeners":[
          {
            "LoadBalancerPort":"443",
            "InstancePort":{
              "Ref":"ForumServerPort"
            },
            "Protocol":"HTTPS",
            "InstanceProtocol":"HTTP",
            "SSLCertificateId": {
              "Ref": "SSLCertificateARN"
            }
          }
        ],
        "HealthCheck":{
          "Target":{"Fn::Join":["",
			       ["TCP:",
				{"Ref":"ForumServerPort"}
			       ]
			      ]
		   },
          "HealthyThreshold":"3",
          "UnhealthyThreshold":"5",
          "Interval":"30",
          "Timeout":"5"
        },
        "Subnets":[
          {
            "Ref":"PublicSubnet01"
          },
          {
            "Ref":"PublicSubnet02"
          }
        ]
      }
    },
    "ForumELBSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Enable HTTPS access",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"443",
            "ToPort":"443",
            "CidrIp":"0.0.0.0/0"
          }
        ],
        "SecurityGroupEgress":[
          {
            "IpProtocol":"tcp",
            "FromPort": { "Ref": "ForumServerPort" },
            "ToPort": { "Ref": "ForumServerPort" },
            "CidrIp":"0.0.0.0/0"
          }
        ]
      }
    },
    "ForumServerSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Open up SSH access plus Edx Server required ports",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":{
              "Ref":"SSHLocation"
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort": { "Ref": "ForumServerPort" },
            "ToPort": { "Ref": "ForumServerPort" },
            "SourceSecurityGroupId" : {
                "Ref" : "ForumELBSecurityGroup"
            }
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"forum"
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            }
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            }
          }
        ]
      }
    },
    "ForumServerWaitHandle":{
      "Type":"AWS::CloudFormation::WaitConditionHandle"
    },
    "ForumServerWaitCondition":{
      "Type":"AWS::CloudFormation::WaitCondition",
      "DependsOn":"ForumServer",
      "Properties":{
        "Handle":{
          "Ref":"ForumServerWaitHandle"
        },
        "Timeout":"1200"
      }
    },
    "MongoServer":{
      "Type":"AWS::AutoScaling::LaunchConfiguration",
      "Properties":{
        "SecurityGroups":[
          {
            "Ref":"MongoServerSecurityGroup"
          }
        ],
        "ImageId":{
          "Fn::FindInMap":[
            "AWSRegionArch2AMI",
            {
              "Ref":"AWS::Region"
            },
            {
              "Fn::FindInMap":[
                "AWSInstanceType2Arch",
                {
                  "Ref":"MongoInstanceType"
                },
                "Arch"
              ]
            }
          ]
        },
        "UserData":{
          "Fn::Base64":{
            "Fn::Join":[
              "",
              [
                "#!/bin/bash -x\n",
                "exec >> /home/ubuntu/cflog.log\n",
                "exec 2>> /home/ubuntu/cflog.log\n",
                "function error_exit\n",
                "{\n",
                "  cfn-signal -e 1 -r \"$1\" '",
                {
                  "Ref":"MongoServerWaitHandle"
                },
                "'\n",
                "  exit 1\n",
                "}\n",
                "apt-get -y update\n",
                "apt-get -y install python-setuptools\n",
                "echo \"Python Tools installed\" - `date` >> /home/ubuntu/cflog.txt\n",
                "easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
                "echo \"Cloudformation Boostrap installed \" - `date` >> /home/ubuntu/cflog.txt\n",

                "#Install lvm2 so we can create logical volumes.\n",
                "apt-get -y install lvm2 mdadm\n",

                "## Waiting for EBS mounts to become available and set their read ahead.\n",
                "for device in xvdh xvdi xvdj xvdk; do\n",
                "  while [ ! -e /dev/$device ]; do echo waiting for /dev/$device to attach; sleep 10; done\n",
                "  blockdev --setra 128 /dev/$device\n",
                "done\n",

                "## Create RAID10 and persist configuration\n",
                "mdadm --verbose --create /dev/md0 --level=10 --chunk=256 --raid-devices=4 /dev/xvdh /dev/xvdi /dev/xvdj /dev/xvdk | tee /tmp/mdadm.log 2>&1\n",
                "echo '`mdadm --detail --scan`' | tee -a /etc/mdadm.conf\n",

                "## Set read-ahead on the new device\n",
                "blockdev --setra 128 /dev/md0\n",

                "## Create physical and logical volumes\n",
                "dd if=/dev/zero of=/dev/md0 bs=512 count=1\n",
                "pvcreate /dev/md0\n",
                "vgcreate vg0 /dev/md0\n",
                "lvcreate -l 90%vg -n data vg0\n",
                "lvcreate -l 5%vg -n log vg0\n",
                "lvcreate -l 5%vg -n journal vg0\n",

                "## Create filesystems and mount point info\n",
                "mke2fs -t ext4 -F /dev/vg0/data > /tmp/mke2fs1.log 2>&1\n",
                "mke2fs -t ext4 -F /dev/vg0/log > /tmp/mke2fs2.log 2>&1\n",
                "mke2fs -t ext4 -F /dev/vg0/journal > /tmp/mke2fs3.log 2>&1\n",

                "mkdir -p /edx/var/mongo/data\n",
                "mkdir -p /edx/var/log/mongo\n",
                "mkdir -p /edx/var/mongo/journal\n",

                "echo '/dev/vg0/data /edx/var/mongo/data ext4 defaults,auto,noatime,noexec 0 0' | tee -a /etc/fstab\n",
                "echo '/dev/vg0/log /edx/var/log/mongo ext4 defaults,auto,noatime,noexec 0 0' | tee -a /etc/fstab\n",
                "echo '/dev/vg0/journal /edx/var/mongo/journal ext4 defaults,auto,noatime,noexec 0 0' | tee -a /etc/fstab\n",
                "mount /edx/var/mongo/data > /tmp/mount1.log 2>&1\n",
                "mount /edx/var/log/mongo > /tmp/mount2.log 2>&1\n",
                "mount /edx/var/mongo/journal > /tmp/mount3.log 2>&1\n",

                "ln -s /edx/var/mongo/journal /edx/var/mongo/data/journal\n",

                "# If all went well, signal success\n",
                "cfn-signal -e $? -r 'Edx Mongo configuration' '",
                {
                  "Ref":"MongoServerWaitHandle"
                },
                "'\n"
              ]
            ]
          }
        },
        "KeyName":{
          "Ref":"KeyName"
        },
        "InstanceType":{
          "Ref":"MongoInstanceType"
        },
        "BlockDeviceMappings":[
          {
            "DeviceName":"/dev/xvdh",
            "Ebs":{
              "VolumeSize": { "Ref":"MongoVolumeSize" }
            }
          },
          {
            "DeviceName":"/dev/xvdi",
            "Ebs":{
              "VolumeSize": { "Ref":"MongoVolumeSize" }
            }
          },
          {
            "DeviceName":"/dev/xvdj",
            "Ebs":{
              "VolumeSize": { "Ref":"MongoVolumeSize" }
            }
          },
          {
            "DeviceName":"/dev/xvdk",
            "Ebs":{
              "VolumeSize": { "Ref":"MongoVolumeSize" }
            }
          }
        ]
      }
    },
    "MongoServerASGroup":{
      "Type":"AWS::AutoScaling::AutoScalingGroup",
      "Properties":{
        "AvailabilityZones":[
          {
            "Fn::GetAtt":[
              "MongoSubnet01",
              "AvailabilityZone"
            ]
          },
          {
            "Fn::GetAtt":[
              "MongoSubnet02",
              "AvailabilityZone"
            ]
          },
          {
            "Fn::GetAtt":[
              "MongoSubnet03",
              "AvailabilityZone"
            ]
          }
        ],
        "VPCZoneIdentifier":[
          {
            "Ref":"MongoSubnet01"
          },
          {
            "Ref":"MongoSubnet02"
          },
          {
            "Ref":"MongoSubnet03"
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"mongo",
            "PropagateAtLaunch":true
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            },
            "PropagateAtLaunch":true
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            },
            "PropagateAtLaunch":true
          }
        ],
        "LaunchConfigurationName":{
          "Ref":"MongoServer"
        },
        "MinSize":{
          "Ref":"MongoDesiredCapacity"
        },
        "MaxSize":{
          "Ref":"MongoDesiredCapacity"
        },
        "DesiredCapacity":{
          "Ref":"MongoDesiredCapacity"
        }
      }
    },
    "MongoServerSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Open up SSH access plus Edx Server required ports",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":{
              "Ref":"SSHLocation"
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"27017",
            "ToPort":"27017",
            "SourceSecurityGroupId": { "Ref": "EdxappServerSecurityGroup" }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"28017",
            "ToPort":"28017",
            "SourceSecurityGroupId": { "Ref": "EdxappServerSecurityGroup" }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"27017",
            "ToPort":"27017",
            "SourceSecurityGroupId": { "Ref": "WorkerServerSecurityGroup" }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"28017",
            "ToPort":"28017",
            "SourceSecurityGroupId": { "Ref": "WorkerServerSecurityGroup" }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"27017",
            "ToPort":"27017",
            "SourceSecurityGroupId": { "Ref": "ForumServerSecurityGroup" }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"28017",
            "ToPort":"28017",
            "SourceSecurityGroupId": { "Ref": "ForumServerSecurityGroup" }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"27017",
            "ToPort":"27017",
            "CidrIp":{
              "Fn::FindInMap":[
                "SubnetConfig",
                "Mongo01",
                "CIDR"
              ]
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"28017",
            "ToPort":"28017",
            "CidrIp":{
              "Fn::FindInMap":[
                "SubnetConfig",
                "Mongo01",
                "CIDR"
              ]
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"27017",
            "ToPort":"27017",
            "CidrIp":{
              "Fn::FindInMap":[
                "SubnetConfig",
                "Mongo02",
                "CIDR"
              ]
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"28017",
            "ToPort":"28017",
            "CidrIp":{
              "Fn::FindInMap":[
                "SubnetConfig",
                "Mongo02",
                "CIDR"
              ]
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"27017",
            "ToPort":"27017",
            "CidrIp":{
              "Fn::FindInMap":[
                "SubnetConfig",
                "Mongo03",
                "CIDR"
              ]
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":"28017",
            "ToPort":"28017",
            "CidrIp":{
              "Fn::FindInMap":[
                "SubnetConfig",
                "Mongo03",
                "CIDR"
              ]
            }
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"mongo"
          },
          {
            "Key":"environment",
            "Value":{
              "Ref":"EnvironmentTag"
            }
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            }
          }
        ]
      }
    },
    "MongoServerWaitHandle":{
      "Type":"AWS::CloudFormation::WaitConditionHandle"
    },
    "MongoServerWaitCondition":{
      "Type":"AWS::CloudFormation::WaitCondition",
      "DependsOn":"MongoServer",
      "Properties":{
        "Handle":{
          "Ref":"MongoServerWaitHandle"
        },
        "Timeout":"2400"
      }
    },
    "CacheSubnetGroup" : {
        "Type" : "AWS::ElastiCache::SubnetGroup",
        "Properties" : {
            "Description" : "Cache Subnet Group",
            "SubnetIds" : [ { "Ref" : "Cache01" }, { "Ref" : "Cache02" }  ]
        }
    },
    "CacheCluster" : {
      "Type": "AWS::ElastiCache::CacheCluster",
      "Properties": {
        "NumCacheNodes"        : { "Ref" : "NumberOfCacheNodes" },
        "CacheNodeType"        : { "Ref" : "CacheNodeType" },
        "Engine"               : "memcached",
        "EngineVersion": "1.4.5",
        "Port": { "Ref": "CacheNodePort" },
        "PreferredAvailabilityZone": { "Fn::FindInMap":[
            "MapRegionsToAvailZones",
            { "Ref":"AWS::Region" },
            "AZone0"
          ]
        },
        "CacheParameterGroupName": "default.memcached1.4",
        "AutoMinorVersionUpgrade": true,
        "CacheSubnetGroupName" : { "Ref" : "CacheSubnetGroup" },
        "VpcSecurityGroupIds"  : [ { "Ref" : "CacheSecurityGroup" } ]
      }
    },
		"NotifierRole": {
				"Type": "AWS::IAM::Role",
        "Properties": {
						"AssumeRolePolicyDocument": {
								"Statement": [ {
										"Effect": "Allow",
										"Principal": {
												"Service": [ "ec2.amazonaws.com" ]
										},
										"Action": [ "sts:AssumeRole" ]
								} ]
            },
            "Path": "/",
            "Policies": [ {
              "PolicyName": "NotifierBasePolicy",
              "PolicyDocument": {
                "Statement":[
                  {
                    "Effect":"Allow",
                    "Action":[
                      "cloudformation:DescribeStackResource",
                      "s3:Put",
                      "ses:SendEmail",
                      "ses:SendRawEmail",
                      "ses:GetSendQuota"
                    ],
                    "Resource":"*"
                  }
                ]
              }
            } ]
        }
    },
	  "NotifierInstanceProfile": {
        "Type": "AWS::IAM::InstanceProfile",
        "Properties": {
            "Path": "/",
            "Roles": [ {
								"Ref": "NotifierRole"
            } ]
        }
    },
    "NotifierHost":{
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "InstanceType":{
          "Ref":"NotifierInstanceType"
        },
        "KeyName":{
          "Ref":"KeyName"
        },
        "IamInstanceProfile" : {
          "Ref" : "NotifierInstanceProfile"
        },
        "SubnetId":{
          "Ref":"NotifierSubnet01"
        },
        "ImageId":{
          "Fn::FindInMap":[
            "AWSRegionArch2AMI",
            {
              "Ref":"AWS::Region"
            },
            {
              "Fn::FindInMap":[
                "AWSInstanceType2Arch",
                {
                  "Ref":"NotifierInstanceType"
                },
                "Arch"
              ]
            }
          ]
        },
        "SecurityGroupIds":[
          {
            "Ref":"NotifierSecurityGroup"
          }
        ],
        "Tags":[
          {
            "Key":"play",
            "Value":"notifier"
          },
          {
            "Key":"deployment",
            "Value":{
              "Ref":"DeploymentTag"
            },
            "PropagateAtLaunch":true
          }
        ],
        "UserData":{
          "Fn::Base64":{
            "Fn::Join":[
              "",
              [
                "#!/bin/bash -x\n",
                "exec >> /home/ubuntu/cflog.log\n",
                "exec 2>> /home/ubuntu/cflog.log\n",
                "function error_exit\n",
                "{\n",
                "  cfn-signal -e 1 -r \"$1\" '",
                {
                  "Ref":"NotifierServerWaitHandle"
                },
                "'\n",
                "  exit 1\n",
                "}\n",
                "apt-get -y update\n",
                "apt-get -y install python-setuptools\n",
                "echo \"Python Tools installed\" - `date`\n",
                "easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
                "echo \"Cloudformation Boostrap installed \" - `date`\n",
                "# If all went well, signal success\n",
                "cfn-signal -e $? -r 'Edx Server configuration' '",
                {
                  "Ref":"NotifierServerWaitHandle"
                },
                "'\n"
              ]
            ]
          }
        }
      }
    },
    "NotifierSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Notifier Security Group",
        "VpcId":{
          "Ref":"EdxVPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":{
              "Ref":"SSHLocation"
            }
          }
        ]
      }
    },
    "NotifierServerWaitHandle":{
      "Type":"AWS::CloudFormation::WaitConditionHandle"
    },
    "NotifierServerWaitCondition":{
      "Type":"AWS::CloudFormation::WaitCondition",
      "DependsOn":"NotifierHost",
      "Properties":{
        "Handle":{
          "Ref":"NotifierServerWaitHandle"
        },
        "Timeout":"1200"
      }
    }
  },
  "Outputs":{
    "EdxSecurityGroup":{
      "Description":"EC2 Security Group with access to the Edx server",
      "Value":{
        "Ref":"EdxappServerSecurityGroup"
      }
    }
  }
}