DEV Community

Cover image for AWS Project: Deploying a VPC with Terraform
Asif Khan
Asif Khan

Posted on

AWS Project: Deploying a VPC with Terraform

Introduction

As cloud infrastructure becomes the backbone of modern applications, managing resources efficiently and securely is essential. This blog post details the process of provisioning a Virtual Private Cloud (VPC) in AWS using Terraform, an Infrastructure as Code (IaC) tool. By the end of this post, you'll understand how to automate the deployment of a fully functional VPC environment, including public and private subnets, routing configurations, and EC2 instances, all through Terraform.

Why use Terraform?

Terraform is widely used for managing cloud infrastructure because of its simplicity and flexibility. In AWS, setting up a VPC manually involves several steps and careful planning. Terraform automates this process, ensuring consistency and reducing the risk of human error. This project illustrates how to create a reliable, scalable network infrastructure in AWS that can be easily managed and modified through code.

What you will learn:

  • How to use Terraform to create a VPC, subnets, route tables, gateways, and EC2 instances.
  • How to manage resources with Terraform for future scalability and automation.

Tech Stack

This project leverages the following technologies and services:

  • Terraform: An open-source IaC tool used to define and provision infrastructure.
  • Amazon VPC: A virtual network in AWS for isolating and managing resources.
  • Amazon EC2: Virtual servers (instances) running inside the VPC for various application workloads.
  • Security Groups: Firewall configurations that control inbound and outbound traffic to EC2 instances.

Additional services involved:

  • NAT Gateway: Enables instances in private subnets to access the internet.
  • Elastic IP: Used for the NAT gateway.
  • Route Tables: Direct network traffic to and from subnets.

Prerequisites

Before starting this project, make sure you have the following in place:

  1. Basic knowledge of AWS: Familiarity with services such as VPC, EC2, and IAM.
  2. Terraform installed locally: Download and install Terraform on your machine.
  3. AWS account: Ensure you have proper IAM credentials and permissions to manage AWS resources.
  4. AWS CLI configured: Have the AWS CLI configured to verify resource deployments.
  5. Text editor/IDE: Tools like VS Code will help you write and manage your Terraform scripts.

Problem Statement or Use Case

Provisioning AWS infrastructure manually through the console can be time-consuming, error-prone, and inefficient, especially when managing large, complex environments. The need for automation becomes clear when considering scalability, ease of deployment, and consistency across multiple environments.

Key Challenge

Create a scalable, secure, and customizable VPC environment using Infrastructure as Code (IaC), allowing teams to spin up resources on demand while maintaining best practices for networking and security.

Solution

This project demonstrates how to use Terraform to automate the deployment of a VPC with both public and private subnets, NAT and internet gateways, and EC2 instances. The result is a flexible, repeatable infrastructure that can be deployed or destroyed quickly and efficiently—a critical capability for modern DevOps and cloud environments.

Architecture Diagram

The architecture for this project involves several AWS components working together to create a network that securely connects private and public resources. Below is a high-level visual representation of the architecture:

Deploy a VPC with Terraform

Component Breakdown

  1. Virtual Private Cloud (VPC): Provides a private, isolated network in AWS where resources such as EC2 instances are hosted.
  2. Public and Private Subnets: Segments the network, allowing specific instances (in public subnets) to communicate with the internet, while others (in private subnets) remain isolated.
  3. Route Tables and Route Associations: Manage how traffic flows to and from the internet and between different subnets.
  4. Internet Gateway: Allows communication between resources in the public subnet and the internet.
  5. NAT Gateway: Enables instances in private subnets to access the internet without exposing them directly.
  6. EC2 Instances: Virtual machines deployed in both the public and private subnets.
  7. Security Groups: Control inbound and outbound traffic for EC2 instances, ensuring secure access.

Step-by-Step Implementation

1. Download Terraform Binaries and Set Up Workspace

  • Download the Terraform binaries from the official Terraform website.
  • Initialize your project folder and Terraform configuration files:
  terraform init
Enter fullscreen mode Exit fullscreen mode

2. Provider Configuration

provider "aws" {
  region     = "us-east-1"
  access_key = "***"
  secret_key = "***"
}
Enter fullscreen mode Exit fullscreen mode

