Creating AWS Infrastructure with Terraform

BalajiBalaji
4 min read

Creating AWS Infrastructure with Terraform - One VPC 2 Private Subnets and 1 Public Subnet

Title: Building AWS Infrastructure with Terraform: A Step-by-Step Guide to Creating Two Private Subnets and One Public Subnet

Introduction:

In today's cloud-centric world, infrastructure as code (IaC) tools like Terraform have become essential for automating and managing cloud resources. In this blog post, we will walk through the process of setting up a simple AWS infrastructure using Terraform. Specifically, we will create a Virtual Private Cloud (VPC) with two private subnets and one public subnet. This setup is fundamental for many applications and services that require segregated network environments for security and performance reasons.

Prerequisites:

Before we dive in, make sure you have the following:

  • An AWS account

  • Terraform installed on your local machine

  • AWS CLI configured with your credentials

Step 1: Define Variables

First, let's define the variables we will use in our Terraform configuration. These variables will make our script more flexible and reusable.

  variable "aws_region" {
  description = "The AWS region to deploy the infrastructure"
  default     = "us-west-1"
}

variable "vpc_cidr" {
  description = "The CIDR block for the VPC"
  default     = "11.0.0.0/16"
}

variable "public_subnet_cidr" {
  description = "The CIDR block for the public subnet"
  default     = "11.0.1.0/24"
}

variable "private_subnet_1_cidr" {
  description = "The CIDR block for the first private subnet"
  default     = "11.0.2.0/24"
}

variable "private_subnet_2_cidr" {
  description = "The CIDR block for the second private subnet"
  default     = "11.0.3.0/24"
}

variable "availability_zone_1" {
  description = "The first availability zone to deploy the subnets"
  default     = "us-west-1b"
}

variable "availability_zone_2" {
  description = "The second availability zone to deploy the subnets"
  default     = "us-west-1b"
}

variable "availability_zone_3" {
  description = "The third availability zone to deploy the subnets"
  default     = "us-west-1c"
}

Step 2: Create the Main Terraform Configuration

Next, we create the main Terraform configuration file, main.tf. This file will define our VPC, subnets, Internet Gateway, and NAT Gateway.

  provider "aws" {
  region = var.aws_region
}

resource "aws_vpc" "main" {
  cidr_block = var.vpc_cidr
  tags = {
    Name = "assignment-vpc"
  }
}

resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = var.public_subnet_cidr
  map_public_ip_on_launch = true
  availability_zone       = var.availability_zone_1
  tags = {
    Name = "public-subnet"
  }
}

resource "aws_subnet" "private_1" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.private_subnet_1_cidr
  availability_zone = var.availability_zone_2
  tags = {
    Name = "private-subnet-1"
  }
}

resource "aws_subnet" "private_2" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.private_subnet_2_cidr
  availability_zone = var.availability_zone_3
  tags = {
    Name = "private-subnet-2"
  }
}

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "assignment-igw"
  }
}

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }
  tags = {
    Name = "public-route-table"
  }
}

resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

resource "aws_eip" "nat" {
  vpc = true
  tags = {
    Name = "assignment-nat-eip"
  }
}

resource "aws_nat_gateway" "main" {
  allocation_id = aws_eip.nat.id
  subnet_id     = aws_subnet.public.id
  tags = {
    Name = "assignment-nat-gateway"
  }
}

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.main.id
  }
  tags = {
    Name = "private-route-table"
  }
}

resource "aws_route_table_association" "private_1" {
  subnet_id      = aws_subnet.private_1.id
  route_table_id = aws_route_table.private.id
}

resource "aws_route_table_association" "private_2" {
  subnet_id      = aws_subnet.private_2.id
  route_table_id = aws_route_table.private.id
}

Step 3: Define Outputs

We also define outputs to easily retrieve the IDs of our created resources. This is useful for referencing these resources in other parts of our Terraform configuration or in other Terraform scripts.

  output "vpc_id" {
  description = "The ID of the VPC"
  value       = aws_vpc.main.id
}

output "public_subnet_id" {
  description = "The ID of the public subnet"
  value       = aws_subnet.public.id
}

output "private_subnet_1_id" {
  description = "The ID of the first private subnet"
  value       = aws_subnet.private_1.id
}

output "private_subnet_2_id" {
  description = "The ID of the second private subnet"
  value       = aws_subnet.private_2.id
}

output "internet_gateway_id" {
  description = "The ID of the Internet Gateway"
  value       = aws_internet_gateway.main.id
}

output "nat_gateway_id" {
  description = "The ID of the NAT Gateway"
  value       = aws_nat_gateway.main.id
}

Step 4: Define Terraform Variables

Finally, we provide the values for our variables in a terraform.tfvars file. This file is ignored by version control systems like Git to keep sensitive information secure.

Note: In (us-west-1a) region currently we can't able to deploy Ec2 instances

codeaws_region = "us-west-1"
vpc_cidr = "11.0.0.0/16"
public_subnet_cidr = "11.0.1.0/24"
private_subnet_1_cidr = "11.0.2.0/24"
private_subnet_2_cidr = "11.0.3.0/24"
availability_zone_1 = "us-west-1b"
availability_zone_2 = "us-west-1b"
availability_zone_3 = "us-west-1c"

Conclusion:

That's it! You now have a basic AWS infrastructure setup with Terraform that includes one public subnet and two private subnets. This setup can serve as a foundation for more complex infrastructure and applications. Terraform's declarative nature makes it easy to manage and scale your infrastructure, ensuring consistency and reliability.

1
Subscribe to my newsletter

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

Written by

Balaji
Balaji

👋 Hi there! I'm Balaji S, a passionate technologist with a focus on AWS, Linux, DevOps, and Kubernetes. 💼 As an experienced DevOps engineer, I specialize in designing, implementing, and optimizing cloud infrastructure on AWS. I have a deep understanding of various AWS services like EC2, S3, RDS, Lambda, and more, and I leverage my expertise to architect scalable and secure solutions. 🐧 With a strong background in Linux systems administration, I'm well-versed in managing and troubleshooting Linux-based environments. I enjoy working with open-source technologies and have a knack for maximizing performance and stability in Linux systems. ⚙️ DevOps is my passion, and I thrive in bridging the gap between development and operations teams. I automate processes, streamline CI/CD pipelines, and implement robust monitoring and logging solutions to ensure continuous delivery and high availability of applications. ☸️ Kubernetes is a key part of my toolkit, and I have hands-on experience in deploying and managing containerized applications in Kubernetes clusters. I'm skilled in creating Helm charts, optimizing resource utilization, and implementing effective scaling strategies for microservices architectures. 📝 On Hashnode, I share my insights, best practices, and tutorials on topics related to AWS, Linux, DevOps, and Kubernetes. Join me on my journey as we explore the latest trends and advancements in cloud-native technologies. ✨ Let's connect and dive into the world of AWS, Linux, DevOps, and Kubernetes together!