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—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 all
You 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