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. 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. PrivateSubnet1ID: Description: Private Subnet Id 1 Type: 'AWS::EC2::Subnet::Id' PrivateSubnet2ID: Description: Private Subnet Id 2 Type: 'AWS::EC2::Subnet::Id' PublicSubnet1ID: Description: Public Subnet Id 1 Type: 'AWS::EC2::Subnet::Id' PublicSubnet2ID: Description: Public Subnet Id 2 Type: 'AWS::EC2::Subnet::Id' VPCID: Description: 'ID of the VPC (e.g., vpc-0343606e)' Type: 'AWS::EC2::VPC::Id' 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