AWS CloudFormation Auto Scaling Overview Create production-ready Auto Scaling infrastructure using AWS CloudFormation templates. This skill covers Auto Scaling Groups for EC2, ECS, and Lambda, launch configurations, launch templates, scaling policies, lifecycle hooks, and best practices for high availability and cost optimization. When to Use Use this skill when: Creating Auto Scaling Groups for EC2 instances Configuring Launch Configurations or Launch Templates Implementing scaling policies (step, target tracking, simple) Adding lifecycle hooks for lifecycle management Creating scaling for ECS services Implementing Lambda provisioned concurrency scaling Organizing templates with Parameters, Outputs, Mappings, Conditions Implementing cross-stack references with export/import Using mixed instances policies for diversity CloudFormation Template Structure Base Template with Standard Format AWSTemplateFormatVersion : 2010-09-09 Description : Auto Scaling group with load balancer Metadata : AWS::CloudFormation::Interface : ParameterGroups : - Label : default : Auto Scaling Configuration Parameters : - MinSize - MaxSize - DesiredCapacity - Label : default : Instance Configuration Parameters : - InstanceType - AmiId Parameters : MinSize : Type : Number Default : 2 Description : Minimum number of instances MaxSize : Type : Number Default : 10 Description : Maximum number of instances DesiredCapacity : Type : Number Default : 2 Description : Desired number of instances InstanceType : Type : String Default : t3.micro AllowedValues : - t3.micro - t3.small - t3.medium - t3.large AmiId : Type : AWS : : EC2 : : Image : : Id Description : AMI ID for instances Mappings : EnvironmentConfig : dev : InstanceType : t3.micro MinSize : 1 MaxSize : 3 staging : InstanceType : t3.medium MinSize : 2 MaxSize : 6 production : InstanceType : t3.large MinSize : 3 MaxSize : 12 Conditions : IsProduction : !Equals [ !Ref Environment , production ] UseSpotInstances : !Or [ !Equals [ !Ref Environment , dev ] , !Equals [ !Ref Environment , staging ] ] Resources :
Auto Scaling Group
MyAutoScalingGroup : Type : AWS : : AutoScaling : : AutoScalingGroup Properties : AutoScalingGroupName : !Sub "${AWS::StackName}-asg" MinSize : !Ref MinSize MaxSize : !Ref MaxSize DesiredCapacity : !Ref DesiredCapacity VPCZoneIdentifier : !Ref SubnetIds LaunchConfigurationName : !Ref MyLaunchConfiguration LoadBalancerNames : - !Ref MyLoadBalancer HealthCheckType : ELB HealthCheckGracePeriod : 300 TerminationPolicies : - OldestInstance - Default Tags : - Key : Environment Value : !Ref Environment PropagateAtLaunch : true - Key : ManagedBy Value : CloudFormation PropagateAtLaunch : true Outputs : AutoScalingGroupName : Description : Name of the Auto Scaling Group Value : !Ref MyAutoScalingGroup Parameters Best Practices AWS-Specific Parameter Types Parameters :
AWS-specific types for validation
InstanceType : Type : AWS : : EC2 : : Instance : : Type Description : EC2 instance type AmiId : Type : AWS : : EC2 : : Image : : Id Description : AMI ID for instances SubnetIds : Type : List<AWS : : EC2 : : Subnet : : Id
Description : Subnets for Auto Scaling group SecurityGroupIds : Type : List<AWS : : EC2 : : SecurityGroup : : Id
Description : Security groups for instances LoadBalancerArn : Type : AWS : : ElasticLoadBalancingV2 : : LoadBalancer : : Arn Description : Application Load Balancer ARN TargetGroupArn : Type : AWS : : ElasticLoadBalancingV2 : : TargetGroup : : Arn Description : Target Group ARN for ALB LaunchTemplateId : Type : AWS : : EC2 : : LaunchTemplate : : LaunchTemplateId Description : Launch template ID ScalingPolicyArn : Type : AWS : : AutoScaling : : ScalingPolicy : : Arn Description : Scaling policy ARN Parameter Constraints Parameters : MinSize : Type : Number Default : 1 Description : Minimum number of instances MinValue : 0 MaxValue : 1000 ConstraintDescription : Must be between 0 and 1000 MaxSize : Type : Number Default : 10 Description : Maximum number of instances MinValue : 1 MaxValue : 1000 ConstraintDescription : Must be between 1 and 1000 DesiredCapacity : Type : Number Default : 2 Description : Desired number of instances MinValue : 0 MaxValue : 1000 InstanceType : Type : String Default : t3.micro Description : EC2 instance type ConstraintDescription : Must be a valid EC2 instance type AmiId : Type : AWS : : EC2 : : Image : : Id Description : AMI ID EnvironmentName : Type : String Default : dev Description : Deployment environment AllowedValues : - dev - staging - production ConstraintDescription : Must be dev , staging , or production SSM Parameter References Parameters : LatestAmiId : Type : AWS : : SSM : : Parameter : : Value<AWS : : EC2 : : Image : : Id
Default : /aws/service/ami - amazon - linux - latest/amzn2 - ami - hvm - x86_64 - gp2 Description : Latest Amazon Linux 2 AMI from SSM InstanceConfiguration : Type : AWS : : SSM : : Parameter : : Value<String
Default : /myapp/instance - configuration Description : Instance configuration from SSM Outputs and Cross-Stack References Export/Import Patterns
Stack A - Network and Auto Scaling Stack
AWSTemplateFormatVersion : 2010-09-09 Description : Auto Scaling infrastructure stack Resources : MyAutoScalingGroup : Type : AWS : : AutoScaling : : AutoScalingGroup Properties : AutoScalingGroupName : !Sub "${AWS::StackName}-asg" MinSize : 2 MaxSize : 10 DesiredCapacity : 2 VPCZoneIdentifier : !Ref SubnetIds LaunchConfigurationName : !Ref MyLaunchConfiguration Outputs : AutoScalingGroupName : Description : Name of the Auto Scaling Group Value : !Ref MyAutoScalingGroup Export : Name : !Sub "${AWS::StackName}-AutoScalingGroupName" AutoScalingGroupArn : Description : ARN of the Auto Scaling Group Value : !Sub "arn:aws:autoscaling:${AWS::Region}:${AWS::AccountId}:autoScalingGroup:*:autoScalingGroupName/${MyAutoScalingGroup}" Export : Name : !Sub "${AWS::StackName}-AutoScalingGroupArn" LaunchConfigurationName : Description : Name of the Launch Configuration Value : !Ref MyLaunchConfiguration Export : Name : !Sub "${AWS::StackName}-LaunchConfigurationName"
Stack B - Application Stack (imports from Stack A)
AWSTemplateFormatVersion : 2010-09-09 Description : Application stack using Auto Scaling from infrastructure stack Parameters : InfraStackName : Type : String Default : infra - stack Description : Name of the infrastructure stack Resources : ScalingPolicy : Type : AWS : : AutoScaling : : ScalingPolicy Properties : PolicyName : !Sub "${AWS::StackName}-scale-up" PolicyType : StepScaling AdjustmentType : PercentChangeInCapacity Cooldown : 300 StepAdjustments : - MetricIntervalLowerBound : 0 MetricIntervalUpperBound : 10000 ScalingAdjustment : 200 - MetricIntervalLowerBound : 10000 ScalingAdjustment : 400 AutoScalingGroupName : !ImportValue !Sub "$ { InfraStackName } - AutoScalingGroupName" Nested Stacks for Modularity AWSTemplateFormatVersion : 2010-09-09 Description : Main stack with nested Auto Scaling stacks Resources :
Nested stack for EC2 Auto Scaling
EC2AutoScalingStack : Type : AWS : : CloudFormation : : Stack Properties : TemplateURL : https : //s3.amazonaws.com/bucket/ec2 - asg.yaml TimeoutInMinutes : 15 Parameters : Environment : !Ref Environment InstanceType : !Ref InstanceType MinSize : !Ref MinSize MaxSize : !Ref MaxSize
Nested stack for scaling policies
ScalingPoliciesStack : Type : AWS : : CloudFormation : : Stack Properties : TemplateURL : https : //s3.amazonaws.com/bucket/scaling - policies.yaml TimeoutInMinutes : 15 Parameters : AutoScalingGroupName : !GetAtt EC2AutoScalingStack.Outputs.AutoScalingGroupName Environment : !Ref Environment Launch Configurations Base Launch Configuration AWSTemplateFormatVersion : 2010-09-09 Description : Auto Scaling with Launch Configuration Parameters : InstanceType : Type : String Default : t3.micro AmiId : Type : AWS : : EC2 : : Image : : Id KeyName : Type : AWS : : EC2 : : KeyPair : : KeyName Resources : MyLaunchConfiguration : Type : AWS : : AutoScaling : : LaunchConfiguration Properties : LaunchConfigurationName : !Sub "${AWS::StackName}-lc" ImageId : !Ref AmiId InstanceType : !Ref InstanceType KeyName : !Ref KeyName SecurityGroups : - !Ref InstanceSecurityGroup InstanceMonitoring : Enabled SpotPrice : !If [ UseSpot , "0.05" , !Ref AWS : : NoValue ] UserData : Fn::Base64 : |
!/bin/bash
yum update -y yum install -y httpd systemctl start httpd echo "Hello from Auto Scaling" > /var/www/html/index.html InstanceSecurityGroup : Type : AWS : : EC2 : : SecurityGroup Properties : GroupName : !Sub "${AWS::StackName}-instance-sg" GroupDescription : Security group for instances VpcId : !Ref VPCId SecurityGroupIngress : - IpProtocol : tcp FromPort : 80 ToPort : 80 CidrIp : 0.0.0.0/0 - IpProtocol : tcp FromPort : 22 ToPort : 22 CidrIp : 0.0.0.0/0 Conditions : UseSpot : !Equals [ !Ref UseSpotInstances , true ] Parameters : UseSpotInstances : Type : String Default : false AllowedValues : - true - false Launch Templates Launch Template with Customization AWSTemplateFormatVersion : 2010-09-09 Description : Auto Scaling with Launch Template Parameters : InstanceType : Type : String Default : t3.micro AmiId : Type : AWS : : EC2 : : Image : : Id Resources : MyLaunchTemplate : Type : AWS : : EC2 : : LaunchTemplate Properties : LaunchTemplateName : !Sub "${AWS::StackName}-lt" LaunchTemplateData : ImageId : !Ref AmiId InstanceType : !Ref InstanceType Monitoring : Enabled : true NetworkInterfaces : - DeviceIndex : 0 AssociatePublicIpAddress : false Groups : - !Ref InstanceSecurityGroup TagSpecifications : - ResourceType : instance Tags : - Key : Name Value : !Sub "${AWS::StackName}-instance" - Key : Environment Value : !Ref Environment UserData : Fn::Base64 : |
!/bin/bash
yum update -y systemctl enable httpd systemctl start httpd InstanceSecurityGroup : Type : AWS : : EC2 : : SecurityGroup Properties : GroupName : !Sub "${AWS::StackName}-sg" GroupDescription : Security group for instances VpcId : !Ref VPCId MyAutoScalingGroup : Type : AWS : : AutoScaling : : AutoScalingGroup Properties : AutoScalingGroupName : !Sub "${AWS::StackName}-asg" MinSize : 2 MaxSize : 10 DesiredCapacity : 2 VPCZoneIdentifier : !Ref SubnetIds LaunchTemplate : LaunchTemplateId : !Ref MyLaunchTemplate Version : !GetAtt MyLaunchTemplate.LatestVersionNumber Auto Scaling Groups ASG with Load Balancer AWSTemplateFormatVersion : 2010-09-09 Description : Auto Scaling group with Application Load Balancer Resources : MyAutoScalingGroup : Type : AWS : : AutoScaling : : AutoScalingGroup Properties : AutoScalingGroupName : !Sub "${AWS::StackName}-asg" MinSize : 2 MaxSize : 10 DesiredCapacity : 2 VPCZoneIdentifier : !Ref PrivateSubnetIds LaunchConfigurationName : !Ref MyLaunchConfiguration TargetGroupARNs : - !Ref MyTargetGroup HealthCheckType : ELB HealthCheckGracePeriod : 300 TerminationPolicies : - OldestInstance - Default InstanceMaintenancePolicy : MinHealthyPercentage : 50 MaxHealthyPercentage : 200 Tags : - Key : Environment Value : !Ref Environment PropagateAtLaunch : true - Key : Name Value : !Sub "${AWS::StackName}-instance" PropagateAtLaunch : true MyTargetGroup : Type : AWS : : ElasticLoadBalancingV2 : : TargetGroup Properties : Name : !Sub "${AWS::StackName}-tg" Port : 80 Protocol : HTTP VpcId : !Ref VPCId HealthCheckPath : / HealthCheckIntervalSeconds : 30 HealthCheckTimeoutSeconds : 5 HealthyThresholdCount : 5 UnhealthyThresholdCount : 2 TargetType : instance ASG with Launch Template and Mixed Instances AWSTemplateFormatVersion : 2010-09-09 Description : Auto Scaling with Mixed Instances Policy Resources : MyLaunchTemplate : Type : AWS : : EC2 : : LaunchTemplate Properties : LaunchTemplateName : !Sub "${AWS::StackName}-lt" LaunchTemplateData : ImageId : !Ref AmiId InstanceType : t3.micro KeyName : !Ref KeyName MyAutoScalingGroup : Type : AWS : : AutoScaling : : AutoScalingGroup Properties : AutoScalingGroupName : !Sub "${AWS::StackName}-asg" MinSize : 2 MaxSize : 10 DesiredCapacity : 2 VPCZoneIdentifier : !Ref SubnetIds LaunchTemplate : LaunchTemplateId : !Ref MyLaunchTemplate Version : !GetAtt MyLaunchTemplate.LatestVersionNumber MixedInstancesPolicy : InstancesDistribution : OnDemandAllocationStrategy : prioritized OnDemandBaseCapacity : 2 OnDemandPercentageAboveBaseCapacity : 50 SpotAllocationStrategy : capacity - optimized SpotInstancePools : 3 SpotMaxPrice : !Ref MaxSpotPrice LaunchTemplate : LaunchTemplateId : !Ref MyLaunchTemplate Overrides : - InstanceType : t3.micro - InstanceType : t3.small - InstanceType : t3.medium ASG with Lifecycle Hooks AWSTemplateFormatVersion : 2010-09-09 Description : Auto Scaling with lifecycle hooks Resources : MyLaunchConfiguration : Type : AWS : : AutoScaling : : LaunchConfiguration Properties : LaunchConfigurationName : !Sub "${AWS::StackName}-lc" ImageId : !Ref AmiId InstanceType : t3.micro MyAutoScalingGroup : Type : AWS : : AutoScaling : : AutoScalingGroup Properties : AutoScalingGroupName : !Sub "${AWS::StackName}-asg" MinSize : 2 MaxSize : 10 DesiredCapacity : 2 VPCZoneIdentifier : !Ref SubnetIds LaunchConfigurationName : !Ref MyLaunchConfiguration
Lifecycle Hook - Instance Launch
LifecycleHookLaunch : Type : AWS : : AutoScaling : : LifecycleHook Properties : LifecycleHookName : !Sub "${AWS::StackName}-launch-hook" AutoScalingGroupName : !Ref MyAutoScalingGroup LifecycleTransition : autoscaling : EC2_INSTANCE_LAUNCHING HeartbeatTimeout : 900 NotificationTargetARN : !Ref SnsTopicArn RoleARN : !GetAtt LifecycleHookRole.Arn
Lifecycle Hook - Instance Termination
LifecycleHookTermination : Type : AWS : : AutoScaling : : LifecycleHook Properties : LifecycleHookName : !Sub "${AWS::StackName}-termination-hook" AutoScalingGroupName : !Ref MyAutoScalingGroup LifecycleTransition : autoscaling : EC2_INSTANCE_TERMINATING HeartbeatTimeout : 3600 NotificationTargetARN : !Ref SnsTopicArn RoleARN : !GetAtt LifecycleHookRole.Arn
IAM Role for Lifecycle Hooks
LifecycleHookRole : Type : AWS : : IAM : : Role Properties : RoleName : !Sub "${AWS::StackName}-lifecycle-role" AssumeRolePolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Principal : Service : autoscaling.amazonaws.com Action : sts : AssumeRole Policies : - PolicyName : !Sub "${AWS::StackName}-lifecycle-policy" PolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Action : - sns : Publish Resource : !Ref SnsTopicArn SnsTopic : Type : AWS : : SNS : : Topic Properties : TopicName : !Sub "${AWS::StackName}-lifecycle" Scaling Policies Target Tracking Policy AWSTemplateFormatVersion : 2010-09-09 Description : Auto Scaling with Target Tracking scaling policy Resources : MyAutoScalingGroup : Type : AWS : : AutoScaling : : AutoScalingGroup Properties : AutoScalingGroupName : !Sub "${AWS::StackName}-asg" MinSize : 2 MaxSize : 10 DesiredCapacity : 2 VPCZoneIdentifier : !Ref SubnetIds LaunchConfigurationName : !Ref MyLaunchConfiguration TargetTrackingPolicy : Type : AWS : : AutoScaling : : ScalingPolicy Properties : PolicyName : !Sub "${AWS::StackName}-target-tracking" PolicyType : TargetTrackingScaling AutoScalingGroupName : !Ref MyAutoScalingGroup TargetTrackingConfiguration : PredefinedMetricSpecification : PredefinedMetricType : ASGAverageCPUUtilization TargetValue : 70 DisableScaleIn : false Step Scaling Policy Resources : StepScalingPolicy : Type : AWS : : AutoScaling : : ScalingPolicy Properties : PolicyName : !Sub "${AWS::StackName}-step-scaling" PolicyType : StepScaling AdjustmentType : PercentChangeInCapacity Cooldown : 300 StepAdjustments : - MetricIntervalLowerBound : 0 MetricIntervalUpperBound : 10000 ScalingAdjustment : 200 - MetricIntervalLowerBound : 10000 MetricIntervalUpperBound : 20000 ScalingAdjustment : 400 - MetricIntervalLowerBound : 20000 ScalingAdjustment : 600 AutoScalingGroupName : !Ref MyAutoScalingGroup
Alarm for Step Scaling
HighCpuAlarm : Type : AWS : : CloudWatch : : Alarm Properties : AlarmName : !Sub "${AWS::StackName}-high-cpu" AlarmDescription : Alarm when CPU utilization is high MetricName : CPUUtilization Namespace : AWS/EC2 Dimensions : - Name : AutoScalingGroupName Value : !Ref MyAutoScalingGroup Statistic : Average Period : 60 EvaluationPeriods : 3 Threshold : 70 ComparisonOperator : GreaterThanThreshold AlarmActions : - !Ref StepScalingPolicy Simple Scaling Policy Resources : SimpleScalingPolicy : Type : AWS : : AutoScaling : : ScalingPolicy Properties : PolicyName : !Sub "${AWS::StackName}-simple-scale-up" PolicyType : SimpleScaling AdjustmentType : ChangeInCapacity ScalingAdjustment : 1 Cooldown : 300 AutoScalingGroupName : !Ref MyAutoScalingGroup ScaleDownPolicy : Type : AWS : : AutoScaling : : ScalingPolicy Properties : PolicyName : !Sub "${AWS::StackName}-simple-scale-down" PolicyType : SimpleScaling AdjustmentType : ChangeInCapacity ScalingAdjustment : -1 Cooldown : 600 AutoScalingGroupName : !Ref MyAutoScalingGroup HighCpuAlarm : Type : AWS : : CloudWatch : : Alarm Properties : AlarmName : !Sub "${AWS::StackName}-high-cpu" MetricName : CPUUtilization Namespace : AWS/EC2 Dimensions : - Name : AutoScalingGroupName Value : !Ref MyAutoScalingGroup Statistic : Average Period : 120 EvaluationPeriods : 2 Threshold : 80 ComparisonOperator : GreaterThanThreshold AlarmActions : - !Ref SimpleScalingPolicy LowCpuAlarm : Type : AWS : : CloudWatch : : Alarm Properties : AlarmName : !Sub "${AWS::StackName}-low-cpu" MetricName : CPUUtilization Namespace : AWS/EC2 Dimensions : - Name : AutoScalingGroupName Value : !Ref MyAutoScalingGroup Statistic : Average Period : 300 EvaluationPeriods : 2 Threshold : 30 ComparisonOperator : LessThanThreshold AlarmActions : - !Ref ScaleDownPolicy Scheduled Scaling Resources : ScheduledScaleUp : Type : AWS : : AutoScaling : : ScheduledAction Properties : ScheduledActionName : !Sub "${AWS::StackName}-scheduled-scale-up" AutoScalingGroupName : !Ref MyAutoScalingGroup MinSize : 5 MaxSize : 15 DesiredCapacity : 5 StartTime : "2024-01-01T08:00:00Z" ScheduledScaleDown : Type : AWS : : AutoScaling : : ScheduledAction Properties : ScheduledActionName : !Sub "${AWS::StackName}-scheduled-scale-down" AutoScalingGroupName : !Ref MyAutoScalingGroup MinSize : 2 MaxSize : 10 DesiredCapacity : 2 StartTime : "2024-01-01T20:00:00Z"
Recurring schedule using cron
RecurringScaleUp : Type : AWS : : AutoScaling : : ScheduledAction Properties : ScheduledActionName : !Sub "${AWS::StackName}-morning-scale-up" AutoScalingGroupName : !Ref MyAutoScalingGroup MinSize : 5 MaxSize : 15 DesiredCapacity : 5 Recurrence : "0 8 * * *" ECS Auto Scaling ECS Service Scaling AWSTemplateFormatVersion : 2010-09-09 Description : ECS service with Auto Scaling Resources :
ECS Cluster
EcsCluster : Type : AWS : : ECS : : Cluster Properties : ClusterName : !Sub "${AWS::StackName}-cluster"
Task Definition
TaskDefinition : Type : AWS : : ECS : : TaskDefinition Properties : Family : !Sub "${AWS::StackName}-task" Cpu : "512" Memory : "1024" NetworkMode : awsvpc RequiresCompatibilities : - FARGATE ContainerDefinitions : - Name : web Image : nginx : latest PortMappings : - ContainerPort : 80 LogConfiguration : LogDriver : awslogs Options : awslogs-group : !Ref LogGroup awslogs-region : !Ref AWS : : Region
ECS Service
EcsService : Type : AWS : : ECS : : Service Properties : ServiceName : !Sub "${AWS::StackName}-service" Cluster : !Ref EcsCluster TaskDefinition : !Ref TaskDefinition DesiredCount : 2 LaunchType : FARGATE NetworkConfiguration : AwsvpcConfiguration : AssignPublicIp : DISABLED SecurityGroups : - !Ref ServiceSecurityGroup Subnets : !Ref PrivateSubnets LoadBalancers : - ContainerName : web ContainerPort : 80 TargetGroupArn : !Ref TargetGroup
Application Auto Scaling Target
ScalableTarget : Type : AWS : : ApplicationAutoScaling : : ScalableTarget Properties : MaxCapacity : 10 MinCapacity : 2 ResourceId : !Sub "service/${EcsCluster}/${EcsService.Name}" RoleARN : !GetAtt EcsServiceScalingRole.Arn ScalableDimension : ecs : service : DesiredCount ServiceNamespace : ecs
Target Tracking Scaling Policy
EcsTargetTrackingPolicy : Type : AWS : : ApplicationAutoScaling : : ScalingPolicy Properties : PolicyName : !Sub "${AWS::StackName}-ecs-target-tracking" PolicyType : TargetTrackingScaling ScalingTargetId : !Ref ScalableTarget TargetTrackingScalingPolicyConfiguration : PredefinedMetricSpecification : PredefinedMetricType : ECSServiceAverageCPUUtilization TargetValue : 70 ScaleInCooldown : 300 ScaleOutCooldown : 60
Log Group
LogGroup : Type : AWS : : Logs : : LogGroup Properties : LogGroupName : !Sub "/ecs/${AWS::StackName}" RetentionInDays : 30
Security Group
ServiceSecurityGroup : Type : AWS : : EC2 : : SecurityGroup Properties : GroupName : !Sub "${AWS::StackName}-service-sg" GroupDescription : Security group for ECS service VpcId : !Ref VPCId
Application Load Balancer Target Group
TargetGroup : Type : AWS : : ElasticLoadBalancingV2 : : TargetGroup Properties : Name : !Sub "${AWS::StackName}-ecs-tg" Port : 80 Protocol : HTTP VpcId : !Ref VPCId TargetType : ip
IAM Role for ECS Service Scaling with Least Privilege
EcsServiceScalingRole : Type : AWS : : IAM : : Role Properties : RoleName : !Sub "${AWS::StackName}-ecs-scaling-role" AssumeRolePolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Principal : Service : application - autoscaling.amazonaws.com Action : sts : AssumeRole Policies : - PolicyName : !Sub "${AWS::StackName}-ecs-scaling-policy" PolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Action : - ecs : DescribeServices - ecs : UpdateService Resource : !Sub "arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:service/${EcsCluster}/*" Lambda Provisioned Concurrency Scaling Lambda with Provisioned Concurrency Auto Scaling AWSTemplateFormatVersion : 2010-09-09 Description : Lambda with Application Auto Scaling for provisioned concurrency Resources :
Lambda Function
MyLambdaFunction : Type : AWS : : Lambda : : Function Properties : FunctionName : !Sub "${AWS::StackName}-function" Runtime : python3.11 Handler : app.handler Code : S3Bucket : !Ref CodeBucket S3Key : lambda/function.zip MemorySize : 512 Timeout : 30 Role : !GetAtt LambdaExecutionRole.Arn
Lambda Version
LambdaVersion : Type : AWS : : Lambda : : Version Properties : FunctionName : !Ref MyLambdaFunction Description : Version for provisioned concurrency
Application Auto Scaling Scalable Target
LambdaScalableTarget : Type : AWS : : ApplicationAutoScaling : : ScalableTarget Properties : MaxCapacity : 20 MinCapacity : 5 ResourceId : !Sub "function:${MyLambdaFunction}:${LambdaVersion.Version}" RoleARN : !GetAtt LambdaScalingRole.Arn ScalableDimension : lambda : function : ProvisionedConcurrency ServiceNamespace : lambda
Target Tracking Scaling Policy
LambdaTargetTrackingPolicy : Type : AWS : : ApplicationAutoScaling : : ScalingPolicy Properties : PolicyName : !Sub "${AWS::StackName}-lambda-target-tracking" PolicyType : TargetTrackingScaling ScalingTargetId : !Ref LambdaScalableTarget TargetTrackingScalingPolicyConfiguration : TargetValue : 90 PredefinedMetricSpecification : PredefinedMetricType : LambdaProvisionedConcurrencyUtilization ScaleInCooldown : 120 ScaleOutCooldown : 60
Lambda Execution Role
LambdaExecutionRole : Type : AWS : : IAM : : Role Properties : RoleName : !Sub "${AWS::StackName}-lambda-role" AssumeRolePolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Principal : Service : lambda.amazonaws.com Action : sts : AssumeRole ManagedPolicyArns : - arn : aws : iam : : aws : policy/service - role/AWSLambdaBasicExecutionRole
IAM Role for Lambda Scaling with Least Privilege
LambdaScalingRole : Type : AWS : : IAM : : Role Properties : RoleName : !Sub "${AWS::StackName}-lambda-scaling-role" AssumeRolePolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Principal : Service : application - autoscaling.amazonaws.com Action : sts : AssumeRole Policies : - PolicyName : !Sub "${AWS::StackName}-lambda-scaling-policy" PolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Action : - lambda : PutProvisionedConcurrencyConfig - lambda : GetProvisionedConcurrencyConfig Resource : !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${MyLambdaFunction}:*" Conditions and Transform Conditions for Environment-Specific Scaling AWSTemplateFormatVersion : 2010-09-09 Description : Auto Scaling with conditional scaling configuration Parameters : Environment : Type : String Default : dev AllowedValues : - dev - staging - production Conditions : IsProduction : !Equals [ !Ref Environment , production ] IsStaging : !Equals [ !Ref Environment , staging ] UseSpot : !Or [ !Equals [ !Ref Environment , dev ] , !Equals [ !Ref Environment , staging ] ] UseAlb : !Not [ !Equals [ !Ref Environment , dev ] ] EnableDetailedMonitoring : !Not [ !Equals [ !Ref Environment , dev ] ] Resources : MyLaunchConfiguration : Type : AWS : : AutoScaling : : LaunchConfiguration Properties : LaunchConfigurationName : !Sub "${AWS::StackName}-lc" ImageId : !Ref AmiId InstanceType : !If [ IsProduction , t3.large , !If [ IsStaging , t3.medium , t3.micro ] ] InstanceMonitoring : !If [ EnableDetailedMonitoring , Enabled , Basic ] MyAutoScalingGroup : Type : AWS : : AutoScaling : : AutoScalingGroup Properties : AutoScalingGroupName : !Sub "${AWS::StackName}-asg" MinSize : !If [ IsProduction , 3 , !If [ IsStaging , 2 , 1 ] ] MaxSize : !If [ IsProduction , 12 , !If [ IsStaging , 6 , 3 ] ] DesiredCapacity : !If [ IsProduction , 3 , !If [ IsStaging , 2 , 1 ] ] VPCZoneIdentifier : !Ref SubnetIds LaunchConfigurationName : !Ref MyLaunchConfiguration HealthCheckType : !If [ UseAlb , ELB , EC2 ] HealthCheckGracePeriod : !If [ UseAlb , 300 , 300 ] Transform for Code Reuse AWSTemplateFormatVersion : 2010-09-09 Transform : AWS : : Serverless - 2016-10-31 Description : Using SAM for simplified Auto Scaling Globals : Function : Timeout : 30 Runtime : python3.11 Tracing : Active Environment : Variables : LOG_LEVEL : INFO Parameters : Environment : Type : String Default : dev Resources :
Auto Scaling Group using SAM
WebServerGroup : Type : AWS : : Serverless : : Application Properties : Location : ./asg - template.yaml Parameters : Environment : !Ref Environment CloudFormation Stack Management Best Practices Stack Policies Stack Policies prevent unintentional updates to critical stack resources. Use them to protect Auto Scaling Groups from accidental modifications or deletions. AWSTemplateFormatVersion : 2010-09-09 Description : Stack with policy to protect Auto Scaling resources Resources : MyAutoScalingGroup : Type : AWS : : AutoScaling : : AutoScalingGroup Properties : AutoScalingGroupName : !Sub "${AWS::StackName}-asg" MinSize : 2 MaxSize : 10 DesiredCapacity : 2 VPCZoneIdentifier : !Ref SubnetIds LaunchConfigurationName : !Ref MyLaunchConfiguration MyLaunchConfiguration : Type : AWS : : AutoScaling : : LaunchConfiguration Properties : LaunchConfigurationName : !Sub "${AWS::StackName}-lc" ImageId : !Ref AmiId InstanceType : t3.micro Metadata : AWS::CloudFormation::StackPolicy : Statement : - Effect : Allow Resource : "" Action : Update : Modify - Effect : Deny Resource : "" Action : Update : Delete Condition : StringEquals : ResourceType : - AWS : : AutoScaling : : AutoScalingGroup - AWS : : AutoScaling : : LaunchConfiguration Termination Protection Enable termination protection to prevent accidental deletion of Auto Scaling Groups. This is critical for production environments.
Enable termination protection on an existing stack
aws cloudformation update-termination-protection \ --stack-name my-auto-scaling-stack \ --enable-termination-protection
Check if termination protection is enabled
aws cloudformation describe-stacks \ --stack-name my-auto-scaling-stack \ --query "Stacks[0].EnableTerminationProtection" Drift Detection Detect when your Auto Scaling infrastructure has been modified outside of CloudFormation.
Detect drift on a stack
aws cloudformation detect-stack-drift \ --stack-name my-auto-scaling-stack
Get drift detection status
aws cloudformation describe-stack-drift-detection-status \ --stack-name my-auto-scaling-stack
Get drift detection results
aws cloudformation describe-stack-resource-drifts \ --stack-name my-auto-scaling-stack
Check specific resource drift
aws cloudformation describe-stack-resource-drifts \ --stack-name my-auto-scaling-stack \ --stack-resource-drifts-not-in-sync Change Sets Use Change Sets to preview and review changes before applying them to your Auto Scaling infrastructure.
Create a change set
aws cloudformation create-change-set \ --stack-name my-auto-scaling-stack \ --change-set-name my-changeset \ --template-body file://template.yaml \ --parameters ParameterKey = Environment,ParameterValue = production
List change sets
aws cloudformation list-change-sets \ --stack-name my-auto-scaling-stack
Describe change set
aws cloudformation describe-change-set \ --stack-name my-auto-scaling-stack \ --change-set-name my-changeset
Execute change set
aws cloudformation execute-change-set \ --stack-name my-auto-scaling-stack \ --change-set-name my-changeset
Automated change set creation in CI/CD pipeline
Resources : ChangeSetRole : Type : AWS : : IAM : : Role Properties : AssumeRolePolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Principal : Service : cloudformation.amazonaws.com Action : sts : AssumeRole Policies : - PolicyName : ChangeSetPolicy PolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Action : - autoscaling : Describe - cloudwatch : Describe - ec2 : Describe Resource : "" - Effect : Allow Action : - autoscaling : UpdateAutoScalingGroup - autoscaling : CreateOrUpdateTags - cloudwatch : PutMetricAlarm - cloudwatch : DeleteAlarms Resource : - !Sub "arn:aws:autoscaling:${AWS::Region}:${AWS::AccountId}:autoScalingGroup::autoScalingGroupName/" - !Sub "arn:aws:cloudwatch:${AWS::Region}:${AWS::AccountId}:alarm:*" Best Practices High Availability Distribute instances across multiple AZs Use ALB with health checks for automatic routing Implement lifecycle hooks for graceful shutdown Configure appropriate termination policies Use mixed instances policies for diversity Cost Optimization Use Spot Instances for fault-tolerant workloads Implement right-sizing of instances Configure aggressive scale-in policies Use scheduled scaling for predictable patterns Monitor and optimize regularly Monitoring Create CloudWatch Alarms for key metrics Implement scaling policies based on metrics Use lifecycle hooks for logging and analytics Configure SNS notifications for scaling events Implement detailed monitoring for troubleshooting Security Use IAM roles with minimum permissions Encrypt EBS volumes with KMS Configure restrictive security groups Use VPC with appropriate subnets Implement parameter store for sensitive configuration Avoid using broad managed policies like CloudWatchFullAccess Use specific permissions instead of broad managed policies Least Privilege IAM Examples
Instead of CloudWatchFullAccess, use specific permissions
ScalingAlarmRole : Type : AWS : : IAM : : Role Properties : RoleName : !Sub "${AWS::StackName}-scaling-alarm-role" AssumeRolePolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Principal : Service : autoscaling.amazonaws.com Action : sts : AssumeRole Policies : - PolicyName : !Sub "${AWS::StackName}-cloudwatch-specific-policy" PolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Action : - cloudwatch : PutMetricAlarm - cloudwatch : DescribeAlarms - cloudwatch : DeleteAlarms - cloudwatch : EnableAlarmActions - cloudwatch : DisableAlarmActions Resource : !Sub "arn:aws:cloudwatch:${AWS::Region}:${AWS::AccountId}:alarm:*" Related Resources Auto Scaling Documentation AWS CloudFormation User Guide Auto Scaling Best Practices Application Auto Scaling Additional Files For complete details on resources and their properties, consult: REFERENCE.md - Detailed reference guide for all CloudFormation resources EXAMPLES.md - Complete production-ready examples