πŸš€ Build an AWS Infrastructure with Terraform – VPC, Load Balancer & Auto Scaling

VinuthnaVinuthna
4 min read

In this post, we’ll walk through automating the deployment of a complete AWS infrastructure using Terraform. The setup includes a VPC, public subnets, internet connectivity, EC2 launch templates, a load balancer, and an auto scaling group β€” all managed with infrastructure as code.


πŸ—‚οΈ What We’re Building

Using Terraform, we will provision:

  • A VPC

  • Two public subnets in different Availability Zones

  • An Internet Gateway

  • A Route Table and associations

  • A Security Group that allows traffic

  • A Launch Template for EC2 instances

  • An Elastic Load Balancer

  • An Auto Scaling Group


πŸ“ Step 1: provider.tf – AWS Provider Setup

hclCopyEditprovider "aws" {
  region = "us-east-2"
}

➑️ This tells Terraform to use the AWS provider and deploy resources in the us-east-2 region.


πŸ“ Step 2: main.tf – Launch Template, Load Balancer & Auto Scaling Group

πŸ”Έ Launch Template

hCopyEditresource "aws_launch_template" "mylt" {
  name          = "Terraform-LT"
  image_id      = "ami-05df0ea761147eda6"
  instance_type = "t2.micro"
  key_name      = "Ansible"

  placement {
    availability_zone = "us-east-1a"
  }

  vpc_security_group_ids = [aws_security_group.mysg.id]
  user_data              = filebase64("/root/netflix/netflix.sh")
}

This template defines the EC2 instance config that will be used by the Auto Scaling Group.


πŸ”Έ Load Balancer

hCopyEditresource "aws_elb" "myelb" {
  name            = "terraformlb"
  subnets         = [aws_subnet.mysubnet1.id, aws_subnet.mysubnet2.id]
  security_groups = [aws_security_group.mysg.id]

  listener {
    instance_port     = 80
    instance_protocol = "HTTP"
    lb_port           = 80
    lb_protocol       = "HTTP"
  }

  tags = {
    Name = "Terraform-LB"
  }
}

The ELB distributes incoming traffic across the EC2 instances in the Auto Scaling Group.


πŸ”Έ Auto Scaling Group (ASG)

hclCopyEditresource "aws_autoscaling_group" "myasg" {
  name                 = "Terraform-Asg"
  min_size             = 2
  max_size             = 4
  desired_capacity     = 2
  health_check_type    = "EC2"
  load_balancers       = [aws_elb.myelb.name]
  vpc_zone_identifier  = [aws_subnet.mysubnet1.id, aws_subnet.mysubnet2.id]

  launch_template {
    id      = aws_launch_template.mylt.id
    version = "$Latest"
  }

  tag {
    key                 = "Name"
    value               = "ASG-instance"
    propagate_at_launch = true
  }
}

The ASG automatically scales your EC2 instances based on demand.


πŸ“ Step 3: routetable.tf – Internet Routing

hclCopyEditresource "aws_route_table" "myrt" {
  vpc_id = aws_vpc.myvpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.myigw.id
  }

  tags = {
    Name = "Terraform-RT"
  }
}

The route table allows internet traffic to flow through the internet gateway.


πŸ“ Step 4: security.tf – Security Group

