To Build Reusable Terraform Modules to Launch EC2 Instances on AWS
Introduction:
Terraform project in which I developed reusable modules to start AWS EC2 instances. This is a great place to start whether you’re new to Terraform or want to clean up your infrastructure code.
What Are Terraform Modules?
Think of a module as a reusable block of Terraform code. Instead of repeating the same code whenever you want to launch a resource (like an EC2 instance), you can wrap it in a modules and reuse it across multiple environments or projects.
Project Overview:
To use modular Terraform code to build two EC2 instances, each with a basic Apache web server configuration and a separate security group. The aim is to learn how to use Terraform modules efficiently for clean code management and reusability.
Prerequisites:
- Basic knowledge of AWS and EC2
 - Terraform installed on your machine
 - An AWS account with a valid access key and secret key configured (via 
aws configure) - A public SSH key (for EC2 key pair)
 - Familiarity with basic command line usage
 
ALSO READ:
Automating the Deployment of a Secure AWS VPC with Public and Private EC2 Instances Using Terraform
Effortless AWS EC2 Deployment with Terraform: Automate Your Infrastructure Today!
Effortlessly Set Up AWS VPC & Launch an EC2 Instance – A Step-by-Step Guide
Click here to: GitHub
Project Flow Chart

provider.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.91.0"
    }
  }
}
provider "aws" {
  region = "us-east-1"
}Root Module–terraform-module.tf
module "module-01" {
  source = "./module-1"
}
module "module-02" {
  source = "./module-2"
}
resource "aws_key_pair" "key" {
  key_name   = "aws_key"
  public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOSzpwBPR5xcFZrdXW6RE2CdSbKP6xDnUQcQVp1o9MsL USER@DESKTOP-4N177QU"
}Root Module-output.tf
output "aws_module1_public_ip" {
  value = module.module-01.public_ip
}
output "aws_module2_public_ip" {
  value = module.module-02.public_ip
}Module 1 – Launching EC2 with Apache Web Server
Inside module-1/ec2-module01.tf:
resource "aws_instance" "ec2_module-1" {
  ami           = var.ami_id
  instance_type = var.instance_type
  key_name      = "aws_key"
  vpc_security_group_ids = [aws_security_group.aws_module1.id]
  user_data = <<-EOF
    #!/bin/bash
    sudo yum update -y
    sudo yum install -y httpd
    sudo systemctl start httpd
    sudo systemctl enable httpd
    INSTANCE_ID=$(curl http://169.254.169.254/latest/meta-data/instance-id)
    echo "<html><body><h1>Hello this is module-1 at instance id $INSTANCE_ID </h1></body></html>" > /var/www/html/index.html
  EOF
  tags = {
    Name = "ec2_module-1-tags"
  }
}Module 1—Security Group for AWS Module 01
Inside module-1/ec2-module01.tf:
resource "aws_security_group" "aws_module2" {
    name = "Allow_all_module2"
    description = "allow every one"
  ingress {
    from_port   = 80
    protocol    = "TCP"
    to_port     = 80
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port   = 22
    protocol    = "TCP"
    to_port     = 22
    cidr_blocks = ["0.0.0.0/0"]
  }
  egress {
    from_port   = 0
    protocol    = "-1"
    to_port     = 0
    cidr_blocks = ["0.0.0.0/0"]
  }
    tags = {
      Name = "Allow_all_tag-module-2"
    }
}Module 1—variables.tf
variable "ami_id" {
    default = "ami-07a6f770277670015"
}
variable "instance_type" {
    default = "t2.micro"  
}
Module 1—output.tf
output "public_ip" {
  value = aws_instance.ec2_module-1.public_ip
}Same for Module 2!
module-2/ has almost the same setup but serves a different message:
“Hello, this is module-2…”
How to Run It
In the root directory (module_terraform/):
terraform init
terraform fmt
terraform validate
terraform plan
terraform apply 
terraform destroy   # To clean allYou can get the public IPs in the output. Now you can connect the server via putty
Output Screenshots:
terraform validate

terraform plan

terraform apply

terraform destroy

Thank You