Terraform project with AWS to build infra within seconds! (Web Ec2 with eIP)

1. Introduction:

  • What is Terraform?

Terraform is an open-source Infrastructure as Code (IaC) tool created by HashiCorp. It lets you define, provision, and manage cloud infrastructure using declarative configuration files. Instead of manually creating AWS resources in the console, you write code that describes what you want, and Terraform takes care of creating or updating it.
  • Why use it with AWS?

a) Infrastructure as Code (IaC)
  • You can define AWS resources (EC2, VPC, S3, IAM, etc.) in .tf files.
  • These configurations can be version-controlled in Git.
b) Multi-Cloud Support
  • Although AWS has its own tool (CloudFormation), Terraform works with AWS + Azure + GCP + on-prem at the same time.
c) Reusability & Automation
  • You can reuse Terraform modules to deploy the same AWS setup in different environments (dev, test, prod).
d) State Management
  • Terraform keeps a state file to know which resources it manages.
  • Makes it easy to track and update changes in AWS without accidentally deleting something important.
e) Plan Before Apply
  • terraform plan shows what changes will happen before you apply them—reducing mistakes.
f) Easier Collaboration
  • Multiple team members can work on the same infrastructure code.
  • Remote state (e.g., in S3) keeps everyone in sync.

  • What you will achieve by the end of this tutorial:

    • Create a complete VPC environment from scratch

    • Deploy an EC2 instance with Apache web server running

2. Prerequisites

Before starting, make sure you have:

  • AWS Account (Free Tier works fine)

  • IAM User with programmatic access (Access Key + Secret Key)

    • Attach AdministratorAccess (or limited VPC + EC2 permissions)

  • Visual Studio Code installed

  • Terraform CLI installed

  • VS Code Extensions:

    • HashiCorp Terraform

    • AWS Toolkit

  • Basic knowledge of AWS networking concepts (VPC, Subnet, Route Table, IGW, SG)

3. Project Structure

Create a folder (e.g., terraform-aws-vpc) and inside, have:

main.tf # Terraform configuration variables.tf # (Optional) Variables file outputs.tf # (Optional) Outputs file

You can use visualcode to use this code

Prerequisites:

  • Have a AWS account
  • Create IAM user with secret and access key to use within code
  • Visual Studio Code with HarshiCorp Terraform installed and AWS extensions

Note:

# Initialize the project

terraform init

# Preview the execution plan

terraform plan

# Apply the configuration

terraform apply

# Destroy the infrastructure

terraform destroy

====================================================================
Project Architecture:






Project file (.tf):

provider "aws" {

  region     = "eu-north-1"

  access_key = ""

  secret_key = ""

}


# 1. Create VPC

resource "aws_vpc" "my_vpc" {

  cidr_block = "10.0.0.0/16"

  tags = {

    Name = "my_vpc"

  }

}


# 2. Create Internet Gateway

resource "aws_internet_gateway" "my_igw" {

  vpc_id = aws_vpc.my_vpc.id

  tags = {

    Name = "my_igw"

  }

}


# 3. Create Custom Route Table

resource "aws_route_table" "my_rt" {

  vpc_id = aws_vpc.my_vpc.id


  route {

    cidr_block = "0.0.0.0/0"

    gateway_id = aws_internet_gateway.my_igw.id

  }


  tags = {

    Name = "my_rt"

  }

}


# 4. Create a Subnet

resource "aws_subnet" "my_subnet" {

  vpc_id            = aws_vpc.my_vpc.id

  cidr_block        = "10.0.1.0/24"

  availability_zone = "eu-north-1a"

  map_public_ip_on_launch = true


  tags = {

    Name = "my_subnet"

  }

}


# 5. Associate Subnet with Route Table

resource "aws_route_table_association" "my_assoc" {

  subnet_id      = aws_subnet.my_subnet.id

  route_table_id = aws_route_table.my_rt.id

}


# 6. Create Security Group

resource "aws_security_group" "my_sg" {

  name        = "web_sg"

  description = "Allow ports 22, 80, 443"

  vpc_id      = aws_vpc.my_vpc.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"]

  }


  ingress {

    from_port   = 443

    to_port     = 443

    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"]

  }


  tags = {

    Name = "web_sg"

  }

}


# 7. Create Network Interface

resource "aws_network_interface" "my_eni" {

  subnet_id       = aws_subnet.my_subnet.id

  private_ips     = ["10.0.1.10"]

  security_groups = [aws_security_group.my_sg.id]

  tags = {

    Name = "my_eni"

  }

}


# 8. Assign Elastic IP to ENI

resource "aws_eip" "my_eip" {

  network_interface = aws_network_interface.my_eni.id

  associate_with_private_ip = "10.0.1.10"

}


# 9. Create Ubuntu Server and install/enable apache2

resource "aws_instance" "my_instance" {

  ami           = "ami-042b4708b1d05f512" # Ubuntu 22.04 LTS in us-east-1 

  instance_type = "t3.micro"

  network_interface {

    network_interface_id = aws_network_interface.my_eni.id

    device_index         = 0

  }

  key_name = "my-key-ec2"  # Replace with your EC2 key pair name


  user_data = <<-EOF

              #!/bin/bash

              apt-get update -y

              apt-get install -y apache2

              systemctl enable apache2

              systemctl start apache2

              echo "Welcome to my server" > /var/www/html/index.html

              EOF


  tags = {

    Name = "Ubuntu-Apache"

  }

}

================================================================

6. Points to Remember

  • Never commit AWS credentials to GitHub. Use ~/.aws/credentials or environment variables.

  • Make sure Key Pair exists before running terraform apply.

  • Always check region and AMI ID (they are region-specific).

  • Clean up resources after testing (terraform destroy) to avoid charges.

  • Security groups here allow open access (0.0.0.0/0) — for production, restrict to known IPs.

  • Elastic IPs cost money if not attached to a running instance.



=======================================================================

Thank you, check out more blogs for such information..!
For any queries,feel free to reach out me on shubhammore07007@gmail.com

Comments

Popular posts from this blog

AWS: Serverless REST API (API Gateway + Lambda + DynamoDb + WAF)

Nginx : Setting Up Nginx with Load Balancing