hclCopyEditresource "aws_security_group" "mysg" {
  name        = "terraform-sg"
  description = "Allow all traffic"
  vpc_id      = aws_vpc.myvpc.id

  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

This group allows all inbound and outbound traffic. Be sure to restrict this in production environments.


πŸ“ Step 5: subnetassociation.tf – Attach Subnets to Route Table

hclCopyEditresource "aws_route_table_association" "subnet1" {
  subnet_id      = aws_subnet.mysubnet1.id
  route_table_id = aws_route_table.myrt.id
}

resource "aws_route_table_association" "subnet2" {
  subnet_id      = aws_subnet.mysubnet2.id
  route_table_id = aws_route_table.myrt.id
}

These associations connect your subnets to the route table for internet access.


πŸ“ Step 6: subnet.tf – Public Subnets

hclCopyEditresource "aws_subnet" "mysubnet1" {
  vpc_id                  = aws_vpc.myvpc.id
  cidr_block              = "10.0.0.0/24"
  availability_zone       = "us-east-2a"
  map_public_ip_on_launch = true

  tags = {
    Name = "Subnet-1"
  }
}

resource "aws_subnet" "mysubnet2" {
  vpc_id                  = aws_vpc.myvpc.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "us-east-2b"
  map_public_ip_on_launch = true

  tags = {
    Name = "Subnet-2"
  }
}

Each subnet is placed in a different Availability Zone for high availability.


πŸ“ Step 7: vpc.tf – Create VPC

hclCopyEditresource "aws_vpc" "myvpc" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  instance_tenancy     = "default"

  tags = {
    Name = "Terraform-VPC"
  }
}

The VPC is your own private network space in AWS where all resources are launched.


πŸ“ Step 8: igw.tf – Internet Gateway

hclCopyEditresource "aws_internet_gateway" "myigw" {
  vpc_id = aws_vpc.myvpc.id

  tags = {
    Name = "myigw"
  }
}

This allows your resources to access the internet.


πŸ§ͺ How to Execute This Project

Now that your .tf files are ready, follow these Terraform CLI commands to build your infrastructure:

bashCopyEdit# 1. Initialize the project
terraform init

# 2. Check your configuration for errors
terraform validate

# 3. See what will be created
terraform plan

# 4. Apply the configuration
terraform apply

# 5. (Optional) Destroy the infrastructure when you're done
terraform destroy

🟒 Make sure your AWS credentials are configured (~/.aws/credentials or environment variables) before running these commands.


βœ… Final Thoughts

With these 8 Terraform files and simple commands, you’ve automated the provisioning of an entire AWS architecture β€” scalable, repeatable, and production-ready.

This project forms the foundation of many real-world DevOps setups. Once you're comfortable with it, try:

  • Using variables.tf for reusability

  • Creating reusable modules

  • Storing state in S3 for collaboration

Thanks for reading! πŸ™Œ
Let me know in the comments if you have any questions or want the GitHub repo!

0
Subscribe to my newsletter

Read articles from Vinuthna directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Vinuthna
Vinuthna

Why Collaborate with Me? ~ Infrastructure as Code (IaC): Skilled in automating infrastructure provisioning with Terraform and Ansible, ensuring consistency, scalability, and repeatability. ~ Containerization & Orchestration: Expert in building, managing, and scaling containerized applications using Docker and Kubernetes clusters. ~ CI/CD Expertise: Proficient in designing and optimizing Jenkins pipelines for seamless code integration, testing, and deployment workflows. ~ Linux Systems Mastery: Strong background in Linux system administration, scripting, performance tuning, and server management. ~ Automation Enthusiast: Adept at automating repetitive tasks and complex workflows with Ansible, shell scripting, and YAML-driven configurations. ~ Problem Solver: Quick to learn emerging technologies, troubleshoot complex issues, and optimize systems for maximum reliability and efficiency. ~ Detail-Oriented: Committed to delivering clean, secure, and high-quality solutions that meet both business and technical goals. Core Competencies ~ DevOps Tools: Jenkins, Docker, Kubernetes, Ansible, Terraform, Git, Bitbucket, YAML ~ Infrastructure as Code: Terraform, Ansible ~ Containerization and Orchestration: Docker, Kubernetes ~ Continuous Integration/Continuous Deployment: Jenkins Pipelines, GitOps workflows ~ Operating Systems: Linux (Ubuntu, CentOS) ~ Scripting: Shell scripting, YAML ~ Monitoring & Logging: (Optional, if you know Prometheus, Grafana, or similar tools.) ~ Project Management: Jira, Slack, Agile Methodologies