AWSTemplateFormatVersion: '2010-09-09'
Metadata:
License: Apache-2.0
Description: 'AWS CloudFormation Sample Template AutoScalingMultiAZWithNotifications:
Create a multi-az, load balanced and Auto Scaled sample web site running on an Apache
Web Server. 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
ap-south-1:
Examples: https://s3-ap-south-1.amazonaws.com/cloudformation-examples-ap-south-1
us-east-2:
Examples: https://s3-us-east-2.amazonaws.com/cloudformation-examples-us-east-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-2a69aa47
HVM64: ami-6869aa05
HVMG2: ami-50b4f047
us-west-2:
PV64: ami-7f77b31f
HVM64: ami-7172b611
HVMG2: ami-002bf460
us-west-1:
PV64: ami-a2490dc2
HVM64: ami-31490d51
HVMG2: ami-699ad409
eu-west-1:
PV64: ami-4cdd453f
HVM64: ami-f9dd458a
HVMG2: ami-f0e0a483
eu-central-1:
PV64: ami-6527cf0a
HVM64: ami-ea26ce85
HVMG2: ami-d9d62ab6
ap-northeast-1:
PV64: ami-3e42b65f
HVM64: ami-374db956
HVMG2: ami-78ba6619
ap-northeast-2:
PV64: NOT_SUPPORTED
HVM64: ami-2b408b45
HVMG2: NOT_SUPPORTED
ap-southeast-1:
PV64: ami-df9e4cbc
HVM64: ami-a59b49c6
HVMG2: ami-56e84c35
ap-southeast-2:
PV64: ami-63351d00
HVM64: ami-dc361ebf
HVMG2: ami-2589b946
ap-south-1:
PV64: NOT_SUPPORTED
HVM64: ami-ffbdd790
HVMG2: ami-f7354198
us-east-2:
PV64: NOT_SUPPORTED
HVM64: ami-f6035893
HVMG2: NOT_SUPPORTED
sa-east-1:
PV64: ami-1ad34676
HVM64: ami-6dd04501
HVMG2: NOT_SUPPORTED
cn-north-1:
PV64: ami-77559f1a
HVM64: ami-8e6aa0e3
HVMG2: NOT_SUPPORTED
Resources:
NotificationTopic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: !Ref 'OperatorEMail'
Protocol: email
WebServerGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AvailabilityZones: !GetAZs ''
LaunchConfigurationName: !Ref 'LaunchConfig'
MinSize: '1'
MaxSize: '3'
LoadBalancerNames: [!Ref 'ElasticLoadBalancer']
NotificationConfigurations:
- 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: !Join ['
', [<img src=", !FindInMap [Region2Examples, !Ref 'AWS::Region',
Examples], /cloudformation_graphic.png" alt="AWS CloudFormation
Logo"/>, '<h1>Congratulations, you have successfully launched
the AWS CloudFormation sample.</h1>']]
mode: '000644'
owner: root
group: root
/etc/cfn/cfn-hup.conf:
content: !Join ['', ['[main]
', stack=, !Ref 'AWS::StackId', '
', region=, !Ref 'AWS::Region', '
']]
mode: '000400'
owner: root
group: root
/etc/cfn/hooks.d/cfn-auto-reloader.conf:
content: !Join ['', ['[cfn-auto-reloader-hook]
', 'triggers=post.update
', 'path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init
', 'action=/opt/aws/bin/cfn-init -v ', ' --stack ', !Ref 'AWS::StackName',
' --resource LaunchConfig ', ' --region ', !Ref 'AWS::Region',
'
', 'runas=root
']]
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: !FindInMap [AWSRegionArch2AMI, !Ref 'AWS::Region', !FindInMap [AWSInstanceType2Arch,
!Ref 'InstanceType', Arch]]
SecurityGroups: [!Ref 'InstanceSecurityGroup']
InstanceType: !Ref 'InstanceType'
UserData: !Base64
Fn::Join:
- ''
- ['#!/bin/bash -xe
', 'yum update -y aws-cfn-bootstrap
', '/opt/aws/bin/cfn-init -v ', ' --stack ', !Ref 'AWS::StackName',
' --resource LaunchConfig ', ' --region ', !Ref 'AWS::Region',
'
', '/opt/aws/bin/cfn-signal -e $? ', ' --stack ', !Ref 'AWS::StackName',
' --resource WebServerGroup ', ' --region ', !Ref 'AWS::Region',
'
']
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: !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: !GetAtt [ElasticLoadBalancer, SourceSecurityGroup.OwnerAlias]
SourceSecurityGroupName: !GetAtt [ElasticLoadBalancer, SourceSecurityGroup.GroupName]
Outputs:
URL:
Description: The URL of the website
Value: !Join ['', ['http://', !GetAtt [ElasticLoadBalancer, DNSName]]]