Architecting AWS with Terraform Series.
Erick Okal

Erick Okal @bokal

About: I'm a seasoned software engineer with 8+ years of experience specializing in backend development, cloud technologies, and DevOps practices.

Joined:
Dec 3, 2024

Architecting AWS with Terraform Series.

Publish Date: Dec 10 '24
61 6

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.

VPC diagram

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
Enter fullscreen mode Exit fullscreen mode

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

  1. 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"
 }
Enter fullscreen mode Exit fullscreen mode
  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
}

Enter fullscreen mode Exit fullscreen mode
  1. 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
  }
}

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
  • Follow the steps in README to deploy your own NGINX server.

Happy building!

Comments 6 total

  • VIKRAM PALLED
    VIKRAM PALLEDDec 11, 2024

    Crisp and clear. Thanks man!!

    • Erick Okal
      Erick OkalDec 16, 2024

      Thanks a lot. I'm glad to hear that.

  • Keith-bytes
    Keith-bytesDec 11, 2024

    Yes straight forward great guide

    • Erick Okal
      Erick OkalDec 16, 2024

      Thanks, I'm happy you found it useful.

  • Vignesh S
    Vignesh SDec 12, 2024

    Really wonderful article. Very clearly explained. I gave a star for your repo. Please do more such articles.

    • Erick Okal
      Erick OkalDec 16, 2024

      Thanks for the encouragement and support, I really appreciate it. I'll definitely drop more

Add comment