Day 66 - Terraform Hands-on Project - Build Your Own AWS Infrastructure with Ease using Infrastructure as Code (Jan 31, 2024)

🙏 Introduction:
In this blog, In the previous tasks, you have learned about the basics of Terraform, its configuration file, and creating an EC2 instance using Terraform. Today, we will explore more about Terraform and create multiple resources.
🎯Task: 1
Create a VPC (Virtual Private Cloud) with CIDR block 10.0.0.0/16
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main"
}
}
- This will create a new VPC in your AWS account with the specified CIDR block and a name tag of main.

- Run the terraform init command to initialize the working directory and download the required providers. After that, run terraform apply to create the VPC in our AWS account

- VPC has been created successfully

Create a public subnet with CIDR block 10.0.1.0/24 in the above VPC
resource "aws_subnet" "public_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
tags = {
Name = "Public Subnet"
}
}

- Run the terraform init command to initialize the working directory and download the required providers. After that, run terraform apply to create the public subnet in our AWS account

- Public Subnet is created

Create a private subnet with CIDR block 10.0.2.0/24 in the above VPC
resource "aws_subnet" "private_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
tags = {
Name = "Private Subnet"
}
}

- Run the terraform init command to initialize the working directory and download the required providers. After that, run terraform apply to create the private subnet in our AWS account

- Private Subnet is created

Create an Internet Gateway (IGW) and attach it to the VPC
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "igw"
}
}

- Run the terraform init command to initialize the working directory and download the required providers. After that, run terraform apply to create the Internet Gateway in our AWS account

- Internet gateway is created

- Internet Gateway (IGW) is attach it to the VPC

Create a route table for the public subnet and associate it with the public subnet. This route table should have a route to the Internet Gateway
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
tags = {
Name = "route-table"
}
}
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public_subnet.id
route_table_id = aws_route_table.public.id
}
First we create a route table for public subnet.
aws_route_table block creates a new route table in the VPC specified by vpc_id attribute. It also defines a route that sends all traffic with destination CIDR 0.0.0.0/0 to the internet gateway specified by gateway_id attribute. The tags attribute sets a name for the route table for easy identification.
Then associate route table with public subnet.
aws_route_table_association block associates the newly created route table with a public subnet specified by the subnet_id attribute. The route_table_id attribute refers to the ID of the route table created in the previous block.

- Run the terraform init command to initialize the working directory and download the required providers. After that, run terraform apply to create the route table in our AWS account

- Route table is successfully created

- Route table is associate with public subnet

Launch an EC2 instance in the public subnet with the following details
AMI: ami-008fe2fc65df48dac
Instance type: t2.micro
Security group: Allow SSH access from anywhere
User data: Use a shell script to install Apache and host a simple website
Create an Elastic IP and associate it with the EC2 instance
resource "aws_instance" "web_server" {
ami = "ami-008fe2fc65df48dac"
instance_type = "t2.micro"
key_name = "terra_key"
subnet_id = aws_subnet.public_subnet.id
vpc_security_group_ids = [
aws_security_group.ssh_access.id
]
}
resource "aws_security_group" "ssh_access" {
name_prefix = "ssh_access"
vpc_id = aws_vpc.main.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
User data: Use a shell script to install Apache and host a simple website
user_data = <<-EOF
#!/bin/bash
sudo apt-get update -y
sudo apt-get install apache2 -y
sudo systemctl start apache2
sudo systemctl enable apache2
echo "<html><body><h1>Welcome to my website!</h1></body></html>" > /var/www/html/index.html
sudo systemctl restart apache2
EOF
Create an Elastic IP and associate it with the EC2 instance
resource "aws_eip" "eip" {
instance = aws_instance.web_server.id
tags = {
Name = "test-eip"
}
}
Final main.tf file
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-west-2"
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main"
}
}
resource "aws_subnet" "public_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
tags = {
Name = "Public Subnet"
}
}
resource "aws_subnet" "private_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
tags = {
Name = "Private Subnet"
}
}
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "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.gw.id
}
tags = {
Name = "route-table"
}
}
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public_subnet.id
route_table_id = aws_route_table.public.id
}
resource "aws_instance" "web_server" {
ami = "ami-008fe2fc65df48dac"
instance_type = "t2.micro"
key_name = "terra_key"
subnet_id = aws_subnet.public_subnet.id
vpc_security_group_ids = [
aws_security_group.ssh_access.id
]
user_data = <<-EOF
#!/bin/bash
sudo apt-get update -y
sudo apt-get install apache2 -y
sudo systemctl start apache2
sudo systemctl enable apache2
echo "<html><body><h1>Welcome to my website!</h1></body></html>" > /var/www/html/index.html
sudo systemctl restart apache2
EOF
tags = {
Name = "terraform-instance"
}
}
resource "aws_security_group" "ssh_access" {
name_prefix = "ssh_access"
vpc_id = aws_vpc.main.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_eip" "eip" {
instance = aws_instance.web_server.id
tags = {
Name = "test-eip"
}
}
- New instance is created with the desired details configuration

- Elastic IP created

Open the website URL in a browser to verify that the website is hosted successfully





