🚀 Deploying AWS Infrastructure with Terraform


In today’s fast-paced DevOps world, Infrastructure as Code (IaC) is essential. In this project, I built a fully automated AWS infrastructure using Terraform—defining everything declaratively, applying it in a repeatable manner, and managing it in version control. Whether you're a cloud beginner or looking for a practical IaC example, this walkthrough is for you.
Project Overview
Repository: terraform-aws-infra
(GitHub)
Goal: Use Terraform to create and manage AWS infrastructure in a structured, modular, and reusable way, with a focus on maintainability and best practices.
Why Terraform on AWS
Terraform allows you to define your cloud infrastructure as code—making it readable, testable, and sharable. Compared to manually clicking through AWS Console, Terraform ensures repeatability, reviewability, and consistency.
It’s ideal for personal projects and scales well to enterprise-level environments. As your infrastructure grows, Terraform’s idiomatic HCL syntax (HashiCorp Configuration Language) and module system make maintenance easier.
Project Structure
terraform-aws-infra/
├── main.tf # Core Terraform config
├── variables.tf # Input variables
├── providers.tf # AWS region n version
├── username.sh # Apache + HTML provisioning script
├── username1.sh # Similar provisioning script
🔹 The Terraform Code
main.tf provisions:
VPC, Subnets, Security Group
EC2 instance with user-data style script
S3 bucket
variables.tf allows easy customization
providers.tf allows to provide the region, version, etc
🔹 The Automation Script (username.sh)
Here’s the heart of the automation:
#!/bin/bash
apt update
apt install -y apache2
# Get the instance ID using metadata
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
# Install AWS CLI
apt install -y awscli
# Optional: Download from S3
#aws s3 cp s3://myterraformprojectbucket2023/project.webp /var/www/html/project.png --acl public-read
# Create custom portfolio HTML
cat <<EOF > /var/www/html/index.html
<!DOCTYPE html>
<html>
<head>
<title>My Portfolio</title>
<style>
@keyframes colorChange {
0% { color: red; }
50% { color: green; }
100% { color: blue; }
}
h1 { animation: colorChange 2s infinite; }
</style>
</head>
<body>
<h1>Terraform Project Server 1</h1>
<h2>Instance ID: <span style="color:green">$INSTANCE_ID</span></h2>
<p>Welcome to Harshal Vernekar's GitHub again</p>
</body>
</html>
EOF
systemctl start apache2
systemctl enable apache2
👉 username1.sh
is a similar variant, also provisioning Apache with small tweaks.
🔹 Why Add These Scripts?
I could have relied only on Terraform’s user_data
, but writing a dedicated bash script gives me:
Reusability → script can be tested standalone
Clarity → easier to debug than embedding inside
.tf
filesFlexibility → can be extended to more provisioning tasks later
This showcases IaC + automation together, which is exactly what DevOps practices recommend.
🔹 Why Terraform + Scripts Instead of EKS?
Some may ask — why not use EKS (Elastic Kubernetes Service)?
Here’s why I chose this approach:
Simplicity: EKS is powerful but overkill for a small portfolio project. It adds complexity with control planes, node groups, and costs.
Cost: EKS incurs extra charges (control plane ~$74/month). This project is cost-free using free-tier EC2 and S3.
Focus: My goal was to demonstrate Terraform infra automation + server provisioning, not container orchestration.
When I scale into microservices or containerized apps → EKS will be my next step. But for now, this project keeps things lightweight, cost-efficient, and beginner-friendly.
🔹 Project Demo
Clone the repo:
git clone https://github.com/Harshalv21/terraform-aws-infra.git cd terraform-aws-infra
Initialize Terraform:
terraform init
Apply the configuration:
terraform apply -auto-approve
Get the public IP from Terraform output and open in browser:
http://<public-ip>
🎉 You’ll see your custom Apache-powered portfolio page.
After everything is done, If you want to delete:
terraform destroy -auto-approve
Conclusion
This project taught me that Terraform isn’t just about creating resources — it’s about making them production-ready with automation. By mixing IaC with scripting, I got a taste of real-world DevOps workflows.
Github repo:- https://github.com/Harshalv21/terraform-aws-infra.git
Subscribe to my newsletter
Read articles from HARSHAL VERNEKAR directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

HARSHAL VERNEKAR
HARSHAL VERNEKAR
🚀 Aspiring DevOps & Cloud Engineer with a strong foundation in cloud platforms (AWS), infrastructure automation, and container orchestration tools like Docker and Kubernetes. I’m passionate about building reliable, scalable, and secure cloud-native applications. 🔧 Currently building real-world projects using Terraform, Ansible, Jenkins, GitHub Actions, and EKS to understand how modern infrastructure is deployed, managed, and monitored. I enjoy breaking things (safely), debugging, and learning from hands-on experience. 📦 Comfortable working with: AWS (EC2, S3, IAM, VPC, EKS) Docker, Kubernetes (Minikube & EKS) CI/CD tools like Jenkins & GitHub Actions IaC tools like Terraform & Ansible Monitoring with Prometheus & Grafana Linux, Bash, Git, and Networking fundamentals 💡 Always learning — currently exploring deeper concepts in Kubernetes workloads, Helm, and scaling best practices. 🔍 Open to DevOps, Cloud, or SRE roles where I can grow, contribute, and solve real-world problems.