Terraform Hands-on Project :- Build Your Own AWS Infrastructure
This is Day 66 of #90daysofdevops challenge
Table of contents
- Task-01: Create a VPC (Virtual Private Cloud) with CIDR block 10.0.0.0/16
- Task-02: Create a public subnet with CIDR block 10.0.1.0/24 in the above VPC.
- Task-03: Create a private subnet with CIDR block 10.0.2.0/24 in the above VPC.
- Task-04: Create an Internet Gateway (IGW) and attach it to the VPC.
- Task-05: 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.
- Task-06: Launch an EC2 instance in the public subnet with the following details:
- Task-07: Security group: Allow SSH access from anywhere
- Task-08: User data: Use a shell script to install Apache and host a simple website
- Task-09: Create an Elastic IP and associate it with the EC2 instance.
- Task-10: Combine all the configurations to spin up the EC2 instance.
- Task-11: Open the website URL in a browser to verify that the website is hosted successfully.
Welcome back to your Terraform journey.
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-01: Create a VPC (Virtual Private Cloud) with CIDR block 10.0.0.0/16
- Add the following code to your Terraform configuration in main.tf file.
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main"
}
}
- Execute terraform init, plan, apply to build the VPC.
- Go to VPC console and check new VPC with name ‘main’ is successfully created.
Task-02: Create a public subnet with CIDR block 10.0.1.0/24 in the above VPC.
- Add the following code to your Terraform configuration in main.tf file
resource "aws_subnet" "public_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
tags = {
Name = "Public Subnet"
}
}
- This code creates a public subnet resource named “public_subnet”
- Execute terraform init, plan, apply to build.
- Go to subnet console and check new subnet with name ‘Public Subnet’ is successfully created.
Task-03: Create a private subnet with CIDR block 10.0.2.0/24 in the above VPC.
- Add the following code to your Terraform configuration in main.tf file
resource "aws_subnet" "private_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "ap-south-1a"
tags = {
Name = "Private Subnet"
}
}
- This code creates a public subnet resource named “private_subnet” with the specified CIDR block.
- Execute terraform init, plan, apply to build.
- Go to subnet console and check new subnet with name ‘Private Subnet’ is successfully created.
Task-04: Create an Internet Gateway (IGW) and attach it to the VPC.
- Add the following code to your Terraform configuration in main.tf file
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "igw"
}
}
- Execute terraform init, plan, apply to build.
- Go to Internet gateways console and check new subnet with name ‘My internet Gateway’ is successfully created.
Task-05: 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 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.
- Execute terraform init, plan, apply to build.
- We can verify the route table in AWS console along with the public subnet which is associated in the subnet association section.
Task-06: Launch an EC2 instance in the public subnet with the following details:
- AMI: ami-0557a15b87f6559cf
- Instance type: t2.micro
aws_instance block creates a new EC2 instance in the public subnet specified by subnet_id attribute. It uses the Amazon Machine Image (AMI) ID ami-0f8ca728008ff5af4, which is a Ubuntu 18.04 LTS image. The key_name attribute specifies the name of the key pair used to SSH into the instance. The vpc_security_group_ids attribute specifies a list of security groups to attach to the instance, in this case, it refers to the ID of the security group created in the next block.
resource “aws_instance” “web_server” {
ami = “ami-0f8ca728008ff5af4”
instance_type = “t2.micro”
subnet_id = aws_subnet.public_subnet.id
vpc_security_group_ids = [aws_security_group.ssh_access.id]
Task-07: Security group: Allow SSH access from anywhere
aws_security_group block creates a new security group that allows inbound traffic on ports 22 (SSH) and 80 (HTTP) from any source (0.0.0.0/0). The name_prefix attribute sets a name prefix for the security group, and the vpc_id attribute specifies the ID of the VPC where the security group will be created.
resource "aws_security_group" "ssh_access" {
name_prefix = "ssh_access"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
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"]
}
}
Task-08: User data: Use a shell script to install Apache and host a simple website
The user_data attribute specifies the script to run when the instance is launched. This script updates the package manager, installs Apache web server, creates a basic HTML file, and restarts Apache.
user_data = <<-EOF
#!/bin/bash
# Update the package list
sudo apt update
# Install Apache
sudo apt install -y apache2
sudo cat <<HTML > /var/www/html/index.html
<!DOCTYPE html>
<html><body><h1>Welcome to my website</h1></body></html>
HTML
sudo systemctl restart apache2
EOF
Task-09: Create an Elastic IP and associate it with the EC2 instance.
aws_eip block creates a new Elastic IP address and associates it with the instance created in the first block by specifying the instance ID in the instance attribute. The tags attribute sets a name for the Elastic IP for easy identification.
resource "aws_eip" "eip" {
instance = aws_instance.web_server.id
vpc = true
tags = {
Name = "elastic-ip"
}
Task-10: Combine all the configurations to spin up the EC2 instance.
Launch an EC2 instance in the public subnet with the following details:
AMI: ami-0557a15b87f6559cf
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_security_group" "ssh_access" {
name_prefix = "web-server-sg"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
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"]
}
}
resource "aws_instance" "web_server" {
ami = "ami-053b0d53c279acc90"
instance_type = "t2.micro"
subnet_id = aws_subnet.public_subnet.id
vpc_security_group_ids = [aws_security_group.ssh_access.id]
user_data = <<-EOF
#!/bin/bash
# Update the package list
sudo apt update
# Install Apache
sudo apt install -y apache2
sudo cat <<HTML > /var/www/html/index.html
<!DOCTYPE html>
<html><body><h1>Welcome to my website</h1></body></html>
HTML
sudo systemctl restart apache2
EOF
tags = {
Name = "terraform-instance"
}
}
resource "aws_eip" "ip" {
instance = aws_instance.web_server.id
vpc = true
tags = {
Name = "elastic-ip"
}
}
- Execute terraform init, plan, apply to build.
Task-11: Open the website URL in a browser to verify that the website is hosted successfully.
"Thank you for enjoying my DevOps blog! Your positive response fuels my passion to dive deeper into technology and innovation.
Stay tuned for more captivating DevOps articles, where we'll explore this dynamic field together. Follow me on Hashnode and connect on LinkedIn (https://www.linkedin.com/in/som-shanker-pandey/) for the latest updates and discussions.