Infrastructure as Code (IaC) has transformed the way developers and operations teams provision and manage infrastructure, enabling automation, repeatability, and scalability. Recently, I completed a significant project involving the migration of workloads from on-premises to the AWS cloud. Along the way, I learnt a ton and gained skills that I’m excited to share.
To document and reflect on these lessons, I’ve decided to launch a new series highlighting the key insights and skills acquired through these projects.
Project #01: Deploying an NGINX Server on AWS with Terraform
This is a simple project just to demonstrate how easy and convenient we can deploy an NGINX server on AWS using Terraform. It showcases how automation and repeatable processes can simplify infrastructure provisioning while ensuring consistency and reliability.
Project Steps
Here’s a breakdown of how the infrastructure was created:
1. Create the Network Infrastructure
- A VPC was set up with a CIDR block of
10.0.0.0/16
. - A public subnet within the VPC allowed instances to connect to the internet.
- An Internet Gateway was attached to the VPC for external connectivity.
- A route table was created and associated with the subnet to route traffic through the Internet Gateway.
2. Configure Security Groups
- A security group was defined to allow:
- Inbound traffic on port 80 (HTTP).
- Inbound traffic on port 443 (HTTPS).
- Outbound traffic was unrestricted to enable communication with external resources.
3. Deploy the EC2 Instance
- A t2.micro instance was launched using a publicly available Ubuntu AMI.
- The instance was configured with a public IP address to allow external access.
- A user data script automated the installation and setup of the NGINX web server:
#!/bin/bash
sudo apt-get update -y
sudo apt-get install -y nginx
sudo systemctl start nginx
sudo systemctl enable nginx
4. Verify the Deployment
- Terraform outputs included the public IP address of the EC2 instance.
- The default NGINX page was accessible by navigating to the public IP in a browser.
5. Clean Up Resources
- Terraform’s
destroy
command ensured all resources were safely and systematically deleted when no longer needed.
Key Project Files
-
providers.tf
: Configured the AWS provider and defined the Terraform version:
terraform {
required_version = ">= 1.7.5"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
-
network.tf
: Defined the VPC, subnet, Internet Gateway, route table, and associations:
locals {
common_tags = {
project = "project01"
}
}
resource "aws_vpc" "project01-vpc" {
cidr_block = "10.0.0.0/16"
tags = merge(local.common_tags, {
Name = "project01-vpc"
})
}
resource "aws_subnet" "public-subnet" {
vpc_id = aws_vpc.project01-vpc.id
cidr_block = "10.0.0.0/24"
tags = merge(local.common_tags, {
Name = "public-subnet"
})
}
resource "aws_internet_gateway" "project01-igw" {
vpc_id = aws_vpc.project01-vpc.id
tags = merge(local.common_tags, {
Name = "project01-igw"
})
}
resource "aws_route_table" "project01-rtb" {
vpc_id = aws_vpc.project01-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.project01-igw.id
}
tags = merge(local.common_tags, {
Name = "project01-rtb"
})
}
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public-subnet.id
route_table_id = aws_route_table.project01-rtb.id
}
-
compute.tf
: Provisioned the EC2 instance and security group:
resource "aws_security_group" "nginx-server-sg" {
description = "Security group allowing HTTP(port 80) and HTTPS(port 443)"
name = "nginx-server-sg"
vpc_id = aws_vpc.project01-vpc.id
# Allow inbound HTTP traffic on port 80
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# Allow inbound HTTP traffic on port 443
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# Allow all outbound traffic
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = merge(local.common_tags, {
Name = "nginx-server-sg"
})
}
resource "aws_instance" "nginx-server" {
ami = "ami-0866a3c8686eaeeba"
associate_public_ip_address = true
instance_type = "t2.micro"
subnet_id = aws_subnet.public-subnet.id
vpc_security_group_ids = [aws_security_group.nginx-server-sg.id]
root_block_device {
delete_on_termination = true
volume_size = 10
volume_type = "gp3"
}
user_data = <<-EOF
#!/bin/bash
sudo apt-get update -y
sudo apt-get install -y nginx
sudo systemctl start nginx
sudo systemctl enable nginx
EOF
tags = merge(local.common_tags, {
Name = "project01-nginx-server"
})
lifecycle {
create_before_destroy = true
}
}
Conclusion
This project offers a glimpse into the capabilities of Infrastructure as Code (IaC) tools like Terraform. While it’s neither exhaustive nor flawless, it serves as a foundation for exploring how IaC can simplify and automate infrastructure management. I hope this project sparks ideas and inspires you to dive deeper into IaC practices.
Your feedback is invaluable, please feel free to share your thoughts. I’d love to hear from you!
Try It Yourself
- Clone the repository:
git clone https://github.com/bokal2/terraform-projects.git
cd project01
- Follow the steps in README to deploy your own NGINX server.
Happy building!
Top comments (3)
Crisp and clear. Thanks man!!
Yes straight forward great guide
Really wonderful article. Very clearly explained. I gave a star for your repo. Please do more such articles.