AWSTemplateFormatVersion: 2010-09-09
Description: >-
AWS CloudFormation Sample Template. 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.
Resources:
NotificationTopic:
Type: 'AWS::SNS::Topic'
Properties:
Subscription:
- Endpoint: !Ref OperatorEMail
Protocol: email
WebServerGroup:
Type: 'AWS::AutoScaling::AutoScalingGroup'
Properties:
VPCZoneIdentifier:
- !Ref PrivateSubnet1ID
- !Ref PrivateSubnet2ID
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: !Join
- |+
- - >-
Congratulations, you have successfully launched the AWS
CloudFormation sample.
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:
- !GetAtt InstanceSecurityGroup.GroupId
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:
Subnets:
- !Ref PublicSubnet1ID
- !Ref PublicSubnet2ID
CrossZone: 'true'
Listeners:
- LoadBalancerPort: '80'
InstancePort: '80'
Protocol: HTTP
HealthCheck:
Target: 'HTTP:80/'
HealthyThreshold: '3'
UnhealthyThreshold: '5'
Interval: '30'
Timeout: '5'
SecurityGroups:
- !GetAtt LoadBalancerSecurityGroup.GroupId
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
SourceSecurityGroupId: !GetAtt LoadBalancerSecurityGroup.GroupId
VpcId: !Ref VPCID
LoadBalancerSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Enable HTTP from the world
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
VpcId: !Ref VPCID