Automate Scaling with Terraform: Building an AWS Auto Scaling Group
Srinivasan (Srini) Viswanathan
Service Delivery Leader | DevOps Engineer| Kubernetes | Terraform | CI/CD | Containers| AWS | GCP | Observability | GKE | EKS
Scaling your EC2 instances based on demand is crucial for maintaining application performance and cost-efficiency. AWS Auto Scaling Groups (ASGs) offer an automated solution, allowing your infrastructure to dynamically adjust resource allocation. This article guides you through creating an ASG using Terraform, an infrastructure as code (IaC) tool, providing greater control and repeatability.
Prerequisites:
Steps:
1.Create VPC & Subnet: Below code, creates a standard aws vpc with DNS support and DNS hostname enabled. Subnet code enables public ip mapping.
# Create VPC & Subnet
resource "aws_vpc" "asg" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
instance_tenancy = "default"
tags = {
Name = "asg-vpc"
}
}
resource "aws_subnet" "asg" {
vpc_id = aws_vpc.asg.id
cidr_block = "10.0.1.0/24"
availability_zone ="us-west-2a"
map_public_ip_on_launch = true # this will enable a public ip for subnet created
tags = {
Name = "asg-subnet "
}
}
2. Network: In this section, terraform will create four resources.
AWS Internet Gateway provides a path for internet traffic to and from VPC.
A route table is essential for managing and controlling the flow of traffic within a VPC.
领英推荐
A route table association is created for subnet association, particularly scenarios where multiple subnets are present.
A Security Group acts as a firewall to control both inbound and outbound traffic, in this example, port 22 & 80 configured for inbound and full access (which may not be ideal for production) to internet for outbound traffic.
# create internet gateway, route table, route table association, and
# security group to open egress and ingress ports for ssh 22 and http 80
resource "aws_internet_gateway" "asg" {
vpc_id = aws_vpc.asg.id
tags = {
Name = "asg-igw"
}
}
resource "aws_route_table" "asg" {
vpc_id = aws_vpc.asg.id
route {
// associated subnet can reach everywhere
cidr_block = "0.0.0.0/0"
// use this IGW to reach internet
gateway_id = aws_internet_gateway.asg.id
}
tags = {
Name = "asg-route-table"
}
}
resource "aws_route_table_association" "asg" {
subnet_id = aws_subnet.asg.id
route_table_id = aws_route_table.asg.id
}
resource "aws_security_group" "asg" {
name = "asg-sg"
description = "Allow ssh and http inbound traffic"
vpc_id = aws_vpc.asg.id
ingress {
description = "ssh from VPC"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "http from VPC"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "asg-security-group"
}
}
3. ASG - Auto Scaling Group is a service which automatically scale the number of EC2 instances based on provided conditions. (Here we are using min=1; max=1). In this section we will be creating three resources.
AWS key pair is a cryptic key to securely connect and authenticate with EC2. This key pair set consists of public & private key. We use ssh-keygen command to generate keys, while public key is stored in EC2 instance & private key is securely store in client machine for access.
Launch configuration is a template used by ASG to launch EC2. Refer to below snippet for required parameters defined in the template. user-data parameter is defined to execute needed commands during creating of the instance. In this case, we are invoking a shell script to install, launch and customize a web server which can be accessed through port 80.
Auto Scaling Group allows to configure scaling behavior. we are using depends_on attribute to ensure a subnet is created before launching ASG.
# Steps to create auto scaling group
# 1. aws key pair
# 2. launch configuration &
# 3. auto scaling group
# 1. aws key pair
resource "aws_key_pair" "asg" {
key_name = var.key_name
public_key = file(var.PUBLIC_KEY_PATH)
}
# 2. launch configuration
resource "aws_launch_configuration" "asg" {
name_prefix = "asg-launch-config"
image_id = var.ami
instance_type = var.instance_type
key_name = aws_key_pair.asg.id
security_groups = [
aws_security_group.asg.id
]
user_data = "${file(var.startup_script)}"
lifecycle {
create_before_destroy = true
}
}
# 3. auto scaling group
resource "aws_autoscaling_group" "asg" {
name = "asg-group"
launch_configuration = aws_launch_configuration.asg.name
min_size = 1
max_size = 1
vpc_zone_identifier = ["${aws_subnet.asg.id}"]
depends_on = [aws_subnet.asg]
tag {
key = "Name"
value = "asg-group"
propagate_at_launch = true
}
}
By utilizing Terraform, you can create and manage ASGs in a declarative and repeatable manner. This approach provides greater control and simplifies infrastructure provisioning for your AWS applications. Remember to customize the code based on your specific requirements and security best practices.