Wednesday 8 March 2023

AWS EC2 Auto Scaling with Terraform


aws_autoscaling_group | Resources | hashicorp/aws | Terraform Registry

The minimum implementation that will pass terraform plan checks is:

resource "aws_autoscaling_group" "my_app" {
  min_size = 1
  max_size = 1

terraform plan output:

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_autoscaling_group.my_app will be created
  + resource "aws_autoscaling_group" "my_app" {
      + arn                       = (known after apply)
      + availability_zones        = (known after apply)
      + default_cooldown          = (known after apply)
      + desired_capacity          = (known after apply)
      + force_delete              = false
      + force_delete_warm_pool    = false
      + health_check_grace_period = 300
      + health_check_type         = (known after apply)
      + id                        = (known after apply)
      + max_size                  = 1
      + metrics_granularity       = "1Minute"
      + min_size                  = 1
      + name                      = (known after apply)
      + protect_from_scale_in     = false
      + service_linked_role_arn   = (known after apply)
      + vpc_zone_identifier       = (known after apply)
      + wait_for_capacity_timeout = "10m"


If we try to run terraform apply, we'll get the following error:

Error: One of `launch_configuration`, `launch_template`, or `mixed_instances_policy` must be set for an Auto Scaling Group 


Using Launch Configuration for defining EC2

Let's use a launch configuration (despite AWS discouraging the use of launch configurations in favour of launch templates; example with launch template is further down in this article).

We need to know the ID of the AMI we want to use. We'll choose the latest Amazon Linux 2 image, of t2.micro type which allows free tier.

If we select it, the next page will show its ID:

Terraform resource we'll use is aws_launch_configuration | Resources | hashicorp/aws | Terraform Registry.


# EC2 >> Launch configurations
resource "aws_launch_configuration" "my-app" {
  name          = "my-app"
  image_id      = "ami-006dcf34c09e50022"
  instance_type = "t2.micro"

We can now update our auto scaling group:

resource "aws_autoscaling_group" "my-app" {
  min_size = 1
  max_size = 1
  name = "my-app"
  launch_configuration =


terraform apply still complains:

Error: Error creating Auto Scaling Group: ValidationError: At least one Availability Zone or VPC Subnet is required.
        status code: 400, request id: ad34ea76-a6d5-419a-bc48-0ffb15b4e76f


Let's define the subnet which we want our instances to be launched into:

resource "aws_autoscaling_group" "my-app" {
  min_size = 1
  max_size = 1
  name = "
  launch_configuration = aws_launch_configuration.
  vpc_zone_identifier = [ "subnet-14321c874d6d35c6a" ]

terraform apply will now create the autoscaling group together with launch configuration. This can be verified by looking at EC2 >> Auto Scaling groups and EC2 >> Launch configurations. And most importantly, auto scaling group will launch the new EC2 instance, in subnet we denoted in the configuration. This instance can be found in EC2 >> Instances.


Using Launch Template for defining EC2

AWS discourages the use of launch configurations in favour of launch templates.

Terraform resource is aws_launch_template | Resources | hashicorp/aws | Terraform Registry. Its description says:

Provides an EC2 launch template resource. Can be used to create instances or auto scaling groups.

Here are the key differences between launch templates (LT) and launch configuration (LC):

  • LT have more EC2 options than LC
  • LT are getting latest features from Amazon EC2
  • LC are still supported but are not getting the latest EC2 features
  • LC is immutable (resource can't be edited; if we want to change it, we need to destroy it first and then re-create it)
  • LT can be edited and updated
  • LT can have multiple versions which allows creation of parameter subsets (With versioning, you can create a subset of the full set of parameters and then reuse it to create other templates or template versions. - Partial configuration for reuse and inheritance)
  • LT allows using T2 unlimited burst credit option
  • LT allows provisioning using both On-demand and Spot Instances.
  • LT can be used to launch a standalone instance using AWS Console, SDK and CLI.




No comments: