7. Multi Resources Deployment in Single Region (Terraform Hands On Project)

Introduction:

In this project, we demonstrate how to use Terraform to provision a simple yet robust AWS infrastructure. This infrastructure includes a Virtual Private Cloud (VPC), public subnets, an internet gateway, a route table, a security group, and an EC2 instance. This setup is designed to ensure that our application is publicly accessible and secure.

Objective:

The main objective of this project is to deploy an EC2 instance within a custom VPC, allowing public access via an Internet Gateway. This will provide a foundational infrastructure on AWS that can be expanded upon for more complex deployments.

Resources

VPC: To create a logically isolated network.

Subnets: To partition the VPC into smaller sub-networks. Internet Gateway: To allow internet access to our VPC.

Route Table: To define routes for network traffic. Security Group: To control inbound and outbound traffic to our instances.

EC2 Instance: To host our application.

Architecture

The architecture includes a VPC with two public subnets, each in a different availability zone for high availability. An Internet Gateway is attached to the VPC to allow internet access. The route table is associated with both subnets, enabling communication between the subnets and the internet. A security group is configured to allow HTTP traffic on port 80. Finally, an EC2 instance is launched in one of the public subnets, secured by the security group.

VPC: A virtual network that isolates resources within AWS.

Subnets: Two public subnets across different availability zones to enhance availability.

Internet Gateway: Enables internet connectivity for resources within the VPC.

Route Table: Routes internet traffic from the subnets through the Internet Gateway.

Security Group: Restricts access to the EC2 instance, allowing only HTTP traffic.

EC2 Instance: A virtual server running within one of the public subnets.

Main Configuration (main.tf)

Terraform script creates an AWS VPC with associated subnets, internet gateway, and route table. It configures a security group to allow HTTP traffic. Finally, it launches an EC2 instance within the VPC, making it accessible from the internet.

provider "aws" {
  region = "us-east-1"
}

# Define VPC
resource "aws_vpc" "main_vpc" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true
  tags = {
    Name = "main-vpc"
  }
}

# Create Internet Gateway
resource "aws_internet_gateway" "main_igw" {
  vpc_id = aws_vpc.main_vpc.id
}

# Create Route Table
resource "aws_route_table" "main_route_table" {
  vpc_id = aws_vpc.main_vpc.id

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

# Create Public Subnets
resource "aws_subnet" "public_subnet_1" {
  vpc_id                  = aws_vpc.main_vpc.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "us-east-1a"
  map_public_ip_on_launch = true
  tags = {
    Name = "public-subnet-1"
  }
}

resource "aws_subnet" "public_subnet_2" {
  vpc_id                  = aws_vpc.main_vpc.id
  cidr_block              = "10.0.2.0/24"
  availability_zone       = "us-east-1b"
  map_public_ip_on_launch = true
  tags = {
    Name = "public-subnet-2"
  }
}

# Associate Route Table with Subnets
resource "aws_route_table_association" "public_subnet_1_association" {
  subnet_id      = aws_subnet.public_subnet_1.id
  route_table_id = aws_route_table.main_route_table.id
}

resource "aws_route_table_association" "public_subnet_2_association" {
  subnet_id      = aws_subnet.public_subnet_2.id
  route_table_id = aws_route_table.main_route_table.id
}

# Create Security Group
resource "aws_security_group" "app_sg" {
  vpc_id = aws_vpc.main_vpc.id

  ingress {
    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 = "app-sg"
  }
}

# Launch EC2 Instance
resource "aws_instance" "app_instance" {
  ami           = "ami-01fccab91b456acc2"  # Replace with a valid AMI ID for your region
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.public_subnet_1.id
  vpc_security_group_ids = [aws_security_group.app_sg.id]

  tags = {
    Name = "app-instance"
  }
}

# Create DB Subnet Group
resource "aws_db_subnet_group" "db_subnet_group" {
  name       = "my-db-subnet-group_unique"
  subnet_ids = [aws_subnet.public_subnet_1.id, aws_subnet.public_subnet_2.id]

  tags = {
    Name = "my-db-subnet-group_unique"
  }
}

# Create RDS DB Instance
resource "aws_db_instance" "db_instance" {
  allocated_storage    = 20
  storage_type         = "gp2"
  engine               = "mysql"
  engine_version       = "5.7.44"
  instance_class       = "db.t3.micro"
  db_name                 = "mydb"
  username             = "admin"
  password             = "password"
  db_subnet_group_name = aws_db_subnet_group.db_subnet_group.name
  publicly_accessible  = true
  vpc_security_group_ids = [aws_security_group.app_sg.id]

  tags = {
    Name = "my-db-instance"
  }
}

output "vpc_id" {
  value = aws_vpc.main_vpc.id
}

output "subnet_ids" {
  value = [aws_subnet.public_subnet_1.id, aws_subnet.public_subnet_2.id]
}

output "instance_id" {
  value = aws_instance.app_instance.id
}

output "db_instance_id" {
  value = aws_db_instance.db_instance.id
}

Steps to Apply the Terraform Configuration Initialize Terraform.

Open your terminal and run the following command to initialize Terraform:

terraform init

Plan the Changes:

terraform plan

Apply the Changes:

terraform apply

Confirm with yes when prompted.

AWS Console Verification of Infrastructure Created:

VPC: Go to the VPC dashboard to verify the creation of the VPC and subnets.

Internet Gateway: Check the Internet Gateway section to confirm it is attached to the VPC.

Route Table: Verify that the route table has the correct routes and associations.

Security Group: Confirm the security group rules allow HTTP traffic.

EC2 Instance: Check the EC2 dashboard to ensure the instance is running and associated with the public subnet and security group. Access the EC2 Instance. Obtain the public IP address of the EC2 instance from the AWS console. Open a web browser and enter the public IP address to verify the application is accessible.

The custom VPC and associated subnets as seen in the AWS VPC dashboard."

Internet Gateway: "Internet Gateway attached to the VPC, enabling internet access."

Route Table: "Route table with routes allowing internet traffic through the Internet Gateway."

Security Group: "Security group configured to allow inbound HTTP traffic on port 80."

EC2 Instance: "EC2 instance running in the public subnet, accessible via its public IP address."

Conclusion

This project provides a foundational AWS infrastructure using Terraform, demonstrating how to provision a VPC, subnets, internet gateway, route table, security group, and EC2 instance. This setup can be expanded and customized to suit more complex deployment scenarios, offering a robust starting point for deploying scalable and secure applications on AWS.