Skip to content

Instantly share code, notes, and snippets.

@lvnilesh
Created June 20, 2024 03:38
Show Gist options
  • Save lvnilesh/54055e6aed0db38a218b82cf690083b4 to your computer and use it in GitHub Desktop.
Save lvnilesh/54055e6aed0db38a218b82cf690083b4 to your computer and use it in GitHub Desktop.
autoscaling cloudformation JSON
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Create a multi-az, load balanced and Auto Scaled sample web site running on\nan Apache Web Server. The application is configured to span all\nAvailability Zones in the region and is Auto-Scaled based on the CPU\nutilization of the web servers. Notifications will be sent to the operator\nemail address on scaling events. The instances are load balanced with a\nsimple health check against the default web page. **WARNING** This template\ncreates one or more Amazon EC2 instances and an Elastic Load Balancer. You\nwill be billed for the AWS resources used if you create a stack from this\ntemplate.\n",
"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": {
"Fn::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": {
"Fn::Join": [
"",
[
"<img src=\"",
{
"Fn::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": {
"Fn::Sub": "[main]\nstack=${AWS::StackId}\nregion=${AWS::Region}\n"
},
"mode": "000400",
"owner": "root",
"group": "root"
},
"/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
"content": {
"Fn::Sub": "[cfn-auto-reloader-hook]\ntriggers=post.update\npath=Resources.LaunchTemplate.Metadata.AWS::CloudFormation::Init\naction=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchTemplate --region ${AWS::Region}\nrunas=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": {
"LaunchTemplateName": {
"Fn::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": {
"Fn::Base64": {
"Fn::Sub": "#!/bin/bash\n/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchTemplate --region ${AWS::Region}\n/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerGroup --region ${AWS::Region}\n"
}
},
"TagSpecifications": [
{
"ResourceType": "instance",
"Tags": [
{
"Key": "Name",
"Value": {
"Fn::Sub": "${AWS::StackName}-Instance"
}
}
]
}
]
}
}
},
"WebServerGroup": {
"CreationPolicy": {
"ResourceSignal": {
"Timeout": "PT5M",
"Count": 1
}
},
"UpdatePolicy": {
"AutoScalingRollingUpdate": {
"MinInstancesInService": 1,
"MaxBatchSize": 1,
"PauseTime": "PT5M",
"WaitOnResourceSignals": true
}
},
"Type": "AWS::AutoScaling::AutoScalingGroup",
"Metadata": {
"cfn-lint": {
"config": {
"ignore_checks": [
"E3014"
]
}
}
},
"Properties": {
"AvailabilityZones": {
"Ref": "AZs"
},
"LaunchTemplate": {
"LaunchTemplateId": {
"Ref": "LaunchTemplate"
},
"Version": {
"Fn::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": {
"Fn::Join": [
"",
[
"https://",
{
"Fn::GetAtt": [
"ElasticLoadBalancer",
"DNSName"
]
}
]
]
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment