From 45af83964c42c9a179b7002a2c17cdca4f7b2977 Mon Sep 17 00:00:00 2001 From: Raul Cuza Date: Fri, 8 Apr 2016 21:20:19 -0400 Subject: [PATCH 1/8] Add Amazon example template Add AutoScalingMultiAZWithNotifications.template example https://s3-us-west-2.amazonaws.com/cloudformation-templates-us-west-2/AutoScalingMultiAZWithNotifications.template --- ...toScalingMultiAZWithNotifications.template | 411 ++++++++++++++++++ 1 file changed, 411 insertions(+) create mode 100644 tests/examples_output/AutoScalingMultiAZWithNotifications.template diff --git a/tests/examples_output/AutoScalingMultiAZWithNotifications.template b/tests/examples_output/AutoScalingMultiAZWithNotifications.template new file mode 100644 index 000000000..fa215dca5 --- /dev/null +++ b/tests/examples_output/AutoScalingMultiAZWithNotifications.template @@ -0,0 +1,411 @@ +{ + "AWSTemplateFormatVersion" : "2010-09-09", + + "Description" : "AWS CloudFormation Sample Template AutoScalingMultiAZWithNotifications: Create a multi-az, load balanced and Auto Scaled sample web site running on an Apache Web Serever. The application is configured to span all Availability Zones in the region and is Auto-Scaled based on the CPU utilization of the web servers. Notifications will be sent to the operator email address on scaling events. The instances are load balanced with a simple health check against the default web page. **WARNING** This template creates one or more Amazon EC2 instances and an Elastic Load Balancer. You will be billed for the AWS resources used if you create a stack from this template.", + + "Parameters" : { + "InstanceType" : { + "Description" : "WebServer EC2 instance type", + "Type" : "String", + "Default" : "t2.small", + "AllowedValues" : [ "t1.micro", "t2.nano", "t2.micro", "t2.small", "t2.medium", "t2.large", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "g2.2xlarge", "g2.8xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "d2.xlarge", "d2.2xlarge", "d2.4xlarge", "d2.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge", "cg1.4xlarge"] +, + "ConstraintDescription" : "must be a valid EC2 instance type." + }, + + "OperatorEMail": { + "Description": "EMail address to notify if there are any scaling operations", + "Type": "String", + "AllowedPattern": "([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)", + "ConstraintDescription": "must be a valid email address." + }, + + "KeyName" : { + "Description" : "The EC2 Key Pair to allow SSH access to the instances", + "Type" : "AWS::EC2::KeyPair::KeyName", + "ConstraintDescription" : "must be the name of an existing EC2 KeyPair." + }, + + "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." + } + }, + + "Mappings" : { + "Region2Examples" : { + "us-east-1" : { "Examples" : "https://s3.amazonaws.com/cloudformation-examples-us-east-1" }, + "us-west-2" : { "Examples" : "https://s3-us-west-2.amazonaws.com/cloudformation-examples-us-west-2" }, + "us-west-1" : { "Examples" : "https://s3-us-west-1.amazonaws.com/cloudformation-examples-us-west-1" }, + "eu-west-1" : { "Examples" : "https://s3-eu-west-1.amazonaws.com/cloudformation-examples-eu-west-1" }, + "eu-central-1" : { "Examples" : "https://s3-eu-central-1.amazonaws.com/cloudformation-examples-eu-central-1" }, + "ap-southeast-1" : { "Examples" : "https://s3-ap-southeast-1.amazonaws.com/cloudformation-examples-ap-southeast-1" }, + "ap-northeast-1" : { "Examples" : "https://s3-ap-northeast-1.amazonaws.com/cloudformation-examples-ap-northeast-1" }, + "ap-northeast-2" : { "Examples" : "https://s3-ap-northeast-2.amazonaws.com/cloudformation-examples-ap-northeast-2" }, + "ap-southeast-2" : { "Examples" : "https://s3-ap-southeast-2.amazonaws.com/cloudformation-examples-ap-southeast-2" }, + "sa-east-1" : { "Examples" : "https://s3-sa-east-1.amazonaws.com/cloudformation-examples-sa-east-1" }, + "cn-north-1" : { "Examples" : "https://s3.cn-north-1.amazonaws.com.cn/cloudformation-examples-cn-north-1" } + } +, + "AWSInstanceType2Arch" : { + "t1.micro" : { "Arch" : "PV64" }, + "t2.nano" : { "Arch" : "HVM64" }, + "t2.micro" : { "Arch" : "HVM64" }, + "t2.small" : { "Arch" : "HVM64" }, + "t2.medium" : { "Arch" : "HVM64" }, + "t2.large" : { "Arch" : "HVM64" }, + "m1.small" : { "Arch" : "PV64" }, + "m1.medium" : { "Arch" : "PV64" }, + "m1.large" : { "Arch" : "PV64" }, + "m1.xlarge" : { "Arch" : "PV64" }, + "m2.xlarge" : { "Arch" : "PV64" }, + "m2.2xlarge" : { "Arch" : "PV64" }, + "m2.4xlarge" : { "Arch" : "PV64" }, + "m3.medium" : { "Arch" : "HVM64" }, + "m3.large" : { "Arch" : "HVM64" }, + "m3.xlarge" : { "Arch" : "HVM64" }, + "m3.2xlarge" : { "Arch" : "HVM64" }, + "m4.large" : { "Arch" : "HVM64" }, + "m4.xlarge" : { "Arch" : "HVM64" }, + "m4.2xlarge" : { "Arch" : "HVM64" }, + "m4.4xlarge" : { "Arch" : "HVM64" }, + "m4.10xlarge" : { "Arch" : "HVM64" }, + "c1.medium" : { "Arch" : "PV64" }, + "c1.xlarge" : { "Arch" : "PV64" }, + "c3.large" : { "Arch" : "HVM64" }, + "c3.xlarge" : { "Arch" : "HVM64" }, + "c3.2xlarge" : { "Arch" : "HVM64" }, + "c3.4xlarge" : { "Arch" : "HVM64" }, + "c3.8xlarge" : { "Arch" : "HVM64" }, + "c4.large" : { "Arch" : "HVM64" }, + "c4.xlarge" : { "Arch" : "HVM64" }, + "c4.2xlarge" : { "Arch" : "HVM64" }, + "c4.4xlarge" : { "Arch" : "HVM64" }, + "c4.8xlarge" : { "Arch" : "HVM64" }, + "g2.2xlarge" : { "Arch" : "HVMG2" }, + "g2.8xlarge" : { "Arch" : "HVMG2" }, + "r3.large" : { "Arch" : "HVM64" }, + "r3.xlarge" : { "Arch" : "HVM64" }, + "r3.2xlarge" : { "Arch" : "HVM64" }, + "r3.4xlarge" : { "Arch" : "HVM64" }, + "r3.8xlarge" : { "Arch" : "HVM64" }, + "i2.xlarge" : { "Arch" : "HVM64" }, + "i2.2xlarge" : { "Arch" : "HVM64" }, + "i2.4xlarge" : { "Arch" : "HVM64" }, + "i2.8xlarge" : { "Arch" : "HVM64" }, + "d2.xlarge" : { "Arch" : "HVM64" }, + "d2.2xlarge" : { "Arch" : "HVM64" }, + "d2.4xlarge" : { "Arch" : "HVM64" }, + "d2.8xlarge" : { "Arch" : "HVM64" }, + "hi1.4xlarge" : { "Arch" : "HVM64" }, + "hs1.8xlarge" : { "Arch" : "HVM64" }, + "cr1.8xlarge" : { "Arch" : "HVM64" }, + "cc2.8xlarge" : { "Arch" : "HVM64" } + }, + + "AWSInstanceType2NATArch" : { + "t1.micro" : { "Arch" : "NATPV64" }, + "t2.nano" : { "Arch" : "NATHVM64" }, + "t2.micro" : { "Arch" : "NATHVM64" }, + "t2.small" : { "Arch" : "NATHVM64" }, + "t2.medium" : { "Arch" : "NATHVM64" }, + "t2.large" : { "Arch" : "NATHVM64" }, + "m1.small" : { "Arch" : "NATPV64" }, + "m1.medium" : { "Arch" : "NATPV64" }, + "m1.large" : { "Arch" : "NATPV64" }, + "m1.xlarge" : { "Arch" : "NATPV64" }, + "m2.xlarge" : { "Arch" : "NATPV64" }, + "m2.2xlarge" : { "Arch" : "NATPV64" }, + "m2.4xlarge" : { "Arch" : "NATPV64" }, + "m3.medium" : { "Arch" : "NATHVM64" }, + "m3.large" : { "Arch" : "NATHVM64" }, + "m3.xlarge" : { "Arch" : "NATHVM64" }, + "m3.2xlarge" : { "Arch" : "NATHVM64" }, + "m4.large" : { "Arch" : "NATHVM64" }, + "m4.xlarge" : { "Arch" : "NATHVM64" }, + "m4.2xlarge" : { "Arch" : "NATHVM64" }, + "m4.4xlarge" : { "Arch" : "NATHVM64" }, + "m4.10xlarge" : { "Arch" : "NATHVM64" }, + "c1.medium" : { "Arch" : "NATPV64" }, + "c1.xlarge" : { "Arch" : "NATPV64" }, + "c3.large" : { "Arch" : "NATHVM64" }, + "c3.xlarge" : { "Arch" : "NATHVM64" }, + "c3.2xlarge" : { "Arch" : "NATHVM64" }, + "c3.4xlarge" : { "Arch" : "NATHVM64" }, + "c3.8xlarge" : { "Arch" : "NATHVM64" }, + "c4.large" : { "Arch" : "NATHVM64" }, + "c4.xlarge" : { "Arch" : "NATHVM64" }, + "c4.2xlarge" : { "Arch" : "NATHVM64" }, + "c4.4xlarge" : { "Arch" : "NATHVM64" }, + "c4.8xlarge" : { "Arch" : "NATHVM64" }, + "g2.2xlarge" : { "Arch" : "NATHVMG2" }, + "g2.8xlarge" : { "Arch" : "NATHVMG2" }, + "r3.large" : { "Arch" : "NATHVM64" }, + "r3.xlarge" : { "Arch" : "NATHVM64" }, + "r3.2xlarge" : { "Arch" : "NATHVM64" }, + "r3.4xlarge" : { "Arch" : "NATHVM64" }, + "r3.8xlarge" : { "Arch" : "NATHVM64" }, + "i2.xlarge" : { "Arch" : "NATHVM64" }, + "i2.2xlarge" : { "Arch" : "NATHVM64" }, + "i2.4xlarge" : { "Arch" : "NATHVM64" }, + "i2.8xlarge" : { "Arch" : "NATHVM64" }, + "d2.xlarge" : { "Arch" : "NATHVM64" }, + "d2.2xlarge" : { "Arch" : "NATHVM64" }, + "d2.4xlarge" : { "Arch" : "NATHVM64" }, + "d2.8xlarge" : { "Arch" : "NATHVM64" }, + "hi1.4xlarge" : { "Arch" : "NATHVM64" }, + "hs1.8xlarge" : { "Arch" : "NATHVM64" }, + "cr1.8xlarge" : { "Arch" : "NATHVM64" }, + "cc2.8xlarge" : { "Arch" : "NATHVM64" } + } +, + "AWSRegionArch2AMI" : { + "us-east-1" : {"PV64" : "ami-22111148", "HVM64" : "ami-08111162", "HVMG2" : "ami-ebcec381"}, + "us-west-2" : {"PV64" : "ami-792bc219", "HVM64" : "ami-c229c0a2", "HVMG2" : "ami-0f28c06f"}, + "us-west-1" : {"PV64" : "ami-0e087a6e", "HVM64" : "ami-1b0f7d7b", "HVMG2" : "ami-ab9defcb"}, + "eu-west-1" : {"PV64" : "ami-a5368cd6", "HVM64" : "ami-31328842", "HVMG2" : "ami-d1d652a2"}, + "eu-central-1" : {"PV64" : "ami-2bde3944", "HVM64" : "ami-e2df388d", "HVMG2" : "ami-5240a73d"}, + "ap-northeast-1" : {"PV64" : "ami-37020959", "HVM64" : "ami-f80e0596", "HVMG2" : "ami-34a9a35a"}, + "ap-northeast-2" : {"PV64" : "NOT_SUPPORTED", "HVM64" : "ami-6598510b", "HVMG2" : "NOT_SUPPORTED"}, + "ap-southeast-1" : {"PV64" : "ami-ff0cc79c", "HVM64" : "ami-e90dc68a", "HVMG2" : "ami-6f6ca70c"}, + "ap-southeast-2" : {"PV64" : "ami-f5210196", "HVM64" : "ami-f2210191", "HVMG2" : "ami-88c1e1eb"}, + "sa-east-1" : {"PV64" : "ami-661e930a", "HVM64" : "ami-1e159872", "HVMG2" : "NOT_SUPPORTED"}, + "cn-north-1" : {"PV64" : "ami-08ef2465", "HVM64" : "ami-49e22924", "HVMG2" : "NOT_SUPPORTED"} + } + + }, + + "Resources" : { + "NotificationTopic": { + "Type": "AWS::SNS::Topic", + "Properties": { + "Subscription": [ { "Endpoint": { "Ref": "OperatorEMail" }, "Protocol": "email" } ] + } + }, + + "WebServerGroup" : { + "Type" : "AWS::AutoScaling::AutoScalingGroup", + "Properties" : { + "AvailabilityZones" : { "Fn::GetAZs" : ""}, + "LaunchConfigurationName" : { "Ref" : "LaunchConfig" }, + "MinSize" : "1", + "MaxSize" : "3", + "LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ], + "NotificationConfiguration" : { + "TopicARN" : { "Ref" : "NotificationTopic" }, + "NotificationTypes" : [ "autoscaling:EC2_INSTANCE_LAUNCH", + "autoscaling:EC2_INSTANCE_LAUNCH_ERROR", + "autoscaling:EC2_INSTANCE_TERMINATE", + "autoscaling:EC2_INSTANCE_TERMINATE_ERROR"] + } + }, + "CreationPolicy" : { + "ResourceSignal" : { + "Timeout" : "PT15M", + "Count" : "1" + } + }, + "UpdatePolicy": { + "AutoScalingRollingUpdate": { + "MinInstancesInService": "1", + "MaxBatchSize": "1", + "PauseTime" : "PT15M", + "WaitOnResourceSignals": "true" + } + } + }, + + "LaunchConfig" : { + "Type" : "AWS::AutoScaling::LaunchConfiguration", + "Metadata" : { + "Comment" : "Install a simple application", + "AWS::CloudFormation::Init" : { + "config" : { + "packages" : { + "yum" : { + "httpd" : [] + } + }, + + "files" : { + "/var/www/html/index.html" : { + "content" : { "Fn::Join" : ["\n", [ + "\"AWS", + "

Congratulations, you have successfully launched the AWS CloudFormation sample.

" + ]]}, + "mode" : "000644", + "owner" : "root", + "group" : "root" + }, + + "/etc/cfn/cfn-hup.conf" : { + "content" : { "Fn::Join" : ["", [ + "[main]\n", + "stack=", { "Ref" : "AWS::StackId" }, "\n", + "region=", { "Ref" : "AWS::Region" }, "\n" + ]]}, + "mode" : "000400", + "owner" : "root", + "group" : "root" + }, + + "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : { + "content": { "Fn::Join" : ["", [ + "[cfn-auto-reloader-hook]\n", + "triggers=post.update\n", + "path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init\n", + "action=/opt/aws/bin/cfn-init -v ", + " --stack ", { "Ref" : "AWS::StackName" }, + " --resource LaunchConfig ", + " --region ", { "Ref" : "AWS::Region" }, "\n", + "runas=root\n" + ]]} + } + }, + + "services" : { + "sysvinit" : { + "httpd" : { "enabled" : "true", "ensureRunning" : "true" }, + "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", + "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]} + } + } + } + } + }, + "Properties" : { + "KeyName" : { "Ref" : "KeyName" }, + "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, + { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, + "SecurityGroups" : [ { "Ref" : "InstanceSecurityGroup" } ], + "InstanceType" : { "Ref" : "InstanceType" }, + "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ + "#!/bin/bash -xe\n", + "yum update -y aws-cfn-bootstrap\n", + + "/opt/aws/bin/cfn-init -v ", + " --stack ", { "Ref" : "AWS::StackName" }, + " --resource LaunchConfig ", + " --region ", { "Ref" : "AWS::Region" }, "\n", + + "/opt/aws/bin/cfn-signal -e $? ", + " --stack ", { "Ref" : "AWS::StackName" }, + " --resource WebServerGroup ", + " --region ", { "Ref" : "AWS::Region" }, "\n" + ]]}} + } + }, + + "WebServerScaleUpPolicy" : { + "Type" : "AWS::AutoScaling::ScalingPolicy", + "Properties" : { + "AdjustmentType" : "ChangeInCapacity", + "AutoScalingGroupName" : { "Ref" : "WebServerGroup" }, + "Cooldown" : "60", + "ScalingAdjustment" : "1" + } + }, + "WebServerScaleDownPolicy" : { + "Type" : "AWS::AutoScaling::ScalingPolicy", + "Properties" : { + "AdjustmentType" : "ChangeInCapacity", + "AutoScalingGroupName" : { "Ref" : "WebServerGroup" }, + "Cooldown" : "60", + "ScalingAdjustment" : "-1" + } + }, + + "CPUAlarmHigh": { + "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": "WebServerScaleUpPolicy" } ], + "Dimensions": [ + { + "Name": "AutoScalingGroupName", + "Value": { "Ref": "WebServerGroup" } + } + ], + "ComparisonOperator": "GreaterThanThreshold" + } + }, + "CPUAlarmLow": { + "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": "WebServerScaleDownPolicy" } ], + "Dimensions": [ + { + "Name": "AutoScalingGroupName", + "Value": { "Ref": "WebServerGroup" } + } + ], + "ComparisonOperator": "LessThanThreshold" + } + }, + + "ElasticLoadBalancer" : { + "Type" : "AWS::ElasticLoadBalancing::LoadBalancer", + "Properties" : { + "AvailabilityZones" : { "Fn::GetAZs" : "" }, + "CrossZone" : "true", + "Listeners" : [ { + "LoadBalancerPort" : "80", + "InstancePort" : "80", + "Protocol" : "HTTP" + } ], + "HealthCheck" : { + "Target" : "HTTP:80/", + "HealthyThreshold" : "3", + "UnhealthyThreshold" : "5", + "Interval" : "30", + "Timeout" : "5" + } + } + }, + + "InstanceSecurityGroup" : { + "Type" : "AWS::EC2::SecurityGroup", + "Properties" : { + "GroupDescription" : "Enable SSH access and HTTP from the load balancer only", + "SecurityGroupIngress" : [ { + "IpProtocol" : "tcp", + "FromPort" : "22", + "ToPort" : "22", + "CidrIp" : { "Ref" : "SSHLocation"} + }, + { + "IpProtocol" : "tcp", + "FromPort" : "80", + "ToPort" : "80", + "SourceSecurityGroupOwnerId" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.OwnerAlias"]}, + "SourceSecurityGroupName" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.GroupName"]} + } ] + } + } + }, + + "Outputs" : { + "URL" : { + "Description" : "The URL of the website", + "Value" : { "Fn::Join" : [ "", [ "http://", { "Fn::GetAtt" : [ "ElasticLoadBalancer", "DNSName" ]}]]} + } + } +} From 60149977cd7d6fa526b30fc93786b26f362e11e4 Mon Sep 17 00:00:00 2001 From: Raul Cuza Date: Fri, 8 Apr 2016 23:34:13 -0400 Subject: [PATCH 2/8] Run through json.tool and fix endings --- ...toScalingMultiAZWithNotifications.template | 1289 +++++++++++------ 1 file changed, 878 insertions(+), 411 deletions(-) diff --git a/tests/examples_output/AutoScalingMultiAZWithNotifications.template b/tests/examples_output/AutoScalingMultiAZWithNotifications.template index fa215dca5..71baf319d 100644 --- a/tests/examples_output/AutoScalingMultiAZWithNotifications.template +++ b/tests/examples_output/AutoScalingMultiAZWithNotifications.template @@ -1,411 +1,878 @@ -{ - "AWSTemplateFormatVersion" : "2010-09-09", - - "Description" : "AWS CloudFormation Sample Template AutoScalingMultiAZWithNotifications: Create a multi-az, load balanced and Auto Scaled sample web site running on an Apache Web Serever. The application is configured to span all Availability Zones in the region and is Auto-Scaled based on the CPU utilization of the web servers. Notifications will be sent to the operator email address on scaling events. The instances are load balanced with a simple health check against the default web page. **WARNING** This template creates one or more Amazon EC2 instances and an Elastic Load Balancer. You will be billed for the AWS resources used if you create a stack from this template.", - - "Parameters" : { - "InstanceType" : { - "Description" : "WebServer EC2 instance type", - "Type" : "String", - "Default" : "t2.small", - "AllowedValues" : [ "t1.micro", "t2.nano", "t2.micro", "t2.small", "t2.medium", "t2.large", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "g2.2xlarge", "g2.8xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "d2.xlarge", "d2.2xlarge", "d2.4xlarge", "d2.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge", "cg1.4xlarge"] -, - "ConstraintDescription" : "must be a valid EC2 instance type." - }, - - "OperatorEMail": { - "Description": "EMail address to notify if there are any scaling operations", - "Type": "String", - "AllowedPattern": "([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)", - "ConstraintDescription": "must be a valid email address." - }, - - "KeyName" : { - "Description" : "The EC2 Key Pair to allow SSH access to the instances", - "Type" : "AWS::EC2::KeyPair::KeyName", - "ConstraintDescription" : "must be the name of an existing EC2 KeyPair." - }, - - "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." - } - }, - - "Mappings" : { - "Region2Examples" : { - "us-east-1" : { "Examples" : "https://s3.amazonaws.com/cloudformation-examples-us-east-1" }, - "us-west-2" : { "Examples" : "https://s3-us-west-2.amazonaws.com/cloudformation-examples-us-west-2" }, - "us-west-1" : { "Examples" : "https://s3-us-west-1.amazonaws.com/cloudformation-examples-us-west-1" }, - "eu-west-1" : { "Examples" : "https://s3-eu-west-1.amazonaws.com/cloudformation-examples-eu-west-1" }, - "eu-central-1" : { "Examples" : "https://s3-eu-central-1.amazonaws.com/cloudformation-examples-eu-central-1" }, - "ap-southeast-1" : { "Examples" : "https://s3-ap-southeast-1.amazonaws.com/cloudformation-examples-ap-southeast-1" }, - "ap-northeast-1" : { "Examples" : "https://s3-ap-northeast-1.amazonaws.com/cloudformation-examples-ap-northeast-1" }, - "ap-northeast-2" : { "Examples" : "https://s3-ap-northeast-2.amazonaws.com/cloudformation-examples-ap-northeast-2" }, - "ap-southeast-2" : { "Examples" : "https://s3-ap-southeast-2.amazonaws.com/cloudformation-examples-ap-southeast-2" }, - "sa-east-1" : { "Examples" : "https://s3-sa-east-1.amazonaws.com/cloudformation-examples-sa-east-1" }, - "cn-north-1" : { "Examples" : "https://s3.cn-north-1.amazonaws.com.cn/cloudformation-examples-cn-north-1" } - } -, - "AWSInstanceType2Arch" : { - "t1.micro" : { "Arch" : "PV64" }, - "t2.nano" : { "Arch" : "HVM64" }, - "t2.micro" : { "Arch" : "HVM64" }, - "t2.small" : { "Arch" : "HVM64" }, - "t2.medium" : { "Arch" : "HVM64" }, - "t2.large" : { "Arch" : "HVM64" }, - "m1.small" : { "Arch" : "PV64" }, - "m1.medium" : { "Arch" : "PV64" }, - "m1.large" : { "Arch" : "PV64" }, - "m1.xlarge" : { "Arch" : "PV64" }, - "m2.xlarge" : { "Arch" : "PV64" }, - "m2.2xlarge" : { "Arch" : "PV64" }, - "m2.4xlarge" : { "Arch" : "PV64" }, - "m3.medium" : { "Arch" : "HVM64" }, - "m3.large" : { "Arch" : "HVM64" }, - "m3.xlarge" : { "Arch" : "HVM64" }, - "m3.2xlarge" : { "Arch" : "HVM64" }, - "m4.large" : { "Arch" : "HVM64" }, - "m4.xlarge" : { "Arch" : "HVM64" }, - "m4.2xlarge" : { "Arch" : "HVM64" }, - "m4.4xlarge" : { "Arch" : "HVM64" }, - "m4.10xlarge" : { "Arch" : "HVM64" }, - "c1.medium" : { "Arch" : "PV64" }, - "c1.xlarge" : { "Arch" : "PV64" }, - "c3.large" : { "Arch" : "HVM64" }, - "c3.xlarge" : { "Arch" : "HVM64" }, - "c3.2xlarge" : { "Arch" : "HVM64" }, - "c3.4xlarge" : { "Arch" : "HVM64" }, - "c3.8xlarge" : { "Arch" : "HVM64" }, - "c4.large" : { "Arch" : "HVM64" }, - "c4.xlarge" : { "Arch" : "HVM64" }, - "c4.2xlarge" : { "Arch" : "HVM64" }, - "c4.4xlarge" : { "Arch" : "HVM64" }, - "c4.8xlarge" : { "Arch" : "HVM64" }, - "g2.2xlarge" : { "Arch" : "HVMG2" }, - "g2.8xlarge" : { "Arch" : "HVMG2" }, - "r3.large" : { "Arch" : "HVM64" }, - "r3.xlarge" : { "Arch" : "HVM64" }, - "r3.2xlarge" : { "Arch" : "HVM64" }, - "r3.4xlarge" : { "Arch" : "HVM64" }, - "r3.8xlarge" : { "Arch" : "HVM64" }, - "i2.xlarge" : { "Arch" : "HVM64" }, - "i2.2xlarge" : { "Arch" : "HVM64" }, - "i2.4xlarge" : { "Arch" : "HVM64" }, - "i2.8xlarge" : { "Arch" : "HVM64" }, - "d2.xlarge" : { "Arch" : "HVM64" }, - "d2.2xlarge" : { "Arch" : "HVM64" }, - "d2.4xlarge" : { "Arch" : "HVM64" }, - "d2.8xlarge" : { "Arch" : "HVM64" }, - "hi1.4xlarge" : { "Arch" : "HVM64" }, - "hs1.8xlarge" : { "Arch" : "HVM64" }, - "cr1.8xlarge" : { "Arch" : "HVM64" }, - "cc2.8xlarge" : { "Arch" : "HVM64" } - }, - - "AWSInstanceType2NATArch" : { - "t1.micro" : { "Arch" : "NATPV64" }, - "t2.nano" : { "Arch" : "NATHVM64" }, - "t2.micro" : { "Arch" : "NATHVM64" }, - "t2.small" : { "Arch" : "NATHVM64" }, - "t2.medium" : { "Arch" : "NATHVM64" }, - "t2.large" : { "Arch" : "NATHVM64" }, - "m1.small" : { "Arch" : "NATPV64" }, - "m1.medium" : { "Arch" : "NATPV64" }, - "m1.large" : { "Arch" : "NATPV64" }, - "m1.xlarge" : { "Arch" : "NATPV64" }, - "m2.xlarge" : { "Arch" : "NATPV64" }, - "m2.2xlarge" : { "Arch" : "NATPV64" }, - "m2.4xlarge" : { "Arch" : "NATPV64" }, - "m3.medium" : { "Arch" : "NATHVM64" }, - "m3.large" : { "Arch" : "NATHVM64" }, - "m3.xlarge" : { "Arch" : "NATHVM64" }, - "m3.2xlarge" : { "Arch" : "NATHVM64" }, - "m4.large" : { "Arch" : "NATHVM64" }, - "m4.xlarge" : { "Arch" : "NATHVM64" }, - "m4.2xlarge" : { "Arch" : "NATHVM64" }, - "m4.4xlarge" : { "Arch" : "NATHVM64" }, - "m4.10xlarge" : { "Arch" : "NATHVM64" }, - "c1.medium" : { "Arch" : "NATPV64" }, - "c1.xlarge" : { "Arch" : "NATPV64" }, - "c3.large" : { "Arch" : "NATHVM64" }, - "c3.xlarge" : { "Arch" : "NATHVM64" }, - "c3.2xlarge" : { "Arch" : "NATHVM64" }, - "c3.4xlarge" : { "Arch" : "NATHVM64" }, - "c3.8xlarge" : { "Arch" : "NATHVM64" }, - "c4.large" : { "Arch" : "NATHVM64" }, - "c4.xlarge" : { "Arch" : "NATHVM64" }, - "c4.2xlarge" : { "Arch" : "NATHVM64" }, - "c4.4xlarge" : { "Arch" : "NATHVM64" }, - "c4.8xlarge" : { "Arch" : "NATHVM64" }, - "g2.2xlarge" : { "Arch" : "NATHVMG2" }, - "g2.8xlarge" : { "Arch" : "NATHVMG2" }, - "r3.large" : { "Arch" : "NATHVM64" }, - "r3.xlarge" : { "Arch" : "NATHVM64" }, - "r3.2xlarge" : { "Arch" : "NATHVM64" }, - "r3.4xlarge" : { "Arch" : "NATHVM64" }, - "r3.8xlarge" : { "Arch" : "NATHVM64" }, - "i2.xlarge" : { "Arch" : "NATHVM64" }, - "i2.2xlarge" : { "Arch" : "NATHVM64" }, - "i2.4xlarge" : { "Arch" : "NATHVM64" }, - "i2.8xlarge" : { "Arch" : "NATHVM64" }, - "d2.xlarge" : { "Arch" : "NATHVM64" }, - "d2.2xlarge" : { "Arch" : "NATHVM64" }, - "d2.4xlarge" : { "Arch" : "NATHVM64" }, - "d2.8xlarge" : { "Arch" : "NATHVM64" }, - "hi1.4xlarge" : { "Arch" : "NATHVM64" }, - "hs1.8xlarge" : { "Arch" : "NATHVM64" }, - "cr1.8xlarge" : { "Arch" : "NATHVM64" }, - "cc2.8xlarge" : { "Arch" : "NATHVM64" } - } -, - "AWSRegionArch2AMI" : { - "us-east-1" : {"PV64" : "ami-22111148", "HVM64" : "ami-08111162", "HVMG2" : "ami-ebcec381"}, - "us-west-2" : {"PV64" : "ami-792bc219", "HVM64" : "ami-c229c0a2", "HVMG2" : "ami-0f28c06f"}, - "us-west-1" : {"PV64" : "ami-0e087a6e", "HVM64" : "ami-1b0f7d7b", "HVMG2" : "ami-ab9defcb"}, - "eu-west-1" : {"PV64" : "ami-a5368cd6", "HVM64" : "ami-31328842", "HVMG2" : "ami-d1d652a2"}, - "eu-central-1" : {"PV64" : "ami-2bde3944", "HVM64" : "ami-e2df388d", "HVMG2" : "ami-5240a73d"}, - "ap-northeast-1" : {"PV64" : "ami-37020959", "HVM64" : "ami-f80e0596", "HVMG2" : "ami-34a9a35a"}, - "ap-northeast-2" : {"PV64" : "NOT_SUPPORTED", "HVM64" : "ami-6598510b", "HVMG2" : "NOT_SUPPORTED"}, - "ap-southeast-1" : {"PV64" : "ami-ff0cc79c", "HVM64" : "ami-e90dc68a", "HVMG2" : "ami-6f6ca70c"}, - "ap-southeast-2" : {"PV64" : "ami-f5210196", "HVM64" : "ami-f2210191", "HVMG2" : "ami-88c1e1eb"}, - "sa-east-1" : {"PV64" : "ami-661e930a", "HVM64" : "ami-1e159872", "HVMG2" : "NOT_SUPPORTED"}, - "cn-north-1" : {"PV64" : "ami-08ef2465", "HVM64" : "ami-49e22924", "HVMG2" : "NOT_SUPPORTED"} - } - - }, - - "Resources" : { - "NotificationTopic": { - "Type": "AWS::SNS::Topic", - "Properties": { - "Subscription": [ { "Endpoint": { "Ref": "OperatorEMail" }, "Protocol": "email" } ] - } - }, - - "WebServerGroup" : { - "Type" : "AWS::AutoScaling::AutoScalingGroup", - "Properties" : { - "AvailabilityZones" : { "Fn::GetAZs" : ""}, - "LaunchConfigurationName" : { "Ref" : "LaunchConfig" }, - "MinSize" : "1", - "MaxSize" : "3", - "LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ], - "NotificationConfiguration" : { - "TopicARN" : { "Ref" : "NotificationTopic" }, - "NotificationTypes" : [ "autoscaling:EC2_INSTANCE_LAUNCH", - "autoscaling:EC2_INSTANCE_LAUNCH_ERROR", - "autoscaling:EC2_INSTANCE_TERMINATE", - "autoscaling:EC2_INSTANCE_TERMINATE_ERROR"] - } - }, - "CreationPolicy" : { - "ResourceSignal" : { - "Timeout" : "PT15M", - "Count" : "1" - } - }, - "UpdatePolicy": { - "AutoScalingRollingUpdate": { - "MinInstancesInService": "1", - "MaxBatchSize": "1", - "PauseTime" : "PT15M", - "WaitOnResourceSignals": "true" - } - } - }, - - "LaunchConfig" : { - "Type" : "AWS::AutoScaling::LaunchConfiguration", - "Metadata" : { - "Comment" : "Install a simple application", - "AWS::CloudFormation::Init" : { - "config" : { - "packages" : { - "yum" : { - "httpd" : [] - } - }, - - "files" : { - "/var/www/html/index.html" : { - "content" : { "Fn::Join" : ["\n", [ - "\"AWS", - "

Congratulations, you have successfully launched the AWS CloudFormation sample.

" - ]]}, - "mode" : "000644", - "owner" : "root", - "group" : "root" - }, - - "/etc/cfn/cfn-hup.conf" : { - "content" : { "Fn::Join" : ["", [ - "[main]\n", - "stack=", { "Ref" : "AWS::StackId" }, "\n", - "region=", { "Ref" : "AWS::Region" }, "\n" - ]]}, - "mode" : "000400", - "owner" : "root", - "group" : "root" - }, - - "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : { - "content": { "Fn::Join" : ["", [ - "[cfn-auto-reloader-hook]\n", - "triggers=post.update\n", - "path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init\n", - "action=/opt/aws/bin/cfn-init -v ", - " --stack ", { "Ref" : "AWS::StackName" }, - " --resource LaunchConfig ", - " --region ", { "Ref" : "AWS::Region" }, "\n", - "runas=root\n" - ]]} - } - }, - - "services" : { - "sysvinit" : { - "httpd" : { "enabled" : "true", "ensureRunning" : "true" }, - "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", - "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]} - } - } - } - } - }, - "Properties" : { - "KeyName" : { "Ref" : "KeyName" }, - "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, - { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, - "SecurityGroups" : [ { "Ref" : "InstanceSecurityGroup" } ], - "InstanceType" : { "Ref" : "InstanceType" }, - "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ - "#!/bin/bash -xe\n", - "yum update -y aws-cfn-bootstrap\n", - - "/opt/aws/bin/cfn-init -v ", - " --stack ", { "Ref" : "AWS::StackName" }, - " --resource LaunchConfig ", - " --region ", { "Ref" : "AWS::Region" }, "\n", - - "/opt/aws/bin/cfn-signal -e $? ", - " --stack ", { "Ref" : "AWS::StackName" }, - " --resource WebServerGroup ", - " --region ", { "Ref" : "AWS::Region" }, "\n" - ]]}} - } - }, - - "WebServerScaleUpPolicy" : { - "Type" : "AWS::AutoScaling::ScalingPolicy", - "Properties" : { - "AdjustmentType" : "ChangeInCapacity", - "AutoScalingGroupName" : { "Ref" : "WebServerGroup" }, - "Cooldown" : "60", - "ScalingAdjustment" : "1" - } - }, - "WebServerScaleDownPolicy" : { - "Type" : "AWS::AutoScaling::ScalingPolicy", - "Properties" : { - "AdjustmentType" : "ChangeInCapacity", - "AutoScalingGroupName" : { "Ref" : "WebServerGroup" }, - "Cooldown" : "60", - "ScalingAdjustment" : "-1" - } - }, - - "CPUAlarmHigh": { - "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": "WebServerScaleUpPolicy" } ], - "Dimensions": [ - { - "Name": "AutoScalingGroupName", - "Value": { "Ref": "WebServerGroup" } - } - ], - "ComparisonOperator": "GreaterThanThreshold" - } - }, - "CPUAlarmLow": { - "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": "WebServerScaleDownPolicy" } ], - "Dimensions": [ - { - "Name": "AutoScalingGroupName", - "Value": { "Ref": "WebServerGroup" } - } - ], - "ComparisonOperator": "LessThanThreshold" - } - }, - - "ElasticLoadBalancer" : { - "Type" : "AWS::ElasticLoadBalancing::LoadBalancer", - "Properties" : { - "AvailabilityZones" : { "Fn::GetAZs" : "" }, - "CrossZone" : "true", - "Listeners" : [ { - "LoadBalancerPort" : "80", - "InstancePort" : "80", - "Protocol" : "HTTP" - } ], - "HealthCheck" : { - "Target" : "HTTP:80/", - "HealthyThreshold" : "3", - "UnhealthyThreshold" : "5", - "Interval" : "30", - "Timeout" : "5" - } - } - }, - - "InstanceSecurityGroup" : { - "Type" : "AWS::EC2::SecurityGroup", - "Properties" : { - "GroupDescription" : "Enable SSH access and HTTP from the load balancer only", - "SecurityGroupIngress" : [ { - "IpProtocol" : "tcp", - "FromPort" : "22", - "ToPort" : "22", - "CidrIp" : { "Ref" : "SSHLocation"} - }, - { - "IpProtocol" : "tcp", - "FromPort" : "80", - "ToPort" : "80", - "SourceSecurityGroupOwnerId" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.OwnerAlias"]}, - "SourceSecurityGroupName" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.GroupName"]} - } ] - } - } - }, - - "Outputs" : { - "URL" : { - "Description" : "The URL of the website", - "Value" : { "Fn::Join" : [ "", [ "http://", { "Fn::GetAtt" : [ "ElasticLoadBalancer", "DNSName" ]}]]} - } - } -} +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "AWS CloudFormation Sample Template AutoScalingMultiAZWithNotifications: Create a multi-az, load balanced and Auto Scaled sample web site running on an Apache Web Serever. The application is configured to span all Availability Zones in the region and is Auto-Scaled based on the CPU utilization of the web servers. Notifications will be sent to the operator email address on scaling events. The instances are load balanced with a simple health check against the default web page. **WARNING** This template creates one or more Amazon EC2 instances and an Elastic Load Balancer. You will be billed for the AWS resources used if you create a stack from this template.", + "Mappings": { + "AWSInstanceType2Arch": { + "c1.medium": { + "Arch": "PV64" + }, + "c1.xlarge": { + "Arch": "PV64" + }, + "c3.2xlarge": { + "Arch": "HVM64" + }, + "c3.4xlarge": { + "Arch": "HVM64" + }, + "c3.8xlarge": { + "Arch": "HVM64" + }, + "c3.large": { + "Arch": "HVM64" + }, + "c3.xlarge": { + "Arch": "HVM64" + }, + "c4.2xlarge": { + "Arch": "HVM64" + }, + "c4.4xlarge": { + "Arch": "HVM64" + }, + "c4.8xlarge": { + "Arch": "HVM64" + }, + "c4.large": { + "Arch": "HVM64" + }, + "c4.xlarge": { + "Arch": "HVM64" + }, + "cc2.8xlarge": { + "Arch": "HVM64" + }, + "cr1.8xlarge": { + "Arch": "HVM64" + }, + "d2.2xlarge": { + "Arch": "HVM64" + }, + "d2.4xlarge": { + "Arch": "HVM64" + }, + "d2.8xlarge": { + "Arch": "HVM64" + }, + "d2.xlarge": { + "Arch": "HVM64" + }, + "g2.2xlarge": { + "Arch": "HVMG2" + }, + "g2.8xlarge": { + "Arch": "HVMG2" + }, + "hi1.4xlarge": { + "Arch": "HVM64" + }, + "hs1.8xlarge": { + "Arch": "HVM64" + }, + "i2.2xlarge": { + "Arch": "HVM64" + }, + "i2.4xlarge": { + "Arch": "HVM64" + }, + "i2.8xlarge": { + "Arch": "HVM64" + }, + "i2.xlarge": { + "Arch": "HVM64" + }, + "m1.large": { + "Arch": "PV64" + }, + "m1.medium": { + "Arch": "PV64" + }, + "m1.small": { + "Arch": "PV64" + }, + "m1.xlarge": { + "Arch": "PV64" + }, + "m2.2xlarge": { + "Arch": "PV64" + }, + "m2.4xlarge": { + "Arch": "PV64" + }, + "m2.xlarge": { + "Arch": "PV64" + }, + "m3.2xlarge": { + "Arch": "HVM64" + }, + "m3.large": { + "Arch": "HVM64" + }, + "m3.medium": { + "Arch": "HVM64" + }, + "m3.xlarge": { + "Arch": "HVM64" + }, + "m4.10xlarge": { + "Arch": "HVM64" + }, + "m4.2xlarge": { + "Arch": "HVM64" + }, + "m4.4xlarge": { + "Arch": "HVM64" + }, + "m4.large": { + "Arch": "HVM64" + }, + "m4.xlarge": { + "Arch": "HVM64" + }, + "r3.2xlarge": { + "Arch": "HVM64" + }, + "r3.4xlarge": { + "Arch": "HVM64" + }, + "r3.8xlarge": { + "Arch": "HVM64" + }, + "r3.large": { + "Arch": "HVM64" + }, + "r3.xlarge": { + "Arch": "HVM64" + }, + "t1.micro": { + "Arch": "PV64" + }, + "t2.large": { + "Arch": "HVM64" + }, + "t2.medium": { + "Arch": "HVM64" + }, + "t2.micro": { + "Arch": "HVM64" + }, + "t2.nano": { + "Arch": "HVM64" + }, + "t2.small": { + "Arch": "HVM64" + } + }, + "AWSInstanceType2NATArch": { + "c1.medium": { + "Arch": "NATPV64" + }, + "c1.xlarge": { + "Arch": "NATPV64" + }, + "c3.2xlarge": { + "Arch": "NATHVM64" + }, + "c3.4xlarge": { + "Arch": "NATHVM64" + }, + "c3.8xlarge": { + "Arch": "NATHVM64" + }, + "c3.large": { + "Arch": "NATHVM64" + }, + "c3.xlarge": { + "Arch": "NATHVM64" + }, + "c4.2xlarge": { + "Arch": "NATHVM64" + }, + "c4.4xlarge": { + "Arch": "NATHVM64" + }, + "c4.8xlarge": { + "Arch": "NATHVM64" + }, + "c4.large": { + "Arch": "NATHVM64" + }, + "c4.xlarge": { + "Arch": "NATHVM64" + }, + "cc2.8xlarge": { + "Arch": "NATHVM64" + }, + "cr1.8xlarge": { + "Arch": "NATHVM64" + }, + "d2.2xlarge": { + "Arch": "NATHVM64" + }, + "d2.4xlarge": { + "Arch": "NATHVM64" + }, + "d2.8xlarge": { + "Arch": "NATHVM64" + }, + "d2.xlarge": { + "Arch": "NATHVM64" + }, + "g2.2xlarge": { + "Arch": "NATHVMG2" + }, + "g2.8xlarge": { + "Arch": "NATHVMG2" + }, + "hi1.4xlarge": { + "Arch": "NATHVM64" + }, + "hs1.8xlarge": { + "Arch": "NATHVM64" + }, + "i2.2xlarge": { + "Arch": "NATHVM64" + }, + "i2.4xlarge": { + "Arch": "NATHVM64" + }, + "i2.8xlarge": { + "Arch": "NATHVM64" + }, + "i2.xlarge": { + "Arch": "NATHVM64" + }, + "m1.large": { + "Arch": "NATPV64" + }, + "m1.medium": { + "Arch": "NATPV64" + }, + "m1.small": { + "Arch": "NATPV64" + }, + "m1.xlarge": { + "Arch": "NATPV64" + }, + "m2.2xlarge": { + "Arch": "NATPV64" + }, + "m2.4xlarge": { + "Arch": "NATPV64" + }, + "m2.xlarge": { + "Arch": "NATPV64" + }, + "m3.2xlarge": { + "Arch": "NATHVM64" + }, + "m3.large": { + "Arch": "NATHVM64" + }, + "m3.medium": { + "Arch": "NATHVM64" + }, + "m3.xlarge": { + "Arch": "NATHVM64" + }, + "m4.10xlarge": { + "Arch": "NATHVM64" + }, + "m4.2xlarge": { + "Arch": "NATHVM64" + }, + "m4.4xlarge": { + "Arch": "NATHVM64" + }, + "m4.large": { + "Arch": "NATHVM64" + }, + "m4.xlarge": { + "Arch": "NATHVM64" + }, + "r3.2xlarge": { + "Arch": "NATHVM64" + }, + "r3.4xlarge": { + "Arch": "NATHVM64" + }, + "r3.8xlarge": { + "Arch": "NATHVM64" + }, + "r3.large": { + "Arch": "NATHVM64" + }, + "r3.xlarge": { + "Arch": "NATHVM64" + }, + "t1.micro": { + "Arch": "NATPV64" + }, + "t2.large": { + "Arch": "NATHVM64" + }, + "t2.medium": { + "Arch": "NATHVM64" + }, + "t2.micro": { + "Arch": "NATHVM64" + }, + "t2.nano": { + "Arch": "NATHVM64" + }, + "t2.small": { + "Arch": "NATHVM64" + } + }, + "AWSRegionArch2AMI": { + "ap-northeast-1": { + "HVM64": "ami-f80e0596", + "HVMG2": "ami-34a9a35a", + "PV64": "ami-37020959" + }, + "ap-northeast-2": { + "HVM64": "ami-6598510b", + "HVMG2": "NOT_SUPPORTED", + "PV64": "NOT_SUPPORTED" + }, + "ap-southeast-1": { + "HVM64": "ami-e90dc68a", + "HVMG2": "ami-6f6ca70c", + "PV64": "ami-ff0cc79c" + }, + "ap-southeast-2": { + "HVM64": "ami-f2210191", + "HVMG2": "ami-88c1e1eb", + "PV64": "ami-f5210196" + }, + "cn-north-1": { + "HVM64": "ami-49e22924", + "HVMG2": "NOT_SUPPORTED", + "PV64": "ami-08ef2465" + }, + "eu-central-1": { + "HVM64": "ami-e2df388d", + "HVMG2": "ami-5240a73d", + "PV64": "ami-2bde3944" + }, + "eu-west-1": { + "HVM64": "ami-31328842", + "HVMG2": "ami-d1d652a2", + "PV64": "ami-a5368cd6" + }, + "sa-east-1": { + "HVM64": "ami-1e159872", + "HVMG2": "NOT_SUPPORTED", + "PV64": "ami-661e930a" + }, + "us-east-1": { + "HVM64": "ami-08111162", + "HVMG2": "ami-ebcec381", + "PV64": "ami-22111148" + }, + "us-west-1": { + "HVM64": "ami-1b0f7d7b", + "HVMG2": "ami-ab9defcb", + "PV64": "ami-0e087a6e" + }, + "us-west-2": { + "HVM64": "ami-c229c0a2", + "HVMG2": "ami-0f28c06f", + "PV64": "ami-792bc219" + } + }, + "Region2Examples": { + "ap-northeast-1": { + "Examples": "https://s3-ap-northeast-1.amazonaws.com/cloudformation-examples-ap-northeast-1" + }, + "ap-northeast-2": { + "Examples": "https://s3-ap-northeast-2.amazonaws.com/cloudformation-examples-ap-northeast-2" + }, + "ap-southeast-1": { + "Examples": "https://s3-ap-southeast-1.amazonaws.com/cloudformation-examples-ap-southeast-1" + }, + "ap-southeast-2": { + "Examples": "https://s3-ap-southeast-2.amazonaws.com/cloudformation-examples-ap-southeast-2" + }, + "cn-north-1": { + "Examples": "https://s3.cn-north-1.amazonaws.com.cn/cloudformation-examples-cn-north-1" + }, + "eu-central-1": { + "Examples": "https://s3-eu-central-1.amazonaws.com/cloudformation-examples-eu-central-1" + }, + "eu-west-1": { + "Examples": "https://s3-eu-west-1.amazonaws.com/cloudformation-examples-eu-west-1" + }, + "sa-east-1": { + "Examples": "https://s3-sa-east-1.amazonaws.com/cloudformation-examples-sa-east-1" + }, + "us-east-1": { + "Examples": "https://s3.amazonaws.com/cloudformation-examples-us-east-1" + }, + "us-west-1": { + "Examples": "https://s3-us-west-1.amazonaws.com/cloudformation-examples-us-west-1" + }, + "us-west-2": { + "Examples": "https://s3-us-west-2.amazonaws.com/cloudformation-examples-us-west-2" + } + } + }, + "Outputs": { + "URL": { + "Description": "The URL of the website", + "Value": { + "Fn::Join": [ + "", + [ + "http://", + { + "Fn::GetAtt": [ + "ElasticLoadBalancer", + "DNSName" + ] + } + ] + ] + } + } + }, + "Parameters": { + "InstanceType": { + "AllowedValues": [ + "t1.micro", + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "m1.small", + "m1.medium", + "m1.large", + "m1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "c1.medium", + "c1.xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "hi1.4xlarge", + "hs1.8xlarge", + "cr1.8xlarge", + "cc2.8xlarge", + "cg1.4xlarge" + ], + "ConstraintDescription": "must be a valid EC2 instance type.", + "Default": "t2.small", + "Description": "WebServer EC2 instance type", + "Type": "String" + }, + "KeyName": { + "ConstraintDescription": "must be the name of an existing EC2 KeyPair.", + "Description": "The EC2 Key Pair to allow SSH access to the instances", + "Type": "AWS::EC2::KeyPair::KeyName" + }, + "OperatorEMail": { + "AllowedPattern": "([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)", + "ConstraintDescription": "must be a valid email address.", + "Description": "EMail address to notify if there are any scaling operations", + "Type": "String" + }, + "SSHLocation": { + "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.", + "Default": "0.0.0.0/0", + "Description": "The IP address range that can be used to SSH to the EC2 instances", + "MaxLength": "18", + "MinLength": "9", + "Type": "String" + } + }, + "Resources": { + "CPUAlarmHigh": { + "Properties": { + "AlarmActions": [ + { + "Ref": "WebServerScaleUpPolicy" + } + ], + "AlarmDescription": "Scale-up if CPU > 90% for 10 minutes", + "ComparisonOperator": "GreaterThanThreshold", + "Dimensions": [ + { + "Name": "AutoScalingGroupName", + "Value": { + "Ref": "WebServerGroup" + } + } + ], + "EvaluationPeriods": "2", + "MetricName": "CPUUtilization", + "Namespace": "AWS/EC2", + "Period": "300", + "Statistic": "Average", + "Threshold": "90" + }, + "Type": "AWS::CloudWatch::Alarm" + }, + "CPUAlarmLow": { + "Properties": { + "AlarmActions": [ + { + "Ref": "WebServerScaleDownPolicy" + } + ], + "AlarmDescription": "Scale-down if CPU < 70% for 10 minutes", + "ComparisonOperator": "LessThanThreshold", + "Dimensions": [ + { + "Name": "AutoScalingGroupName", + "Value": { + "Ref": "WebServerGroup" + } + } + ], + "EvaluationPeriods": "2", + "MetricName": "CPUUtilization", + "Namespace": "AWS/EC2", + "Period": "300", + "Statistic": "Average", + "Threshold": "70" + }, + "Type": "AWS::CloudWatch::Alarm" + }, + "ElasticLoadBalancer": { + "Properties": { + "AvailabilityZones": { + "Fn::GetAZs": "" + }, + "CrossZone": "true", + "HealthCheck": { + "HealthyThreshold": "3", + "Interval": "30", + "Target": "HTTP:80/", + "Timeout": "5", + "UnhealthyThreshold": "5" + }, + "Listeners": [ + { + "InstancePort": "80", + "LoadBalancerPort": "80", + "Protocol": "HTTP" + } + ] + }, + "Type": "AWS::ElasticLoadBalancing::LoadBalancer" + }, + "InstanceSecurityGroup": { + "Properties": { + "GroupDescription": "Enable SSH access and HTTP from the load balancer only", + "SecurityGroupIngress": [ + { + "CidrIp": { + "Ref": "SSHLocation" + }, + "FromPort": "22", + "IpProtocol": "tcp", + "ToPort": "22" + }, + { + "FromPort": "80", + "IpProtocol": "tcp", + "SourceSecurityGroupName": { + "Fn::GetAtt": [ + "ElasticLoadBalancer", + "SourceSecurityGroup.GroupName" + ] + }, + "SourceSecurityGroupOwnerId": { + "Fn::GetAtt": [ + "ElasticLoadBalancer", + "SourceSecurityGroup.OwnerAlias" + ] + }, + "ToPort": "80" + } + ] + }, + "Type": "AWS::EC2::SecurityGroup" + }, + "LaunchConfig": { + "Metadata": { + "AWS::CloudFormation::Init": { + "config": { + "files": { + "/etc/cfn/cfn-hup.conf": { + "content": { + "Fn::Join": [ + "", + [ + "[main]\n", + "stack=", + { + "Ref": "AWS::StackId" + }, + "\n", + "region=", + { + "Ref": "AWS::Region" + }, + "\n" + ] + ] + }, + "group": "root", + "mode": "000400", + "owner": "root" + }, + "/etc/cfn/hooks.d/cfn-auto-reloader.conf": { + "content": { + "Fn::Join": [ + "", + [ + "[cfn-auto-reloader-hook]\n", + "triggers=post.update\n", + "path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init\n", + "action=/opt/aws/bin/cfn-init -v ", + " --stack ", + { + "Ref": "AWS::StackName" + }, + " --resource LaunchConfig ", + " --region ", + { + "Ref": "AWS::Region" + }, + "\n", + "runas=root\n" + ] + ] + } + }, + "/var/www/html/index.html": { + "content": { + "Fn::Join": [ + "\n", + [ + "\"AWS", + "

Congratulations, you have successfully launched the AWS CloudFormation sample.

" + ] + ] + }, + "group": "root", + "mode": "000644", + "owner": "root" + } + }, + "packages": { + "yum": { + "httpd": [] + } + }, + "services": { + "sysvinit": { + "cfn-hup": { + "enabled": "true", + "ensureRunning": "true", + "files": [ + "/etc/cfn/cfn-hup.conf", + "/etc/cfn/hooks.d/cfn-auto-reloader.conf" + ] + }, + "httpd": { + "enabled": "true", + "ensureRunning": "true" + } + } + } + } + }, + "Comment": "Install a simple application" + }, + "Properties": { + "ImageId": { + "Fn::FindInMap": [ + "AWSRegionArch2AMI", + { + "Ref": "AWS::Region" + }, + { + "Fn::FindInMap": [ + "AWSInstanceType2Arch", + { + "Ref": "InstanceType" + }, + "Arch" + ] + } + ] + }, + "InstanceType": { + "Ref": "InstanceType" + }, + "KeyName": { + "Ref": "KeyName" + }, + "SecurityGroups": [ + { + "Ref": "InstanceSecurityGroup" + } + ], + "UserData": { + "Fn::Base64": { + "Fn::Join": [ + "", + [ + "#!/bin/bash -xe\n", + "yum update -y aws-cfn-bootstrap\n", + "/opt/aws/bin/cfn-init -v ", + " --stack ", + { + "Ref": "AWS::StackName" + }, + " --resource LaunchConfig ", + " --region ", + { + "Ref": "AWS::Region" + }, + "\n", + "/opt/aws/bin/cfn-signal -e $? ", + " --stack ", + { + "Ref": "AWS::StackName" + }, + " --resource WebServerGroup ", + " --region ", + { + "Ref": "AWS::Region" + }, + "\n" + ] + ] + } + } + }, + "Type": "AWS::AutoScaling::LaunchConfiguration" + }, + "NotificationTopic": { + "Properties": { + "Subscription": [ + { + "Endpoint": { + "Ref": "OperatorEMail" + }, + "Protocol": "email" + } + ] + }, + "Type": "AWS::SNS::Topic" + }, + "WebServerGroup": { + "CreationPolicy": { + "ResourceSignal": { + "Count": "1", + "Timeout": "PT15M" + } + }, + "Properties": { + "AvailabilityZones": { + "Fn::GetAZs": "" + }, + "LaunchConfigurationName": { + "Ref": "LaunchConfig" + }, + "LoadBalancerNames": [ + { + "Ref": "ElasticLoadBalancer" + } + ], + "MaxSize": "3", + "MinSize": "1", + "NotificationConfiguration": { + "NotificationTypes": [ + "autoscaling:EC2_INSTANCE_LAUNCH", + "autoscaling:EC2_INSTANCE_LAUNCH_ERROR", + "autoscaling:EC2_INSTANCE_TERMINATE", + "autoscaling:EC2_INSTANCE_TERMINATE_ERROR" + ], + "TopicARN": { + "Ref": "NotificationTopic" + } + } + }, + "Type": "AWS::AutoScaling::AutoScalingGroup", + "UpdatePolicy": { + "AutoScalingRollingUpdate": { + "MaxBatchSize": "1", + "MinInstancesInService": "1", + "PauseTime": "PT15M", + "WaitOnResourceSignals": "true" + } + } + }, + "WebServerScaleDownPolicy": { + "Properties": { + "AdjustmentType": "ChangeInCapacity", + "AutoScalingGroupName": { + "Ref": "WebServerGroup" + }, + "Cooldown": "60", + "ScalingAdjustment": "-1" + }, + "Type": "AWS::AutoScaling::ScalingPolicy" + }, + "WebServerScaleUpPolicy": { + "Properties": { + "AdjustmentType": "ChangeInCapacity", + "AutoScalingGroupName": { + "Ref": "WebServerGroup" + }, + "Cooldown": "60", + "ScalingAdjustment": "1" + }, + "Type": "AWS::AutoScaling::ScalingPolicy" + } + } +} From ed055c811a322198d0a49a34d445dd67c6d551a7 Mon Sep 17 00:00:00 2001 From: Raul Cuza Date: Sun, 10 Apr 2016 15:55:19 -0400 Subject: [PATCH 3/8] Create script that produces example --- .../AutoScalingMultiAZWithNotifications.py | 605 ++++++++++++++++++ 1 file changed, 605 insertions(+) create mode 100755 examples/AutoScalingMultiAZWithNotifications.py diff --git a/examples/AutoScalingMultiAZWithNotifications.py b/examples/AutoScalingMultiAZWithNotifications.py new file mode 100755 index 000000000..1f2ff4166 --- /dev/null +++ b/examples/AutoScalingMultiAZWithNotifications.py @@ -0,0 +1,605 @@ +#!/usr/bin/env python +""" +Converted from AutoScalingMultiAZWithNotifications.template located at: +http://aws.amazon.com/cloudformation/aws-cloudformation-templates/ + +XXX In addition to troposphere, this script requires awacs (Amazon Web Access +Control Subsystem) +""" +from __future__ import absolute_import, division, print_function + +from awacs.aws import ( + Allow, + Statement, + Principal, + Policy, + ) +from awacs.sts import AssumeRole + +from troposphere import ( + autoscaling, + Base64, + cloudformation, + cloudwatch, + constants, + ec2, + FindInMap, + GetAtt, + GetAZs, + Join, + Parameter, + Output, + Ref, + sns, + Tags, + Template, + ) +import troposphere.elasticloadbalancing as elb +# from troposphere.autoscaling import ( +# AutoScalingGroup, +# BlockDeviceMapping, +# EBSBlockDevice, +# LaunchConfiguration, +# Tag, +# ) +from troposphere.policies import ( + AutoScalingRollingUpdate, + CreationPolicy, + ResourceSignal, + UpdatePolicy, + ) + +def main(): + """ + Create a multi-az, load balanced and Auto Scaled sample web site + """ + + template = Template() + + template.add_version("2010-09-09") + + # Description + template.add_description( + 'AWS CloudFormation Sample Template AutoScalingMultiAZWithNotifications: ' + 'Create a multi-az, load balanced and Auto Scaled sample web site ' + 'running on an Apache Web Serever. The application is configured to ' + 'span all Availability Zones in the region and is Auto-Scaled based on ' + 'the CPU utilization of the web servers. Notifications will be sent to ' + 'the operator email address on scaling events. The instances are load ' + 'balanced with a simple health check against the default web page. ' + '**WARNING** This template creates one or more Amazon EC2 instances and ' + 'an Elastic Load Balancer. You will be billed for the AWS resources ' + 'used if you create a stack from this template.' + ) + + + # Mappings + template.add_mapping( + 'AWSInstanceType2Arch', { + "t1.micro" :{"Arch" : "PV64"}, + "t2.nano" :{"Arch" : "HVM64"}, + "t2.micro" :{"Arch" : "HVM64"}, + "t2.small" :{"Arch" : "HVM64"}, + "t2.medium" :{"Arch" : "HVM64"}, + "t2.large" :{"Arch" : "HVM64"}, + "m1.small" :{"Arch" : "PV64"}, + "m1.medium" :{"Arch" : "PV64"}, + "m1.large" :{"Arch" : "PV64"}, + "m1.xlarge" :{"Arch" : "PV64"}, + "m2.xlarge" :{"Arch" : "PV64"}, + "m2.2xlarge" :{"Arch" : "PV64"}, + "m2.4xlarge" :{"Arch" : "PV64"}, + "m3.medium" :{"Arch" : "HVM64"}, + "m3.large" :{"Arch" : "HVM64"}, + "m3.xlarge" :{"Arch" : "HVM64"}, + "m3.2xlarge" :{"Arch" : "HVM64"}, + "m4.large" :{"Arch" : "HVM64"}, + "m4.xlarge" :{"Arch" : "HVM64"}, + "m4.2xlarge" :{"Arch" : "HVM64"}, + "m4.4xlarge" :{"Arch" : "HVM64"}, + "m4.10xlarge" :{"Arch" : "HVM64"}, + "c1.medium" :{"Arch" : "PV64"}, + "c1.xlarge" :{"Arch" : "PV64"}, + "c3.large" :{"Arch" : "HVM64"}, + "c3.xlarge" :{"Arch" : "HVM64"}, + "c3.2xlarge" :{"Arch" : "HVM64"}, + "c3.4xlarge" :{"Arch" : "HVM64"}, + "c3.8xlarge" :{"Arch" : "HVM64"}, + "c4.large" :{"Arch" : "HVM64"}, + "c4.xlarge" :{"Arch" : "HVM64"}, + "c4.2xlarge" :{"Arch" : "HVM64"}, + "c4.4xlarge" :{"Arch" : "HVM64"}, + "c4.8xlarge" :{"Arch" : "HVM64"}, + "g2.2xlarge" :{"Arch" : "HVMG2"}, + "g2.8xlarge" :{"Arch" : "HVMG2"}, + "r3.large" :{"Arch" : "HVM64"}, + "r3.xlarge" :{"Arch" : "HVM64"}, + "r3.2xlarge" :{"Arch" : "HVM64"}, + "r3.4xlarge" :{"Arch" : "HVM64"}, + "r3.8xlarge" :{"Arch" : "HVM64"}, + "i2.xlarge" :{"Arch" : "HVM64"}, + "i2.2xlarge" :{"Arch" : "HVM64"}, + "i2.4xlarge" :{"Arch" : "HVM64"}, + "i2.8xlarge" :{"Arch" : "HVM64"}, + "d2.xlarge" :{"Arch" : "HVM64"}, + "d2.2xlarge" :{"Arch" : "HVM64"}, + "d2.4xlarge" :{"Arch" : "HVM64"}, + "d2.8xlarge" :{"Arch" : "HVM64"}, + "hi1.4xlarge" :{"Arch" : "HVM64"}, + "hs1.8xlarge" :{"Arch" : "HVM64"}, + "cr1.8xlarge" :{"Arch" : "HVM64"}, + "cc2.8xlarge" :{"Arch" : "HVM64"}, + } + ) + + template.add_mapping( + "AWSInstanceType2NATArch", { + "t1.micro" :{"Arch" : "NATPV64"}, + "t2.nano" :{"Arch" : "NATHVM64"}, + "t2.micro" :{"Arch" : "NATHVM64"}, + "t2.small" :{"Arch" : "NATHVM64"}, + "t2.medium" :{"Arch" : "NATHVM64"}, + "t2.large" :{"Arch" : "NATHVM64"}, + "m1.small" :{"Arch" : "NATPV64"}, + "m1.medium" :{"Arch" : "NATPV64"}, + "m1.large" :{"Arch" : "NATPV64"}, + "m1.xlarge" :{"Arch" : "NATPV64"}, + "m2.xlarge" :{"Arch" : "NATPV64"}, + "m2.2xlarge" :{"Arch" : "NATPV64"}, + "m2.4xlarge" :{"Arch" : "NATPV64"}, + "m3.medium" :{"Arch" : "NATHVM64"}, + "m3.large" :{"Arch" : "NATHVM64"}, + "m3.xlarge" :{"Arch" : "NATHVM64"}, + "m3.2xlarge" :{"Arch" : "NATHVM64"}, + "m4.large" :{"Arch" : "NATHVM64"}, + "m4.xlarge" :{"Arch" : "NATHVM64"}, + "m4.2xlarge" :{"Arch" : "NATHVM64"}, + "m4.4xlarge" :{"Arch" : "NATHVM64"}, + "m4.10xlarge" :{"Arch" : "NATHVM64"}, + "c1.medium" :{"Arch" : "NATPV64"}, + "c1.xlarge" :{"Arch" : "NATPV64"}, + "c3.large" :{"Arch" : "NATHVM64"}, + "c3.xlarge" :{"Arch" : "NATHVM64"}, + "c3.2xlarge" :{"Arch" : "NATHVM64"}, + "c3.4xlarge" :{"Arch" : "NATHVM64"}, + "c3.8xlarge" :{"Arch" : "NATHVM64"}, + "c4.large" :{"Arch" : "NATHVM64"}, + "c4.xlarge" :{"Arch" : "NATHVM64"}, + "c4.2xlarge" :{"Arch" : "NATHVM64"}, + "c4.4xlarge" :{"Arch" : "NATHVM64"}, + "c4.8xlarge" :{"Arch" : "NATHVM64"}, + "g2.2xlarge" :{"Arch" : "NATHVMG2"}, + "g2.8xlarge" :{"Arch" : "NATHVMG2"}, + "r3.large" :{"Arch" : "NATHVM64"}, + "r3.xlarge" :{"Arch" : "NATHVM64"}, + "r3.2xlarge" :{"Arch" : "NATHVM64"}, + "r3.4xlarge" :{"Arch" : "NATHVM64"}, + "r3.8xlarge" :{"Arch" : "NATHVM64"}, + "i2.xlarge" :{"Arch" : "NATHVM64"}, + "i2.2xlarge" :{"Arch" : "NATHVM64"}, + "i2.4xlarge" :{"Arch" : "NATHVM64"}, + "i2.8xlarge" :{"Arch" : "NATHVM64"}, + "d2.xlarge" :{"Arch" : "NATHVM64"}, + "d2.2xlarge" :{"Arch" : "NATHVM64"}, + "d2.4xlarge" :{"Arch" : "NATHVM64"}, + "d2.8xlarge" :{"Arch" : "NATHVM64"}, + "hi1.4xlarge" :{"Arch" : "NATHVM64"}, + "hs1.8xlarge" :{"Arch" : "NATHVM64"}, + "cr1.8xlarge" :{"Arch" : "NATHVM64"}, + "cc2.8xlarge" :{"Arch" : "NATHVM64"}, + } + ) + + template.add_mapping( + "AWSRegionArch2AMI", { + "us-east-1" :{"PV64" : "ami-22111148", "HVM64" : "ami-08111162", "HVMG2" : "ami-ebcec381"}, + "us-west-2" :{"PV64" : "ami-792bc219", "HVM64" : "ami-c229c0a2", "HVMG2" : "ami-0f28c06f"}, + "us-west-1" :{"PV64" : "ami-0e087a6e", "HVM64" : "ami-1b0f7d7b", "HVMG2" : "ami-ab9defcb"}, + "eu-west-1" :{"PV64" : "ami-a5368cd6", "HVM64" : "ami-31328842", "HVMG2" : "ami-d1d652a2"}, + "eu-central-1" :{"PV64" : "ami-2bde3944", "HVM64" : "ami-e2df388d", "HVMG2" : "ami-5240a73d"}, + "ap-northeast-1" :{"PV64" : "ami-37020959", "HVM64" : "ami-f80e0596", "HVMG2" : "ami-34a9a35a"}, + "ap-northeast-2" :{"PV64" : "NOT_SUPPORTED", "HVM64" : "ami-6598510b", "HVMG2" : "NOT_SUPPORTED"}, + "ap-southeast-1" :{"PV64" : "ami-ff0cc79c", "HVM64" : "ami-e90dc68a", "HVMG2" : "ami-6f6ca70c"}, + "ap-southeast-2" :{"PV64" : "ami-f5210196", "HVM64" : "ami-f2210191", "HVMG2" : "ami-88c1e1eb"}, + "sa-east-1" :{"PV64" : "ami-661e930a", "HVM64" : "ami-1e159872", "HVMG2" : "NOT_SUPPORTED"}, + "cn-north-1" :{"PV64" : "ami-08ef2465", "HVM64" : "ami-49e22924", "HVMG2" : "NOT_SUPPORTED"} + } + ) + + template.add_mapping( + "Region2Examples", { + "us-east-1" :{"Examples":"https://s3.amazonaws.com/cloudformation-examples-us-east-1"}, + "us-west-2" :{"Examples":"https://s3-us-west-2.amazonaws.com/cloudformation-examples-us-west-2"}, + "us-west-1" :{"Examples":"https://s3-us-west-1.amazonaws.com/cloudformation-examples-us-west-1"}, + "eu-west-1" :{"Examples":"https://s3-eu-west-1.amazonaws.com/cloudformation-examples-eu-west-1"}, + "eu-central-1" :{"Examples":"https://s3-eu-central-1.amazonaws.com/cloudformation-examples-eu-central-1"}, + "ap-southeast-1":{"Examples":"https://s3-ap-southeast-1.amazonaws.com/cloudformation-examples-ap-southeast-1"}, + "ap-northeast-1":{"Examples":"https://s3-ap-northeast-1.amazonaws.com/cloudformation-examples-ap-northeast-1"}, + "ap-northeast-2":{"Examples":"https://s3-ap-northeast-2.amazonaws.com/cloudformation-examples-ap-northeast-2"}, + "ap-southeast-2":{"Examples":"https://s3-ap-southeast-2.amazonaws.com/cloudformation-examples-ap-southeast-2"}, + "sa-east-1" :{"Examples":"https://s3-sa-east-1.amazonaws.com/cloudformation-examples-sa-east-1"}, + "cn-north-1" :{"Examples":"https://s3.cn-north-1.amazonaws.com.cn/cloudformation-examples-cn-north-1"} + } + ) + + + # Parameters + + allowedinstancetype = [ + "t1.micro", + "t2.nano", + "t2.micro", + "t2.small", + "t2.medium", + "t2.large", + "m1.small", + "m1.medium", + "m1.large", + "m1.xlarge", + "m2.xlarge", + "m2.2xlarge", + "m2.4xlarge", + "m3.medium", + "m3.large", + "m3.xlarge", + "m3.2xlarge", + "m4.large", + "m4.xlarge", + "m4.2xlarge", + "m4.4xlarge", + "m4.10xlarge", + "c1.medium", + "c1.xlarge", + "c3.large", + "c3.xlarge", + "c3.2xlarge", + "c3.4xlarge", + "c3.8xlarge", + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "g2.2xlarge", + "g2.8xlarge", + "r3.large", + "r3.xlarge", + "r3.2xlarge", + "r3.4xlarge", + "r3.8xlarge", + "i2.xlarge", + "i2.2xlarge", + "i2.4xlarge", + "i2.8xlarge", + "d2.xlarge", + "d2.2xlarge", + "d2.4xlarge", + "d2.8xlarge", + "hi1.4xlarge", + "hs1.8xlarge", + "cr1.8xlarge", + "cc2.8xlarge", + "cg1.4xlarge", + ] + + instancetype = template.add_parameter(Parameter( + 'InstanceType', + Description='WebServer EC2 instance type', + Type='String', + Default='t2.small', + AllowedValues=allowedinstancetype, + ConstraintDescription='must be a valid EC2 instance type.', + )) + + keyname = template.add_parameter(Parameter( + 'KeyName', + Description='The EC2 Key Pair to allow SSH access to the instances', + Type='AWS::EC2::KeyPair::KeyName', + ConstraintDescription='must be the name of an existing EC2 KeyPair.', + )) + + operatoremail = template.add_parameter(Parameter( + 'OperatorEMail', + AllowedPattern=( + '([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.' + '[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9' + '\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)' + ), + ConstraintDescription="must be a valid email address.", + Description="EMail address to notify if there are any scaling operations", + Type=constants.STRING, + )) + + sshlocation = template.add_parameter(Parameter( + '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.' + )) + + # XXX Resources + + cpualarmhigh = template.add_resource( + cloudwatch.Alarm( + 'CPUAlarmHigh', + # XXX + AlarmActions=[Ref('WebServerScaleUpPolicy')], + AlarmDescription='Scale-up if CPU > 90% for 10 minutes', + ComparisonOperator='GreaterThanThreshold', + Dimensions=[cloudwatch.MetricDimension( + Name='AutoScalingGroupName', + # XXX + Value=Ref('WebServerGroup'), + )], + EvaluationPeriods='2', + MetricName='CPUUtilization', + Namespace='AWS/EC2', + Period='300', + Statistic='Average', + Threshold='90', + ) + ) + + cpualarmlow = template.add_resource( + cloudwatch.Alarm( + 'CPUAlarmLow', + # XXX + AlarmActions=[Ref('WebServerScaleDownPolicy')], + AlarmDescription='Scale-down if CPU < 70% for 10 minutes', + ComparisonOperator='LessThanThreshold', + Dimensions=[cloudwatch.MetricDimension( + Name='AutoScalingGroupName', + # XXX + Value=Ref('WebServerGroup'), + )], + EvaluationPeriods='2', + MetricName='CPUUtilization', + Namespace='AWS/EC2', + Period='300', + Statistic='Average', + Threshold='70', + ) + ) + + r_elb = template.add_resource( + elb.LoadBalancer( + 'ElasticLoadBalancer', + AvailabilityZones=GetAZs(''), + CrossZone=True, + HealthCheck=elb.HealthCheck( + HealthyThreshold='3', + Interval='30', + Target='HTTP:80/', + Timeout='5', + UnhealthyThreshold='5', + ), + Listeners=[ + elb.Listener( + InstancePort='80', + LoadBalancerPort='80', + Protocol='HTTP', + ) + ], + ) + ) + + r_snstopic = template.add_resource( + sns.Topic( + 'NotificationTopic', + Subscription=[ + sns.Subscription( + 'NotificationSubscription', + Endpoint=Ref(operatoremail), + Protocol='email', + ) + ] + ) + ) + webservergroup = template.add_resource(autoscaling.AutoScalingGroup( + 'WebServerGroup', + AvailabilityZones=GetAZs(''), + CreationPolicy=CreationPolicy( + ResourceSignal=ResourceSignal( + Count='1', + Timeout='PT15M', + ) + ), + LaunchConfigurationName=Ref('LaunchConfig'), + LoadBalancerNames=[Ref('ElasticLoadBalancer')], + MinSize='1', + MaxSize='3', + NotificationConfigurations=[ + # XXX Example isn't in a list but troposphere wont build unless it is a list + autoscaling.NotificationConfigurations( + NotificationTypes=[ + "autoscaling:EC2_INSTANCE_LAUNCH", + "autoscaling:EC2_INSTANCE_LAUNCH_ERROR", + "autoscaling:EC2_INSTANCE_TERMINATE", + "autoscaling:EC2_INSTANCE_TERMINATE_ERROR" + ], + TopicARN=Ref('NotificationTopic'), + ) + ], + UpdatePolicy=UpdatePolicy( + AutoScalingRollingUpdate=AutoScalingRollingUpdate( + PauseTime='PT15M', + MinInstancesInService="1", + MaxBatchSize='1', + WaitOnResourceSignals=True + ) + ) + )) + + webservscaleup_policy = template.add_resource(autoscaling.ScalingPolicy( + "WebServerScaleUpPolicy", + AdjustmentType='ChangeInCapacity', + AutoScalingGroupName=Ref(webservergroup), + Cooldown='60', + ScalingAdjustment='1', + )) + + webservscaledown_policy = template.add_resource(autoscaling.ScalingPolicy( + "WebServerScaleDownPolicy", + AdjustmentType='ChangeInCapacity', + AutoScalingGroupName=Ref(webservergroup), + Cooldown='60', + ScalingAdjustment='-1', + )) + + webserversg = template.add_resource(ec2.SecurityGroup( + 'InstanceSecurityGroup', + GroupDescription='Enable SSH access and HTTP from the load balancer only', + SecurityGroupIngress=[ + ec2.SecurityGroupRule( + IpProtocol='tcp', + FromPort='22', + ToPort='22', + CidrIp=Ref(sshlocation), + ), + ec2.SecurityGroupRule( + IpProtocol='tcp', + FromPort='80', + ToPort='80', + SourceSecurityGroupName=GetAtt( + 'ElasticLoadBalancer', + 'SourceSecurityGroup.GroupName', + ), + SourceSecurityGroupOwnerId=GetAtt( + 'ElasticLoadBalancer', + 'SourceSecurityGroup.OwnerAlias', + ), + ) + ] + )) + + r_launchconfig = template.add_resource( + autoscaling.LaunchConfiguration( + 'LaunchConfig', + Metadata=cloudformation.Metadata( + cloudformation.Init({ + 'config': cloudformation.InitConfig( + packages={ + 'yum': { + 'httpd': [], + } + }, + + files=cloudformation.InitFiles({ + '/var/www/html/index.html': cloudformation.InitFile( + content=Join('\n', [ + "\"AWS', + '

Congratulations, you have successfully launched the AWS CloudFormation sample.

', + ]), + mode='000644', + owner='root', + group='root' + ), + + '/etc/cfn/cfn-hup.conf': cloudformation.InitFile( + content=Join('', [ + '[main]\n', + 'stack=', Ref('AWS::StackId'), '\n', + 'region=', Ref('AWS::Region'), '\n' + ]), + mode='000400', + owner='root', + group='root' + ), + '/etc/cfn/hooks.d/cfn-auto-reloader.conf': + cloudformation.InitFile( + content=Join('', [ + '[cfn-auto-reloader-hook]\n', + 'triggers=post.update\n', + 'path=Resources.LaunchConfig.Metadata' + '.AWS::CloudFormation::Init\n', + 'action=/opt/aws/bin/cfn-init -v ', + ' --stack ', Ref('AWS::StackName'), + ' --resource LaunchConfig ', + ' --region ', Ref('AWS::Region'), + '\n', + 'runas=root\n' + ]), + # Why doesn't the Amazon template have this? + # mode='000400', + # owner='root', + # group='root' + ), + }), + services={ + "sysvinit": cloudformation.InitServices({ + "httpd": cloudformation.InitService( + enabled=True, + ensureRunning=True, + ), + "cfn-hup": cloudformation.InitService( + enabled=True, + ensureRunning=True, + files=['/etc/cfn/cfn-hup.conf', + '/etc/cfn/hooks.d/' + 'cfn-auto-reloader.conf'] + ), + }), + }, + ) + }) + ), + # XXX How do I add the comment to the Metadata? Troposphere errors out + #Comment='Install a simple application', + ImageId=FindInMap('AWSRegionArch2AMI', Ref('AWS::Region'), + FindInMap('AWSInstanceType2Arch', + Ref(instancetype), 'Arch')), + InstanceType=Ref(instancetype), + SecurityGroups=[Ref(webserversg)], + KeyName=Ref(keyname), + UserData=Base64(Join('', [ + '#!/bin/bash -xe\n', + 'yum update -y aws-cfn-bootstrap\n', + + '/opt/aws/bin/cfn-init -v ', + ' --stack ', Ref('AWS::StackName'), + ' --resource LaunchConfig ', + ' --region ', Ref('AWS::Region'), '\n', + + '/opt/aws/bin/cfn-signal -e $? ', + ' --stack ', Ref('AWS::StackName'), + ' --resource WebServerGroup ', + ' --region ', Ref('AWS::Region'), '\n' + ])), + #Tags=autoscaling.Tags(Application=Ref('AWS::StackId'), + # Details='Created using Troposhpere') + )) + + # Outputs + template.add_output([ + Output( + 'URL', + Description='The URL of the website', + # XXX + Value=Join('', [ + 'http://', + GetAtt('ElasticLoadBalancer', 'DNSName'), + ]) + ) + ]) + + # Print CloudFormation Template + print(template.to_json()) + + +if __name__ == '__main__': + main() From 7d6b26a272d074074835e1e04ebc836812f75d0c Mon Sep 17 00:00:00 2001 From: Raul Cuza Date: Mon, 11 Apr 2016 02:17:16 -0400 Subject: [PATCH 4/8] Add Comment class to cloudformation The AWS example template as a Comment key in the Metadata of the cloudformation template. I added a Comment class to create this object. --- examples/AutoScalingMultiAZWithNotifications.py | 6 +++--- troposphere/cloudformation.py | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/AutoScalingMultiAZWithNotifications.py b/examples/AutoScalingMultiAZWithNotifications.py index 1f2ff4166..857a7fc87 100755 --- a/examples/AutoScalingMultiAZWithNotifications.py +++ b/examples/AutoScalingMultiAZWithNotifications.py @@ -555,11 +555,11 @@ def main(): ), }), }, - ) - }) + ), + }), + cloudformation.Comment('Install a simple application'), ), # XXX How do I add the comment to the Metadata? Troposphere errors out - #Comment='Install a simple application', ImageId=FindInMap('AWSRegionArch2AMI', Ref('AWS::Region'), FindInMap('AWSInstanceType2Arch', Ref(instancetype), 'Arch')), diff --git a/troposphere/cloudformation.py b/troposphere/cloudformation.py index 1fbdc93b1..1e6729bad 100644 --- a/troposphere/cloudformation.py +++ b/troposphere/cloudformation.py @@ -70,6 +70,12 @@ def to_dict(self): t += encode_to_dict(i).items() return dict(t) +class Comment(AWSHelperFn): + def __init__(self, data): + self.data = {'Comment': data} + + def JSONrepr(self): + return self.data class InitFileContext(AWSHelperFn): def __init__(self, data): From b7cc86578e409f3c291aac8808cc6d1592346057 Mon Sep 17 00:00:00 2001 From: Raul Cuza Date: Mon, 11 Apr 2016 02:31:05 -0400 Subject: [PATCH 5/8] Modified AWS Template to match AWS CFN docs According to the Cloudformation documentation, "AWS::AutoScaling::AutoScalingGroup" types have a property "NotificationConfigurations" that is a list. The original template has the singular and it isn't a list. Troposphere wouldn't build the template using this property. --- .../AutoScalingMultiAZWithNotifications.py | 4 ++-- ...toScalingMultiAZWithNotifications.template | 22 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/examples/AutoScalingMultiAZWithNotifications.py b/examples/AutoScalingMultiAZWithNotifications.py index 857a7fc87..326c9a1af 100755 --- a/examples/AutoScalingMultiAZWithNotifications.py +++ b/examples/AutoScalingMultiAZWithNotifications.py @@ -418,8 +418,8 @@ def main(): MinSize='1', MaxSize='3', NotificationConfigurations=[ - # XXX Example isn't in a list but troposphere wont build unless it is a list autoscaling.NotificationConfigurations( + 'NotificationConfiguration', NotificationTypes=[ "autoscaling:EC2_INSTANCE_LAUNCH", "autoscaling:EC2_INSTANCE_LAUNCH_ERROR", @@ -427,7 +427,7 @@ def main(): "autoscaling:EC2_INSTANCE_TERMINATE_ERROR" ], TopicARN=Ref('NotificationTopic'), - ) + ), ], UpdatePolicy=UpdatePolicy( AutoScalingRollingUpdate=AutoScalingRollingUpdate( diff --git a/tests/examples_output/AutoScalingMultiAZWithNotifications.template b/tests/examples_output/AutoScalingMultiAZWithNotifications.template index 71baf319d..1243e4574 100644 --- a/tests/examples_output/AutoScalingMultiAZWithNotifications.template +++ b/tests/examples_output/AutoScalingMultiAZWithNotifications.template @@ -830,17 +830,19 @@ ], "MaxSize": "3", "MinSize": "1", - "NotificationConfiguration": { - "NotificationTypes": [ - "autoscaling:EC2_INSTANCE_LAUNCH", - "autoscaling:EC2_INSTANCE_LAUNCH_ERROR", - "autoscaling:EC2_INSTANCE_TERMINATE", - "autoscaling:EC2_INSTANCE_TERMINATE_ERROR" - ], - "TopicARN": { - "Ref": "NotificationTopic" + "NotificationConfigurations": [ + { + "NotificationTypes": [ + "autoscaling:EC2_INSTANCE_LAUNCH", + "autoscaling:EC2_INSTANCE_LAUNCH_ERROR", + "autoscaling:EC2_INSTANCE_TERMINATE", + "autoscaling:EC2_INSTANCE_TERMINATE_ERROR" + ], + "TopicARN": { + "Ref": "NotificationTopic" + } } - } + ] }, "Type": "AWS::AutoScaling::AutoScalingGroup", "UpdatePolicy": { From 8e0472b233448817e968528ee8f06d1e1c9720fa Mon Sep 17 00:00:00 2001 From: Raul Cuza Date: Mon, 11 Apr 2016 02:36:24 -0400 Subject: [PATCH 6/8] Add blank lines to meet standards --- troposphere/cloudformation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/troposphere/cloudformation.py b/troposphere/cloudformation.py index 1e6729bad..6620eb626 100644 --- a/troposphere/cloudformation.py +++ b/troposphere/cloudformation.py @@ -70,6 +70,7 @@ def to_dict(self): t += encode_to_dict(i).items() return dict(t) + class Comment(AWSHelperFn): def __init__(self, data): self.data = {'Comment': data} @@ -77,6 +78,7 @@ def __init__(self, data): def JSONrepr(self): return self.data + class InitFileContext(AWSHelperFn): def __init__(self, data): self.data = data From a99628fb4578faa63bc0c2de347a1990954dd72b Mon Sep 17 00:00:00 2001 From: Raul Cuza Date: Mon, 11 Apr 2016 02:51:37 -0400 Subject: [PATCH 7/8] Refactor to pass pyflakes standards --- .../AutoScalingMultiAZWithNotifications.py | 198 +++++++++--------- 1 file changed, 94 insertions(+), 104 deletions(-) diff --git a/examples/AutoScalingMultiAZWithNotifications.py b/examples/AutoScalingMultiAZWithNotifications.py index 326c9a1af..1b5c565cc 100755 --- a/examples/AutoScalingMultiAZWithNotifications.py +++ b/examples/AutoScalingMultiAZWithNotifications.py @@ -2,20 +2,9 @@ """ Converted from AutoScalingMultiAZWithNotifications.template located at: http://aws.amazon.com/cloudformation/aws-cloudformation-templates/ - -XXX In addition to troposphere, this script requires awacs (Amazon Web Access -Control Subsystem) """ from __future__ import absolute_import, division, print_function -from awacs.aws import ( - Allow, - Statement, - Principal, - Policy, - ) -from awacs.sts import AssumeRole - from troposphere import ( autoscaling, Base64, @@ -31,7 +20,6 @@ Output, Ref, sns, - Tags, Template, ) import troposphere.elasticloadbalancing as elb @@ -328,47 +316,7 @@ def main(): # XXX Resources - cpualarmhigh = template.add_resource( - cloudwatch.Alarm( - 'CPUAlarmHigh', - # XXX - AlarmActions=[Ref('WebServerScaleUpPolicy')], - AlarmDescription='Scale-up if CPU > 90% for 10 minutes', - ComparisonOperator='GreaterThanThreshold', - Dimensions=[cloudwatch.MetricDimension( - Name='AutoScalingGroupName', - # XXX - Value=Ref('WebServerGroup'), - )], - EvaluationPeriods='2', - MetricName='CPUUtilization', - Namespace='AWS/EC2', - Period='300', - Statistic='Average', - Threshold='90', - ) - ) - cpualarmlow = template.add_resource( - cloudwatch.Alarm( - 'CPUAlarmLow', - # XXX - AlarmActions=[Ref('WebServerScaleDownPolicy')], - AlarmDescription='Scale-down if CPU < 70% for 10 minutes', - ComparisonOperator='LessThanThreshold', - Dimensions=[cloudwatch.MetricDimension( - Name='AutoScalingGroupName', - # XXX - Value=Ref('WebServerGroup'), - )], - EvaluationPeriods='2', - MetricName='CPUUtilization', - Namespace='AWS/EC2', - Period='300', - Statistic='Average', - Threshold='70', - ) - ) r_elb = template.add_resource( elb.LoadBalancer( @@ -404,56 +352,8 @@ def main(): ] ) ) - webservergroup = template.add_resource(autoscaling.AutoScalingGroup( - 'WebServerGroup', - AvailabilityZones=GetAZs(''), - CreationPolicy=CreationPolicy( - ResourceSignal=ResourceSignal( - Count='1', - Timeout='PT15M', - ) - ), - LaunchConfigurationName=Ref('LaunchConfig'), - LoadBalancerNames=[Ref('ElasticLoadBalancer')], - MinSize='1', - MaxSize='3', - NotificationConfigurations=[ - autoscaling.NotificationConfigurations( - 'NotificationConfiguration', - NotificationTypes=[ - "autoscaling:EC2_INSTANCE_LAUNCH", - "autoscaling:EC2_INSTANCE_LAUNCH_ERROR", - "autoscaling:EC2_INSTANCE_TERMINATE", - "autoscaling:EC2_INSTANCE_TERMINATE_ERROR" - ], - TopicARN=Ref('NotificationTopic'), - ), - ], - UpdatePolicy=UpdatePolicy( - AutoScalingRollingUpdate=AutoScalingRollingUpdate( - PauseTime='PT15M', - MinInstancesInService="1", - MaxBatchSize='1', - WaitOnResourceSignals=True - ) - ) - )) - webservscaleup_policy = template.add_resource(autoscaling.ScalingPolicy( - "WebServerScaleUpPolicy", - AdjustmentType='ChangeInCapacity', - AutoScalingGroupName=Ref(webservergroup), - Cooldown='60', - ScalingAdjustment='1', - )) - webservscaledown_policy = template.add_resource(autoscaling.ScalingPolicy( - "WebServerScaleDownPolicy", - AdjustmentType='ChangeInCapacity', - AutoScalingGroupName=Ref(webservergroup), - Cooldown='60', - ScalingAdjustment='-1', - )) webserversg = template.add_resource(ec2.SecurityGroup( 'InstanceSecurityGroup', @@ -470,11 +370,11 @@ def main(): FromPort='80', ToPort='80', SourceSecurityGroupName=GetAtt( - 'ElasticLoadBalancer', + r_elb, 'SourceSecurityGroup.GroupName', ), SourceSecurityGroupOwnerId=GetAtt( - 'ElasticLoadBalancer', + r_elb, 'SourceSecurityGroup.OwnerAlias', ), ) @@ -572,11 +472,13 @@ def main(): '/opt/aws/bin/cfn-init -v ', ' --stack ', Ref('AWS::StackName'), + # resource is name of this LaunchConfig ' --resource LaunchConfig ', ' --region ', Ref('AWS::Region'), '\n', '/opt/aws/bin/cfn-signal -e $? ', ' --stack ', Ref('AWS::StackName'), + # resource is name of r_webservergroup variable ' --resource WebServerGroup ', ' --region ', Ref('AWS::Region'), '\n' ])), @@ -584,15 +486,103 @@ def main(): # Details='Created using Troposhpere') )) + r_webservergroup = template.add_resource(autoscaling.AutoScalingGroup( + 'WebServerGroup', + AvailabilityZones=GetAZs(''), + CreationPolicy=CreationPolicy( + ResourceSignal=ResourceSignal( + Count='1', + Timeout='PT15M', + ) + ), + LaunchConfigurationName=Ref(r_launchconfig), + LoadBalancerNames=[Ref(r_elb)], + MinSize='1', + MaxSize='3', + NotificationConfigurations=[ + autoscaling.NotificationConfigurations( + 'NotificationConfiguration', + NotificationTypes=[ + "autoscaling:EC2_INSTANCE_LAUNCH", + "autoscaling:EC2_INSTANCE_LAUNCH_ERROR", + "autoscaling:EC2_INSTANCE_TERMINATE", + "autoscaling:EC2_INSTANCE_TERMINATE_ERROR" + ], + TopicARN=Ref(r_snstopic), + ), + ], + UpdatePolicy=UpdatePolicy( + AutoScalingRollingUpdate=AutoScalingRollingUpdate( + PauseTime='PT15M', + MinInstancesInService="1", + MaxBatchSize='1', + WaitOnResourceSignals=True + ) + ) + )) + + webservscaleup_policy = template.add_resource(autoscaling.ScalingPolicy( + "WebServerScaleUpPolicy", + AdjustmentType='ChangeInCapacity', + AutoScalingGroupName=Ref(r_webservergroup), + Cooldown='60', + ScalingAdjustment='1', + )) + + webservscaledown_policy = template.add_resource(autoscaling.ScalingPolicy( + "WebServerScaleDownPolicy", + AdjustmentType='ChangeInCapacity', + AutoScalingGroupName=Ref(r_webservergroup), + Cooldown='60', + ScalingAdjustment='-1', + )) + + template.add_resource( + cloudwatch.Alarm( + 'CPUAlarmHigh', + AlarmActions=[Ref(webservscaleup_policy)], + AlarmDescription='Scale-up if CPU > 90% for 10 minutes', + ComparisonOperator='GreaterThanThreshold', + Dimensions=[cloudwatch.MetricDimension( + Name='AutoScalingGroupName', + Value=Ref(r_webservergroup), + )], + EvaluationPeriods='2', + MetricName='CPUUtilization', + Namespace='AWS/EC2', + Period='300', + Statistic='Average', + Threshold='90', + ) + ) + + template.add_resource( + cloudwatch.Alarm( + 'CPUAlarmLow', + AlarmActions=[Ref(webservscaledown_policy)], + AlarmDescription='Scale-down if CPU < 70% for 10 minutes', + ComparisonOperator='LessThanThreshold', + Dimensions=[cloudwatch.MetricDimension( + Name='AutoScalingGroupName', + Value=Ref(r_webservergroup), + )], + EvaluationPeriods='2', + MetricName='CPUUtilization', + Namespace='AWS/EC2', + Period='300', + Statistic='Average', + Threshold='70', + ) + ) + # Outputs template.add_output([ Output( 'URL', Description='The URL of the website', - # XXX Value=Join('', [ 'http://', - GetAtt('ElasticLoadBalancer', 'DNSName'), + GetAtt(r_elb, 'DNSName'), ]) ) ]) From 36982d6d9bebe027903758c9fa4ae5409ea6f3ef Mon Sep 17 00:00:00 2001 From: Raul Cuza Date: Mon, 11 Apr 2016 03:41:22 -0400 Subject: [PATCH 8/8] Make code harder to read Adjust line lengths to match 79 character preference --- .../AutoScalingMultiAZWithNotifications.py | 399 ++++++++++-------- 1 file changed, 231 insertions(+), 168 deletions(-) diff --git a/examples/AutoScalingMultiAZWithNotifications.py b/examples/AutoScalingMultiAZWithNotifications.py index 1b5c565cc..3d7f6df25 100755 --- a/examples/AutoScalingMultiAZWithNotifications.py +++ b/examples/AutoScalingMultiAZWithNotifications.py @@ -37,6 +37,7 @@ UpdatePolicy, ) + def main(): """ Create a multi-az, load balanced and Auto Scaled sample web site @@ -48,169 +49,230 @@ def main(): # Description template.add_description( - 'AWS CloudFormation Sample Template AutoScalingMultiAZWithNotifications: ' - 'Create a multi-az, load balanced and Auto Scaled sample web site ' - 'running on an Apache Web Serever. The application is configured to ' - 'span all Availability Zones in the region and is Auto-Scaled based on ' - 'the CPU utilization of the web servers. Notifications will be sent to ' - 'the operator email address on scaling events. The instances are load ' - 'balanced with a simple health check against the default web page. ' - '**WARNING** This template creates one or more Amazon EC2 instances and ' - 'an Elastic Load Balancer. You will be billed for the AWS resources ' - 'used if you create a stack from this template.' + 'AWS CloudFormation Sample Template ' + 'AutoScalingMultiAZWithNotifications: Create a multi-az, load ' + 'balanced and Auto Scaled sample web site running on an Apache ' + 'Web Serever. The application is configured to ' + 'span all Availability Zones in the region and is Auto-Scaled ' + 'based on the CPU utilization of the web servers. Notifications ' + 'will be sent to the operator email address on scaling events. ' + 'The instances are load balanced with a simple health check ' + 'against the default web page. **WARNING** This template creates ' + 'one or more Amazon EC2 instances and an Elastic Load Balancer. ' + 'You will be billed for the AWS resources used if you create a ' + 'stack from this template.' ) - # Mappings template.add_mapping( 'AWSInstanceType2Arch', { - "t1.micro" :{"Arch" : "PV64"}, - "t2.nano" :{"Arch" : "HVM64"}, - "t2.micro" :{"Arch" : "HVM64"}, - "t2.small" :{"Arch" : "HVM64"}, - "t2.medium" :{"Arch" : "HVM64"}, - "t2.large" :{"Arch" : "HVM64"}, - "m1.small" :{"Arch" : "PV64"}, - "m1.medium" :{"Arch" : "PV64"}, - "m1.large" :{"Arch" : "PV64"}, - "m1.xlarge" :{"Arch" : "PV64"}, - "m2.xlarge" :{"Arch" : "PV64"}, - "m2.2xlarge" :{"Arch" : "PV64"}, - "m2.4xlarge" :{"Arch" : "PV64"}, - "m3.medium" :{"Arch" : "HVM64"}, - "m3.large" :{"Arch" : "HVM64"}, - "m3.xlarge" :{"Arch" : "HVM64"}, - "m3.2xlarge" :{"Arch" : "HVM64"}, - "m4.large" :{"Arch" : "HVM64"}, - "m4.xlarge" :{"Arch" : "HVM64"}, - "m4.2xlarge" :{"Arch" : "HVM64"}, - "m4.4xlarge" :{"Arch" : "HVM64"}, - "m4.10xlarge" :{"Arch" : "HVM64"}, - "c1.medium" :{"Arch" : "PV64"}, - "c1.xlarge" :{"Arch" : "PV64"}, - "c3.large" :{"Arch" : "HVM64"}, - "c3.xlarge" :{"Arch" : "HVM64"}, - "c3.2xlarge" :{"Arch" : "HVM64"}, - "c3.4xlarge" :{"Arch" : "HVM64"}, - "c3.8xlarge" :{"Arch" : "HVM64"}, - "c4.large" :{"Arch" : "HVM64"}, - "c4.xlarge" :{"Arch" : "HVM64"}, - "c4.2xlarge" :{"Arch" : "HVM64"}, - "c4.4xlarge" :{"Arch" : "HVM64"}, - "c4.8xlarge" :{"Arch" : "HVM64"}, - "g2.2xlarge" :{"Arch" : "HVMG2"}, - "g2.8xlarge" :{"Arch" : "HVMG2"}, - "r3.large" :{"Arch" : "HVM64"}, - "r3.xlarge" :{"Arch" : "HVM64"}, - "r3.2xlarge" :{"Arch" : "HVM64"}, - "r3.4xlarge" :{"Arch" : "HVM64"}, - "r3.8xlarge" :{"Arch" : "HVM64"}, - "i2.xlarge" :{"Arch" : "HVM64"}, - "i2.2xlarge" :{"Arch" : "HVM64"}, - "i2.4xlarge" :{"Arch" : "HVM64"}, - "i2.8xlarge" :{"Arch" : "HVM64"}, - "d2.xlarge" :{"Arch" : "HVM64"}, - "d2.2xlarge" :{"Arch" : "HVM64"}, - "d2.4xlarge" :{"Arch" : "HVM64"}, - "d2.8xlarge" :{"Arch" : "HVM64"}, - "hi1.4xlarge" :{"Arch" : "HVM64"}, - "hs1.8xlarge" :{"Arch" : "HVM64"}, - "cr1.8xlarge" :{"Arch" : "HVM64"}, - "cc2.8xlarge" :{"Arch" : "HVM64"}, + "t1.micro": {"Arch": "PV64"}, + "t2.nano": {"Arch": "HVM64"}, + "t2.micro": {"Arch": "HVM64"}, + "t2.small": {"Arch": "HVM64"}, + "t2.medium": {"Arch": "HVM64"}, + "t2.large": {"Arch": "HVM64"}, + "m1.small": {"Arch": "PV64"}, + "m1.medium": {"Arch": "PV64"}, + "m1.large": {"Arch": "PV64"}, + "m1.xlarge": {"Arch": "PV64"}, + "m2.xlarge": {"Arch": "PV64"}, + "m2.2xlarge": {"Arch": "PV64"}, + "m2.4xlarge": {"Arch": "PV64"}, + "m3.medium": {"Arch": "HVM64"}, + "m3.large": {"Arch": "HVM64"}, + "m3.xlarge": {"Arch": "HVM64"}, + "m3.2xlarge": {"Arch": "HVM64"}, + "m4.large": {"Arch": "HVM64"}, + "m4.xlarge": {"Arch": "HVM64"}, + "m4.2xlarge": {"Arch": "HVM64"}, + "m4.4xlarge": {"Arch": "HVM64"}, + "m4.10xlarge": {"Arch": "HVM64"}, + "c1.medium": {"Arch": "PV64"}, + "c1.xlarge": {"Arch": "PV64"}, + "c3.large": {"Arch": "HVM64"}, + "c3.xlarge": {"Arch": "HVM64"}, + "c3.2xlarge": {"Arch": "HVM64"}, + "c3.4xlarge": {"Arch": "HVM64"}, + "c3.8xlarge": {"Arch": "HVM64"}, + "c4.large": {"Arch": "HVM64"}, + "c4.xlarge": {"Arch": "HVM64"}, + "c4.2xlarge": {"Arch": "HVM64"}, + "c4.4xlarge": {"Arch": "HVM64"}, + "c4.8xlarge": {"Arch": "HVM64"}, + "g2.2xlarge": {"Arch": "HVMG2"}, + "g2.8xlarge": {"Arch": "HVMG2"}, + "r3.large": {"Arch": "HVM64"}, + "r3.xlarge": {"Arch": "HVM64"}, + "r3.2xlarge": {"Arch": "HVM64"}, + "r3.4xlarge": {"Arch": "HVM64"}, + "r3.8xlarge": {"Arch": "HVM64"}, + "i2.xlarge": {"Arch": "HVM64"}, + "i2.2xlarge": {"Arch": "HVM64"}, + "i2.4xlarge": {"Arch": "HVM64"}, + "i2.8xlarge": {"Arch": "HVM64"}, + "d2.xlarge": {"Arch": "HVM64"}, + "d2.2xlarge": {"Arch": "HVM64"}, + "d2.4xlarge": {"Arch": "HVM64"}, + "d2.8xlarge": {"Arch": "HVM64"}, + "hi1.4xlarge": {"Arch": "HVM64"}, + "hs1.8xlarge": {"Arch": "HVM64"}, + "cr1.8xlarge": {"Arch": "HVM64"}, + "cc2.8xlarge": {"Arch": "HVM64"}, } ) template.add_mapping( "AWSInstanceType2NATArch", { - "t1.micro" :{"Arch" : "NATPV64"}, - "t2.nano" :{"Arch" : "NATHVM64"}, - "t2.micro" :{"Arch" : "NATHVM64"}, - "t2.small" :{"Arch" : "NATHVM64"}, - "t2.medium" :{"Arch" : "NATHVM64"}, - "t2.large" :{"Arch" : "NATHVM64"}, - "m1.small" :{"Arch" : "NATPV64"}, - "m1.medium" :{"Arch" : "NATPV64"}, - "m1.large" :{"Arch" : "NATPV64"}, - "m1.xlarge" :{"Arch" : "NATPV64"}, - "m2.xlarge" :{"Arch" : "NATPV64"}, - "m2.2xlarge" :{"Arch" : "NATPV64"}, - "m2.4xlarge" :{"Arch" : "NATPV64"}, - "m3.medium" :{"Arch" : "NATHVM64"}, - "m3.large" :{"Arch" : "NATHVM64"}, - "m3.xlarge" :{"Arch" : "NATHVM64"}, - "m3.2xlarge" :{"Arch" : "NATHVM64"}, - "m4.large" :{"Arch" : "NATHVM64"}, - "m4.xlarge" :{"Arch" : "NATHVM64"}, - "m4.2xlarge" :{"Arch" : "NATHVM64"}, - "m4.4xlarge" :{"Arch" : "NATHVM64"}, - "m4.10xlarge" :{"Arch" : "NATHVM64"}, - "c1.medium" :{"Arch" : "NATPV64"}, - "c1.xlarge" :{"Arch" : "NATPV64"}, - "c3.large" :{"Arch" : "NATHVM64"}, - "c3.xlarge" :{"Arch" : "NATHVM64"}, - "c3.2xlarge" :{"Arch" : "NATHVM64"}, - "c3.4xlarge" :{"Arch" : "NATHVM64"}, - "c3.8xlarge" :{"Arch" : "NATHVM64"}, - "c4.large" :{"Arch" : "NATHVM64"}, - "c4.xlarge" :{"Arch" : "NATHVM64"}, - "c4.2xlarge" :{"Arch" : "NATHVM64"}, - "c4.4xlarge" :{"Arch" : "NATHVM64"}, - "c4.8xlarge" :{"Arch" : "NATHVM64"}, - "g2.2xlarge" :{"Arch" : "NATHVMG2"}, - "g2.8xlarge" :{"Arch" : "NATHVMG2"}, - "r3.large" :{"Arch" : "NATHVM64"}, - "r3.xlarge" :{"Arch" : "NATHVM64"}, - "r3.2xlarge" :{"Arch" : "NATHVM64"}, - "r3.4xlarge" :{"Arch" : "NATHVM64"}, - "r3.8xlarge" :{"Arch" : "NATHVM64"}, - "i2.xlarge" :{"Arch" : "NATHVM64"}, - "i2.2xlarge" :{"Arch" : "NATHVM64"}, - "i2.4xlarge" :{"Arch" : "NATHVM64"}, - "i2.8xlarge" :{"Arch" : "NATHVM64"}, - "d2.xlarge" :{"Arch" : "NATHVM64"}, - "d2.2xlarge" :{"Arch" : "NATHVM64"}, - "d2.4xlarge" :{"Arch" : "NATHVM64"}, - "d2.8xlarge" :{"Arch" : "NATHVM64"}, - "hi1.4xlarge" :{"Arch" : "NATHVM64"}, - "hs1.8xlarge" :{"Arch" : "NATHVM64"}, - "cr1.8xlarge" :{"Arch" : "NATHVM64"}, - "cc2.8xlarge" :{"Arch" : "NATHVM64"}, + "t1.micro": {"Arch": "NATPV64"}, + "t2.nano": {"Arch": "NATHVM64"}, + "t2.micro": {"Arch": "NATHVM64"}, + "t2.small": {"Arch": "NATHVM64"}, + "t2.medium": {"Arch": "NATHVM64"}, + "t2.large": {"Arch": "NATHVM64"}, + "m1.small": {"Arch": "NATPV64"}, + "m1.medium": {"Arch": "NATPV64"}, + "m1.large": {"Arch": "NATPV64"}, + "m1.xlarge": {"Arch": "NATPV64"}, + "m2.xlarge": {"Arch": "NATPV64"}, + "m2.2xlarge": {"Arch": "NATPV64"}, + "m2.4xlarge": {"Arch": "NATPV64"}, + "m3.medium": {"Arch": "NATHVM64"}, + "m3.large": {"Arch": "NATHVM64"}, + "m3.xlarge": {"Arch": "NATHVM64"}, + "m3.2xlarge": {"Arch": "NATHVM64"}, + "m4.large": {"Arch": "NATHVM64"}, + "m4.xlarge": {"Arch": "NATHVM64"}, + "m4.2xlarge": {"Arch": "NATHVM64"}, + "m4.4xlarge": {"Arch": "NATHVM64"}, + "m4.10xlarge": {"Arch": "NATHVM64"}, + "c1.medium": {"Arch": "NATPV64"}, + "c1.xlarge": {"Arch": "NATPV64"}, + "c3.large": {"Arch": "NATHVM64"}, + "c3.xlarge": {"Arch": "NATHVM64"}, + "c3.2xlarge": {"Arch": "NATHVM64"}, + "c3.4xlarge": {"Arch": "NATHVM64"}, + "c3.8xlarge": {"Arch": "NATHVM64"}, + "c4.large": {"Arch": "NATHVM64"}, + "c4.xlarge": {"Arch": "NATHVM64"}, + "c4.2xlarge": {"Arch": "NATHVM64"}, + "c4.4xlarge": {"Arch": "NATHVM64"}, + "c4.8xlarge": {"Arch": "NATHVM64"}, + "g2.2xlarge": {"Arch": "NATHVMG2"}, + "g2.8xlarge": {"Arch": "NATHVMG2"}, + "r3.large": {"Arch": "NATHVM64"}, + "r3.xlarge": {"Arch": "NATHVM64"}, + "r3.2xlarge": {"Arch": "NATHVM64"}, + "r3.4xlarge": {"Arch": "NATHVM64"}, + "r3.8xlarge": {"Arch": "NATHVM64"}, + "i2.xlarge": {"Arch": "NATHVM64"}, + "i2.2xlarge": {"Arch": "NATHVM64"}, + "i2.4xlarge": {"Arch": "NATHVM64"}, + "i2.8xlarge": {"Arch": "NATHVM64"}, + "d2.xlarge": {"Arch": "NATHVM64"}, + "d2.2xlarge": {"Arch": "NATHVM64"}, + "d2.4xlarge": {"Arch": "NATHVM64"}, + "d2.8xlarge": {"Arch": "NATHVM64"}, + "hi1.4xlarge": {"Arch": "NATHVM64"}, + "hs1.8xlarge": {"Arch": "NATHVM64"}, + "cr1.8xlarge": {"Arch": "NATHVM64"}, + "cc2.8xlarge": {"Arch": "NATHVM64"}, } ) template.add_mapping( "AWSRegionArch2AMI", { - "us-east-1" :{"PV64" : "ami-22111148", "HVM64" : "ami-08111162", "HVMG2" : "ami-ebcec381"}, - "us-west-2" :{"PV64" : "ami-792bc219", "HVM64" : "ami-c229c0a2", "HVMG2" : "ami-0f28c06f"}, - "us-west-1" :{"PV64" : "ami-0e087a6e", "HVM64" : "ami-1b0f7d7b", "HVMG2" : "ami-ab9defcb"}, - "eu-west-1" :{"PV64" : "ami-a5368cd6", "HVM64" : "ami-31328842", "HVMG2" : "ami-d1d652a2"}, - "eu-central-1" :{"PV64" : "ami-2bde3944", "HVM64" : "ami-e2df388d", "HVMG2" : "ami-5240a73d"}, - "ap-northeast-1" :{"PV64" : "ami-37020959", "HVM64" : "ami-f80e0596", "HVMG2" : "ami-34a9a35a"}, - "ap-northeast-2" :{"PV64" : "NOT_SUPPORTED", "HVM64" : "ami-6598510b", "HVMG2" : "NOT_SUPPORTED"}, - "ap-southeast-1" :{"PV64" : "ami-ff0cc79c", "HVM64" : "ami-e90dc68a", "HVMG2" : "ami-6f6ca70c"}, - "ap-southeast-2" :{"PV64" : "ami-f5210196", "HVM64" : "ami-f2210191", "HVMG2" : "ami-88c1e1eb"}, - "sa-east-1" :{"PV64" : "ami-661e930a", "HVM64" : "ami-1e159872", "HVMG2" : "NOT_SUPPORTED"}, - "cn-north-1" :{"PV64" : "ami-08ef2465", "HVM64" : "ami-49e22924", "HVMG2" : "NOT_SUPPORTED"} + "us-east-1": { + "PV64": "ami-22111148", + "HVM64": "ami-08111162", + "HVMG2": "ami-ebcec381", + }, + "us-west-2": { + "PV64": "ami-792bc219", + "HVM64": "ami-c229c0a2", + "HVMG2": "ami-0f28c06f", + }, + "us-west-1": { + "PV64": "ami-0e087a6e", + "HVM64": "ami-1b0f7d7b", + "HVMG2": "ami-ab9defcb" + }, + "eu-west-1": { + "PV64": "ami-a5368cd6", + "HVM64": "ami-31328842", + "HVMG2": "ami-d1d652a2" + }, + "eu-central-1": { + "PV64": "ami-2bde3944", + "HVM64": "ami-e2df388d", + "HVMG2": "ami-5240a73d" + }, + "ap-northeast-1": { + "PV64": "ami-37020959", + "HVM64": "ami-f80e0596", + "HVMG2": "ami-34a9a35a" + }, + "ap-northeast-2": { + "PV64": "NOT_SUPPORTED", + "HVM64": "ami-6598510b", + "HVMG2": "NOT_SUPPORTED" + }, + "ap-southeast-1": { + "PV64": "ami-ff0cc79c", + "HVM64": "ami-e90dc68a", + "HVMG2": "ami-6f6ca70c" + }, + "ap-southeast-2": { + "PV64": "ami-f5210196", + "HVM64": "ami-f2210191", + "HVMG2": "ami-88c1e1eb" + }, + "sa-east-1": { + "PV64": "ami-661e930a", + "HVM64": "ami-1e159872", + "HVMG2": "NOT_SUPPORTED" + }, + "cn-north-1": { + "PV64": "ami-08ef2465", + "HVM64": "ami-49e22924", + "HVMG2": "NOT_SUPPORTED" + }, } ) - template.add_mapping( - "Region2Examples", { - "us-east-1" :{"Examples":"https://s3.amazonaws.com/cloudformation-examples-us-east-1"}, - "us-west-2" :{"Examples":"https://s3-us-west-2.amazonaws.com/cloudformation-examples-us-west-2"}, - "us-west-1" :{"Examples":"https://s3-us-west-1.amazonaws.com/cloudformation-examples-us-west-1"}, - "eu-west-1" :{"Examples":"https://s3-eu-west-1.amazonaws.com/cloudformation-examples-eu-west-1"}, - "eu-central-1" :{"Examples":"https://s3-eu-central-1.amazonaws.com/cloudformation-examples-eu-central-1"}, - "ap-southeast-1":{"Examples":"https://s3-ap-southeast-1.amazonaws.com/cloudformation-examples-ap-southeast-1"}, - "ap-northeast-1":{"Examples":"https://s3-ap-northeast-1.amazonaws.com/cloudformation-examples-ap-northeast-1"}, - "ap-northeast-2":{"Examples":"https://s3-ap-northeast-2.amazonaws.com/cloudformation-examples-ap-northeast-2"}, - "ap-southeast-2":{"Examples":"https://s3-ap-southeast-2.amazonaws.com/cloudformation-examples-ap-southeast-2"}, - "sa-east-1" :{"Examples":"https://s3-sa-east-1.amazonaws.com/cloudformation-examples-sa-east-1"}, - "cn-north-1" :{"Examples":"https://s3.cn-north-1.amazonaws.com.cn/cloudformation-examples-cn-north-1"} + # This craziness is needed to pass pep8 line lengths of <79 + regions = [ + 'us-east-1', + 'us-west-2', + 'us-west-1', + 'eu-west-1', + 'sa-east-1', + 'eu-central-1', + 'ap-southeast-1', + 'ap-northeast-1', + 'ap-northeast-2', + 'ap-southeast-2', + 'cn-north-1', + ] + example_map = {} + for a_region in regions: + if a_region == 'us-east-1': + example_prefix = ('https://s3.amazonaws.com/cloudformat' + 'ion-examples-') + elif a_region == 'cn-north-1': + example_prefix = ('https://s3.cn-north-1.amazonaws.com.cn/cloudfo' + 'rmation-examples-') + else: + example_prefix = 'https://s3-' + \ + a_region + \ + '.amazonaws.com/cloudformation-examples-' + example_map[a_region] = { + "Examples": example_prefix + a_region } + template.add_mapping( + "Region2Examples", example_map ) - # Parameters allowedinstancetype = [ @@ -294,7 +356,8 @@ def main(): '\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)' ), ConstraintDescription="must be a valid email address.", - Description="EMail address to notify if there are any scaling operations", + Description=("EMail address to notify if there are any scaling " + "operations"), Type=constants.STRING, )) @@ -314,9 +377,7 @@ def main(): ' form x.x.x.x/x.' )) - # XXX Resources - - + # Resources r_elb = template.add_resource( elb.LoadBalancer( @@ -353,11 +414,10 @@ def main(): ) ) - - webserversg = template.add_resource(ec2.SecurityGroup( 'InstanceSecurityGroup', - GroupDescription='Enable SSH access and HTTP from the load balancer only', + GroupDescription=('Enable SSH access and HTTP from ' + 'the load balancer only'), SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol='tcp', @@ -381,6 +441,19 @@ def main(): ] )) + cfn_init = [ + '[cfn-auto-reloader-hook]\n', + 'triggers=post.update\n', + 'path=Resources.LaunchConfig.Metadata' + '.AWS::CloudFormation::Init\n', + 'action=/opt/aws/bin/cfn-init -v ', + ' --stack ', Ref('AWS::StackName'), + ' --resource LaunchConfig ', + ' --region ', Ref('AWS::Region'), + '\n', + 'runas=root\n' + ] + r_launchconfig = template.add_resource( autoscaling.LaunchConfiguration( 'LaunchConfig', @@ -394,7 +467,8 @@ def main(): }, files=cloudformation.InitFiles({ - '/var/www/html/index.html': cloudformation.InitFile( + ('/var/www/html' + '/index.html'): cloudformation.InitFile( content=Join('\n', [ "\"AWS', - '

Congratulations, you have successfully launched the AWS CloudFormation sample.

', + ('/cloudformation_graphic.png\" ' + 'alt=\"AWS CloudFormation Logo\"/>'), + ('

Congratulations, you have ' + 'successfully launched the AWS ' + 'CloudFormation sample.

'), ]), mode='000644', owner='root', @@ -422,19 +499,8 @@ def main(): ), '/etc/cfn/hooks.d/cfn-auto-reloader.conf': cloudformation.InitFile( - content=Join('', [ - '[cfn-auto-reloader-hook]\n', - 'triggers=post.update\n', - 'path=Resources.LaunchConfig.Metadata' - '.AWS::CloudFormation::Init\n', - 'action=/opt/aws/bin/cfn-init -v ', - ' --stack ', Ref('AWS::StackName'), - ' --resource LaunchConfig ', - ' --region ', Ref('AWS::Region'), - '\n', - 'runas=root\n' - ]), - # Why doesn't the Amazon template have this? + content=Join('', cfn_init) + # Why doesn't the template have this? # mode='000400', # owner='root', # group='root' @@ -459,7 +525,6 @@ def main(): }), cloudformation.Comment('Install a simple application'), ), - # XXX How do I add the comment to the Metadata? Troposphere errors out ImageId=FindInMap('AWSRegionArch2AMI', Ref('AWS::Region'), FindInMap('AWSInstanceType2Arch', Ref(instancetype), 'Arch')), @@ -482,8 +547,6 @@ def main(): ' --resource WebServerGroup ', ' --region ', Ref('AWS::Region'), '\n' ])), - #Tags=autoscaling.Tags(Application=Ref('AWS::StackId'), - # Details='Created using Troposhpere') )) r_webservergroup = template.add_resource(autoscaling.AutoScalingGroup(