AWS Auto Scaling groups provide a logical container for EC2 instances that share the same configuration and scaling rules. Terraform is used to declare those groups and the supporting resources so that capacity can be managed declaratively and repeatedly across environments. Because an Auto Scaling group is dynamic by design, the Terraform configuration must account for actions that change instance counts outside of Terraform plan and apply.
This article covers the core concepts, Terraform resource patterns, scaling policy configuration, lifecycle management, and module-based approaches for building production ready Auto Scaling groups.
Core Concepts of Auto Scaling Groups
An Auto Scaling Group is a collection of EC2 instances treated as a logical grouping for automatic scaling and management. You specify minimum, maximum, and desired capacity for each group. The minimum capacity defines the floor for running instances, the maximum capacity sets the ceiling, and desired capacity is the target number of instances the group attempts to maintain.
An Auto Scaling group helps ensure the correct number of Amazon EC2 instances are available to handle load for an application. You can manage the number of running instances manually or dynamically, allowing you to lower operating costs. Since ASGs are dynamic, Terraform does not manage the underlying instances directly because every scaling action would introduce state drift.
When an Auto Scaling group is used with a load balancer, traffic can be distributed across the instances in the group and the group can react to load changes by adding or removing instances.
Terraform Fundamentals for ASG Provisioning
Terraform is a preferred way to set up ASGs over manual configuration in the AWS console because it brings consistency, version control, and automation to deployments. Infrastructure as Code has become essential for managing cloud resources, and Terraform allows you to define AWS resources like Auto Scaling Groups in declarative configuration files, enabling consistent repeatable deployments across environments while maintaining version control.
A standard Terraform workflow is assumed. The configuration typically includes a provider block, a launch template, and an autoscaling group resource.
A basic provider declaration sets the target region.
hcl
provider "aws" {
region = "us-west-2"
}
The launch template defines the instance configuration used by the group. Launch templates are recommended over launch configurations for all new and existing Auto Scaling groups to ensure access to the latest features and instance types. As of January 1, 2023, new instance types are no longer supported in launch configurations, and AWS recommends migrating to launch templates.
Launch Templates vs Launch Configurations
Launch configurations provide a fixed set of parameters for launching instances. Launch templates provide more flexibility, versioning, and support for newer instance types.
The launch template block can specify a name prefix, image id, instance type, and security groups.
hcl
resource "aws_launch_template" "template" {
name_prefix = "test"
image_id = "ami-1a2b3c"
instance_type = "t2.micro"
security_groups = ["sg-12345678"]
}
The autoscaling group resource references the launch template and defines capacity and networking.
```hcl
resource "awsautoscalinggroup" "autoscale" {
name = "test-autoscaling-group"
availabilityzones = ["us-west-2"]
desiredcapacity = 3
maxsize = 6
minsize = 3
healthchecktype = "EC2"
terminationpolicies = ["OldestInstance"]
vpczone_identifier = ["subnet-12345678"]
launchtemplate {
id = awslaunch_template.template.id
version = "$Latest"
}
}
```
Key attributes of the autoscaling group resource include:
| Attribute | Purpose |
|---|---|
| name | Identifier for the group |
| availability_zones | AZs where instances can launch |
| desired_capacity | Target number of instances |
| max_size | Upper bound for scaling |
| min_size | Lower bound for scaling |
| healthchecktype | EC2 or ELB health evaluation |
| termination_policies | Order for instance termination |
| vpczoneidentifier | Subnets for instance placement |
| launch_template | Reference to launch template |
Scaling Policies and Dynamic Capacity
An Auto Scaling Group without scaling policies is just a fixed-size group of instances. The real power comes from policies that automatically adjust capacity based on metrics, schedules, or predictions. Terraform supports all the scaling policy types AWS offers.
Simple scaling is the oldest and most straightforward type. It adds or removes a fixed number of instances when a CloudWatch alarm fires.
Policy types supported in Terraform include:
| Policy Type | Behavior |
|---|---|
| Simple Scaling | Fixed number of instances added or removed on alarm |
| Step Scaling | Different scaling adjustments based on alarm thresholds |
| Target Tracking | Maintains a target metric value automatically |
| Scheduled Scaling | Adjusts capacity based on predictable time patterns |
Getting the right combination can make the difference between a responsive application and one that crumbles under load. Scaling policies can be attached to an ASG and tied to CloudWatch alarms for CPU, network, queue length, or custom metrics.
Determine the scaling policies you want to apply to the Auto Scaling group before finalizing the resource configuration.
Lifecycle Hooks and Instance Refresh
Advanced ASG configurations require lifecycle hooks and instance refresh to manage rolling updates safely.
Lifecycle hooks allow actions to be triggered on instance launch or termination. Example hook definitions include:
- ExampleStartupLifeCycleHook for autoscaling:EC2INSTANCELAUNCHING
- ExampleTerminationLifeCycleHook for autoscaling:EC2INSTANCETERMINATING
Instance refresh enables controlled replacement of instances when the launch template changes. Preferences can control checkpoint delay, checkpoint percentages, instance warmup, min healthy percentage, and max healthy percentage.
A module example shows how these features are expressed:
```hcl
module "asg" {
source = "terraform-aws-modules/autoscaling/aws"
name = "example-asg"
minsize = 0
maxsize = 1
desiredcapacity = 1
waitforcapacitytimeout = 0
healthchecktype = "EC2"
vpczoneidentifier = ["subnet-1235678", "subnet-87654321"]
initiallifecyclehooks = [
{
name = "ExampleStartupLifeCycleHook"
defaultresult = "CONTINUE"
heartbeattimeout = 60
lifecycletransition = "autoscaling:EC2INSTANCELAUNCHING"
notificationmetadata = jsonencode({ "hello" = "world" })
}
]
instancerefresh = {
strategy = "Rolling"
preferences = {
checkpointdelay = 600
checkpointpercentages = [35, 70, 100]
instancewarmup = 300
minhealthypercentage = 50
maxhealthypercentage = 100
}
triggers = ["tag"]
}
}
```
Module Patterns and Advanced Configuration
The terraform-aws-modules terraform-aws-autoscaling module creates Auto Scaling resources on AWS. Capabilities include:
- Autoscaling group with launch template either created by the module or utilizing an existing launch template
- Autoscaling group utilizing mixed instances policy
- Ability to configure autoscaling groups to set instance refresh configuration and add lifecycle hooks
- Ability to create an autoscaling group that respects desired_capacity or one that ignores to allow for scaling without conflicting Terraform diffs
- IAM role and instance profile creation
Module usage centralizes common patterns for launch templates, capacity settings, health checks, and refresh behavior. For larger organizations, Terragrunt serves as an excellent thin wrapper around Terraform that provides additional benefits.
Avoiding State Drift and Lifecycle Management
Because Auto Scaling groups are dynamic, Terraform does not manage the underlying instances directly because every scaling action would introduce state drift. You can use Terraform lifecycle arguments to avoid drift or accidental changes.
Common techniques include using lifecycle meta arguments to ignore changes to desiredcapacity, or setting createbefore_destroy where appropriate. Understanding how Terraform configuration supports the dynamic aspects of the resource is critical.
In a tutorial flow you will use Terraform to provision and manage an Auto Scaling group and learn how Terraform configuration supports the dynamic aspects of the resource. You will launch an ASG with traffic managed by a load balancer and define a scaling policy to automatically modify the number of instances running in the group. You will learn how to use lifecycle arguments to avoid unwanted scaling of your ASG.
Conclusion
Building Auto Scaling Groups with Terraform requires balancing declarative intent with the operational reality that AWS will change instance counts independently of Terraform state. Defining minimum, maximum, and desired capacity establishes the bounds for automatic behavior, while launch templates provide a forward compatible way to describe instance configuration.
Scaling policies transform a static collection of instances into a responsive system that adjusts to metrics, schedules, or predictions. Lifecycle hooks and instance refresh give operators control over rollout safety, and modules encapsulate these patterns for reuse across teams.
The value proposition of Auto Scaling Groups with Terraform is self-healing, efficient infrastructure that adapts to business needs without manual intervention. Whether scaling to handle millions of users or ensuring an application never goes down at 3 AM, AWS Auto Scaling Groups paired with Terraform provide the foundation for consistent, auditable, and automated capacity management.
Sources
- https://developer.hashicorp.com/terraform/tutorials/aws/aws-asg
- https://www.linkedin.com/pulse/aws-auto-scaling-groups-asg-terraform-deep-dive-part-1-ali-abdukarim-3cpsc
- https://oneuptime.com/blog/post/2026-02-23-configure-auto-scaling-policies-in-terraform/view
- https://spacelift.io/blog/terraform-autoscaling-group
- https://github.com/terraform-aws-modules/terraform-aws-autoscaling