Explanation: Configures the AWS provider, specifying the region and credentials needed to manage resources in your AWS account.

3. Creating a VPC

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  enable_dns_support = true
  enable_dns_hostnames = true
  tags = {
    Name = "main_vpc"
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation: Creates a Virtual Private Cloud (VPC) with a specified CIDR block and enables DNS support and hostnames.

4. Public Subnet

resource "aws_subnet" "public" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"
  availability_zone = "us-east-1a"
  map_public_ip_on_launch = true
  tags = {
    Name = "public_subnet"
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation: Defines a public subnet within the VPC, allowing instances to have public IP addresses.

5. Private Subnet

resource "aws_subnet" "private" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.2.0/24"
  availability_zone = "us-east-1a"
  tags = {
    Name = "private_subnet"
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation: Creates a private subnet where instances do not receive public IP addresses.

6. Internet Gateway

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "main_igw"
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation: Creates an Internet Gateway to enable internet access for instances in the public subnet.

7. Public Route Table

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

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

  tags = {
    Name = "public_route_table"
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation: The public route table routes internet traffic from the public subnet through the Internet Gateway.

8. Private Route Table

resource "aws_route_table" "private" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.ngw.id
  }

  tags = {
    Name = "private_route_table"
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation: This route table directs internet-bound traffic from the private subnet to a NAT Gateway.

9. Route Table Associations

Public Subnet Association

resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}
Enter fullscreen mode Exit fullscreen mode

Private Subnet Association

resource "aws_route_table_association" "private" {
  subnet_id      = aws_subnet.private.id
  route_table_id = aws_route_table.private.id
}
Enter fullscreen mode Exit fullscreen mode

Explanation: These associations link the public and private subnets to their respective route tables.

10. Elastic IP for NAT Gateway

resource "aws_eip" "nat" {}
Enter fullscreen mode Exit fullscreen mode

Explanation: Allocates an Elastic IP address for the NAT Gateway.

11. NAT Gateway

resource "aws_nat_gateway" "ngw" {
  allocation_id = aws_eip.nat.id
  subnet_id     = aws_subnet.public.id

  tags = {
    Name = "main_nat_gateway"
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation: The NAT Gateway enables instances in the private subnet to access the internet without exposing them directly.

12. Security Group

resource "aws_security_group" "sg" {
  vpc_id = aws_vpc.main.id

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

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "main_security_group"
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation: This security group allows all outbound traffic and SSH access (port 22) for incoming connections.

13. Public EC2 Instance



resource "aws_instance" "public" {
  ami           = "ami-0182f373e66f89c85"
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.public.id
  security_groups = [aws_security_group.sg.id]

  tags = {
    Name = "public_instance"
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation: Creates a public EC2 instance that can be accessed over the internet.

14. Private EC2 Instance

resource "aws_instance" "private" {
  ami           = "ami-0182f373e66f89c85"
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.private.id
  security_groups = [aws_security_group.sg.id]

  tags = {
    Name = "private_instance"
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation: Defines a private EC2 instance, isolated from direct internet access.

Challenges Faced and Solutions

  • Challenge 1: Terraform Version Conflicts

    • Users may face version conflicts between Terraform and AWS provider versions. It’s important to specify compatible versions in the Terraform configuration.
  • Challenge 2: EC2 Instance Access

    • Connecting to EC2 instances in the private subnet can be tricky. You can use a bastion host or a VPN to securely access private instances.
  • Challenge 3: NAT Gateway Costs

    • NAT gateways can incur significant costs, especially in long-running environments. To mitigate this, ensure that resources are only deployed when needed, or consider alternative solutions like NAT instances for smaller use cases.

Output

Output

Conclusion

This project demonstrates the power of Terraform for provisioning and managing AWS resources in a scalable, automated manner. By automating the deployment of a VPC, EC2 instances, and associated networking components, you can achieve a highly secure, scalable, and manageable infrastructure in the cloud.

Feel free to check out the full source code in my GitHub repository.

Additional Resources

My GitHub Repository

Asif Khan — Aspiring Cloud Architect | Weekly Cloud Learning Chronicler

LinkedIn/Twitter/GitHub

Top comments (0)