Skip to main content

Command Palette

Search for a command to run...

Deploying Your First Server with Terraform: A Beginner's Guide

Updated
3 min read
Deploying Your First Server with Terraform: A Beginner's Guide

Today, I worked through Chapter 2 of my cloud infrastructure studies, focusing on "Deploying a Single Server" and "Deploying a Web Server" (up to page 59). The goal was to deploy a basic web server on a cloud platform using Terraform and design an architecture diagram for it.

I chose AWS as my cloud provider since it's widely used and integrates well with Terraform. Below, I’ll walk through the steps I took to complete this task.

Task 1: Designing the Architecture Diagram

Since I used AWS, I designed a simple architecture in draw.io showing:

Single Server Deployment

  • Region: us-west-2

  • Instance Type: t2-micro

Web Server Deployment

  • Region: us-west-2

  • Instance Type: t2-micro

Key Components:

  1. EC2 Instance – Hosts the Apache web server.

  2. Security Group – Controls inbound/outbound traffic.

  3. User Data Script – Automates web server setup

Task 2: Writing Terraform Code for a Basic Web Server

Step 1: Setting Up Terraform

Before writing any code, I ensured:

  • Terraform was installed (terraform --version).

  • AWS CLI was configured with my credentials (aws configure).

Step 2: Writing the Terraform Configuration

I created a new directory for this project and wrote a main.tf file with the following code:

The terraform code for basic single server:

# Configure the AWS Provider
provider "aws" {
  region = "us-west-2" 
}

resource "aws_security_group" "ec2_sg" {
  name        = "ec2-security-group"
  description = "Allow SSH inbound traffic"

  ingress {
    from_port   = 22
    to_port     = 22
    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"]
  }
}

resource "aws_instance" "my_single_ec2_server" {
  ami           = "ami-04999cd8f2624f834" 
  instance_type = "t2.micro"              

  vpc_security_group_ids = [aws_security_group.ec2_sg.id]

  tags = {
    Name = "Single-Server"
  }
}


output "instance_public_ip" {
  description = "Public IP address of the EC2 instance"
  value       = aws_instance.my_single_ec2_server.public_ip
}

Terraform code for Basic Web Server:

# Configure the AWS Provider
provider "aws" {
  region = "us-west-2"
}
resource "aws_security_group" "ec2_sg" {
  name        = "web-server-sg"
  description = "Allow web traffic and SSH access"

  ingress {
    description = "SSH"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] 
  }

  ingress {
    description = "HTTP"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description = "HTTPS"
    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-server-security-group"
  }
}

resource "aws_instance" "web_server" {
  ami           = "ami-04999cd8f2624f834" 
  instance_type = "t2.micro"             
  vpc_security_group_ids = [aws_security_group.ec2_sg.id]

  user_data = <<-EOF
              #!/bin/bash
              yum update -y
              yum install -y httpd
              systemctl start httpd
              systemctl enable httpd
              echo "<h1>Hello World from Terraform 30 Day Challenge</h1>" > /var/www/html/index.html
              EOF

  tags = {
    Name = "WebServer"
  }
}

output "public_ip" {
  description = "Public IP address of the web server"
  value       = aws_instance.web_server.public_ip
}

output "public_dns" {
  description = "Public DNS name of the web server"
  value       = aws_instance.web_server.public_dns
}

Challenges Faced & Solutions

  1. AMI ID Variability – Had to ensure I used the correct Amazon Linux 2 AMI for us-west-2

    • Solution: Checked the AWS AMI catalog.
  2. Security Group Misconfiguration – Initially blocked HTTP traffic.

    • Solution: Verified ingress rules for port 80.

More from this blog

Simi Cloud and DevOps

20 posts