Building AWS Infrastructure Using Infrastructure as Code (IaC)

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.

In this project we creating a Virtual Private Cloud (VPC) along with private and public subnets. Additionally, I will set up an Internet Gateway (IGW) to enable communication between the VPC and the internet. To host a website, I will launch an EC2 instance in the public subnet with specific configurations. By leveraging the power of automation and Infrastructure as Code, I aim to ensure a consistent and reliable environment for our application.

Task Overview:

  1. Create a VPC (Virtual Private Cloud) with CIDR block 10.0.0.0/16: Establishing a private network environment that encapsulates our resources and provides secure communication between them.

  2. Create a private subnet with CIDR block 10.0.1.0/24 in the above VPC: This subnet will host resources that require limited external access and enhance security.

  3. Create a public subnet with CIDR block 10.0.2.0/24 in the above VPC: The public subnet will accommodate resources that need direct communication with the internet.

  4. Create an Internet Gateway (IGW) and attach it to the VPC: Enabling internet connectivity for resources within the VPC and allowing them to access the internet.

  5. Create a route table for the public subnet and associate it with the public subnet: Configuring a route table to manage the traffic flow within the public subnet, enabling connectivity to the internet via the Internet Gateway.

  6. Launch an EC2 instance in the public subnet: Creating an EC2 instance with specific details, such as the AMI, instance type, security group settings, and user data.

  7. AMI: ami-0557a15b87f6559cf, Instance type: t2.micro, Security group: Allow SSH access from anywhere: Configuring the EC2 instance with these specifications to ensure proper functionality and secure access.

  8. User data: Use a shell script to install Apache and host a simple website: Automating the installation of Apache and the hosting of a basic website on the EC2 instance using user data.

  9. Create an Elastic IP and associate it with the EC2 instance: Assigning a static public IP address to the EC2 instance to facilitate reliable communication.

  10. Open the website URL in a browser to verify that the website is hosted successfully: After completing the deployment, validating the successful hosting of the website by accessing the URL in a web browser.

Step 1: Create a VPC (Virtual Private Cloud)

Create a VPC (Virtual Private Cloud) with CIDR block 10.0.0.0/16

Below are the prerequisites for building any aws infrastructure is to define providers.

terraform {
    required_providers {
      aws = {
        source  = "hashicorp/aws"
        version = "~> 4.0"
      }
    }
  }

Add a provider.tf and add details about AWS Region that you are using

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

Create a vpc.tf file and mention the required CIDR block with the name tag of VPC.

 resource "aws_vpc" "nahid_vpc" {
    cidr_block       = "10.0.0.0/16"
    tags = {
      Name = "nahid_vpc"
    }
  }

Run the terraform init command to initialize the working directory and download the required providers.

terraform init

After that, run terraform apply to create the VPC in your AWS account.

We can check in the AWS console for the new VPC created with name as "main".

Step 2: Create a private subnet

Now create a private subnet named as subnet.tf with CIDR block 10.0.1.0/24 in the VPC with ID aws_vpc.main.id and tags it with the name "private_subnet", you can take reference of vpc resource that has been created before.

resource "aws_subnet" "private_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
tags = {
Name = "private subnet"
}
}

Run terraform apply to create a private subnet in your AWS account.

A private Subnet is successfully created using Terraform, you can verify this in the VPC Tab of the Subnet console.

Step 3: Create a public subnet

Same as the public subnet, creates a private subnet with CIDR block 10.0.2.0/24 in the VPC with ID aws_vpc.main.id, and tags it with the name "private".

resource "aws_subnet" "public_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-east-1a"
tags = {
Name = "public subnet"
}
}

Run terraform apply to create a public subnet in your AWS account.

Go to VPC console then go to Subnets. Check Public Subnet is created successfully.

Step 4: Create an Internet Gateway (IGW) and attach it to the VPC.

Create an Internet Gateway (IGW) and attach it to the VPC.

Create a internetgateway.tf file and define the internet gateway with the required configurations to attach it to VPC

resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id

tags = {
Name = "internet-gateway"
}
}

Execute the terraform apply command for the creation of Internet Gateway.

Go to VPC then go to Internet gateways, and check whether a new Internet gateway is created with the name 'internet-getway'.

VPC is attached to the internet gateway.

Step 5: Create a Route Table

Now create a route table named routetable.tf for use with a public subnet specified by the subnet_id attribute.

resource "aws_route_table" "route_table" {
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_association" {
subnet_id = aws_subnet.public_subnet.id
route_table_id = aws_route_table.route_table.id
}

In Route tables, a new route table is successfully created using terraform apply command, Now route table routes with an internet gateway.

We can verify the route table in the AWS console along with the public subnet which is associated in the subnet association section.

Step 6: Create a Security Group

To connect our EC2 instance, create a securitygroup.tf file where use the 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).

resource "aws_security_group" "web_server" {
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"]
}
}

Step 7: Create an Elastic IP and associate it with the EC2 instance.

Create an Elastic IP and associate it with the EC2 instance.

resource "aws_eip" "ip" {
instance = aws_instance.server_terraform.id
vpc = true
tags = {
Name = "elastic-ip"
}
}

Task 8: Create user data to install Apache

The user_data attribute specifies the script to run when the instance is launched. This script updates the package manager, installs the Apache web server, creates a basic HTML file, and restarts Apache.

#!/bin/bash
sudo apt-get update -y
sudo apt-get install -y apache2
sudo systemctl start apache2
sudo systemctl enable apache2
echo "<!DOCTYPE html>
<html>
<head>
<title>Introduction</title>
<style>
body {
background-color: #d8e2dc;
font-family: Arial, sans-serif;
color: #3c415e;
text-align: center;
padding: 50px;
}
h1 {
font-size: 3em;
margin-bottom: 20px;
text-shadow: 0 2px 2px rgba(0,0,0,0.1);
}
p {
font-size: 1.5em;
line-height: 1.5;
margin-bottom: 30px;
}
</style>
</head>
<body>
<h1>This is Nahidul Islam.</h1>
<p>I am going to be a DevOps Pro!! InshaaAllah</p>
</body>
</html>" > /var/www/html/index.html
sudo systemctl restart apache2

Step 9: Launch an EC2 instance in the public subnet

Create a new ec2.tf file where add the details of our EC2 instance like AMI ID, instance type, key name, public subnet, security group and User Data to install Apache in our EC2 instance server.

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

Now combine all the configurations to spin up the EC2 instance.

resource "aws_security_group" "web_server" {
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" "server_terraform" {
ami = "ami-053b0d53c279acc90"
instance_type = "t2.micro"
key_name = "an-access-key"
subnet_id = aws_subnet.public_subnet.id
security_groups = [
aws_security_group.web_server.id
]

user_data = filebase64("userdata.sh")
tags = {
Name = "terraform_infra"
}
}
resource "aws_eip" "ip" {
instance = aws_instance.server_terraform.id
vpc = true
tags = {
Name = "elastic-ip"
}
}

Execute the terraform apply command

Now, we can see in the AWS console for the new EC2 instance which is created.

We can verify the security group along with the rules created.

We can verify the elastic IP which is created.

Using the Public IPv4 address, open the URL in a browser to verify that the website is hosted successfully.

Through the effective utilization of Infrastructure as Code and AWS resources, I have successfully built a secure and scalable AWS infrastructure. The creation of a VPC, private and public subnets, an Internet Gateway, and an EC2 instance with a hosted website demonstrates the power of automation and DevOps practices. By following best practices and leveraging AWS services, we have established a reliable environment for our application. This project lays the foundation for future enhancements and expansions while ensuring a consistent and repeatable deployment process

Thank you for reading this blog. If you found this blog helpful, please like, share, and follow me for more blog posts like this in the future.

— Happy Learning !!!

Let’s connect !!!

Linkedin

Medium

Github

Mail