{ "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" } } } }