This project demonstrates how I automated the setup of a complete AWS infrastructure using Terraform. The goal was to learn Infrastructure as Code (IaC) concepts and understand how Terraform can provision AWS resources automatically.
The architecture I built includes the following components:
- VPC — Custom Virtual Private Cloud for isolating the network.
- Subnets — Two public subnets across different availability zones for high availability.
- Internet Gateway (IGW) — To allow instances to communicate with the internet.
- Route Table — Configured to route external traffic through the internet gateway.
- Security Group — Allows inbound HTTP (port 80) and HTTPS (port 443) traffic.
- EC2 Instances — Two web servers launched in the public subnets with Apache installed using user data scripts.
- S3 Bucket — Created to store and retrieve static content (like images or project files).
- Application Load Balancer (ALB) — Distributes traffic between the two web servers.
- Terraform (IaC tool)
- AWS (EC2, S3, VPC, ALB)
- VS Code (for editing
.tffiles) - AWS CLI (for basic verification)
- Created a VPC and Subnets – Defined CIDR blocks for the VPC and public subnets.
- Attached an Internet Gateway – To enable internet access for the public subnets.
- Added a Route Table – Connected subnets with IGW for outbound access.
- Created a Security Group – Opened HTTP (80) and HTTPS (443) ports.
- Provisioned EC2 Instances – Used Ubuntu AMI and attached user data to automatically install and start Apache.
- Created an S3 Bucket – For storing static assets (like images used in my web page).
- Set Up an Application Load Balancer – To route traffic across both EC2 instances.
- Tested Everything – Accessed the ALB DNS name to see my custom HTML page showing the Instance ID and Server name.
Each EC2 instance uses a userdata.sh script that:
- Updates the system
- Installs Apache and AWS CLI
- Fetches instance metadata using IMDSv2
- Generates a simple animated HTML portfolio page with the instance ID displayed
- Variables for CIDR blocks and region
- Outputs to display public IPs and DNS names
- Provisioners (user data scripts)
- State management with Terraform CLI
- Plan & Apply workflow for safe deployments
terraform init
terraform validate
terraform plan
terraform apply
terraform destroyBelow is the architecture of my setup:
This diagram shows:
- One VPC
- Two public subnets
- Two EC2 instances
- One ALB
- One S3 bucket
- Understood how Terraform state tracks resource changes.
- Learned about IMDSv2 (for EC2 metadata security).
- Got hands-on with networking concepts like VPCs, subnets, and route tables.
- Practiced automating infrastructure instead of using the AWS console manually.
Inspired by Abhishek Veeramalla’s YouTube Tutorial I customized and built my own version of the project.

