Skip to content

Instantly share code, notes, and snippets.

@lvnilesh
Created June 20, 2024 03:37
Show Gist options
  • Save lvnilesh/90415e7dc553e58e986e8b625ad6a4f0 to your computer and use it in GitHub Desktop.
Save lvnilesh/90415e7dc553e58e986e8b625ad6a4f0 to your computer and use it in GitHub Desktop.
autoscaling cloudformation YAML
AWSTemplateFormatVersion: "2010-09-09"
Description: |
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: t4g.micro
OperatorEMail:
Description: Email address to notify if there are any scaling operations
Type: String
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
Default: 192.168.1.0/24
MinLength: 9
MaxLength: 18
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.
LatestAmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-arm64
KmsKeyArn:
Description: KMS Key ARN to encrypt data
Type: String
CertificateArn:
Description: Certificate ARN for HTTPS
Type: String
SecurityGroups:
Description: Security Groups to be used
Type: List<AWS::EC2::SecurityGroup::Id>
Subnets:
Description: Subnets to be used
Type: List<AWS::EC2::Subnet::Id>
AZs:
Description: Availability Zones to be used
Type: List<AWS::EC2::AvailabilityZone::Name>
VPC:
Description: VPC to be used
Type: AWS::EC2::VPC::Id
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
Resources:
NotificationTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName: !Sub ${AWS::StackName}-NotificationTopic
Subscription:
- Endpoint: !Ref OperatorEMail
Protocol: email
KmsMasterKeyId: !Ref KmsKeyArn
LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Metadata:
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: !Sub |
[main]
stack=${AWS::StackId}
region=${AWS::Region}
mode: "000400"
owner: root
group: root
/etc/cfn/hooks.d/cfn-auto-reloader.conf:
content: !Sub |
[cfn-auto-reloader-hook]
triggers=post.update
path=Resources.LaunchTemplate.Metadata.AWS::CloudFormation::Init
action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchTemplate --region ${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:
LaunchTemplateName: !Sub ${AWS::StackName}-LaunchTemplate
LaunchTemplateData:
ImageId: !Ref LatestAmiId
InstanceType: !Ref InstanceType
SecurityGroupIds: !Ref SecurityGroups
KeyName: !Ref KeyName
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeSize: 32
UserData: !Base64
Fn::Sub: |
#!/bin/bash
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchTemplate --region ${AWS::Region}
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerGroup --region ${AWS::Region}
TagSpecifications:
- ResourceType: instance
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-Instance
WebServerGroup:
Type: AWS::AutoScaling::AutoScalingGroup
CreationPolicy:
ResourceSignal:
Timeout: PT5M
Count: 1
UpdatePolicy:
AutoScalingRollingUpdate:
MinInstancesInService: 1
MaxBatchSize: 1
PauseTime: PT5M
WaitOnResourceSignals: true
Metadata:
cfn-lint:
config:
ignore_checks:
- E3014
Properties:
AvailabilityZones: !Ref AZs
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
MinSize: "1"
MaxSize: "3"
TargetGroupARNs:
- !Ref TargetGroup
NotificationConfigurations:
- TopicARN: !Ref NotificationTopic
NotificationTypes:
- autoscaling:EC2_INSTANCE_LAUNCH
- autoscaling:EC2_INSTANCE_LAUNCH_ERROR
- autoscaling:EC2_INSTANCE_TERMINATE
- autoscaling:EC2_INSTANCE_TERMINATE_ERROR
HealthCheckType: ELB
VPCZoneIdentifier: !Ref Subnets
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::ElasticLoadBalancingV2::LoadBalancer
Properties:
Scheme: internet-facing
SecurityGroups:
- !Ref LoadBalancerSecurityGroup
Subnets: !Ref Subnets
Type: application
LoadBalancerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allows inbound traffic on port 443
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
VpcId: !Ref VPC
LoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref TargetGroup
LoadBalancerArn: !Ref ElasticLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: ELBSecurityPolicy-2016-08
Certificates:
- CertificateArn: !Ref CertificateArn
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckPath: /
Name: MyTargetGroup
Port: 80
Protocol: HTTP
TargetType: instance
VpcId: !Ref VPC
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Metadata:
guard:
SuppressedRules:
- INCOMING_SSH_DISABLED
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: !Ref LoadBalancerSecurityGroup
Outputs:
URL:
Description: The URL of the website
Value: !Join
- ""
- - https://
- !GetAtt ElasticLoadBalancer.DNSName
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment