DEV Community

Mukami
Mukami

Posted on

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

Introduction

Infrastructure as Code (IaC) is one of those concepts that sounds complicated until you actually try it. Instead of clicking through cloud consoles like a robot, you write code that does the clicking for you. Today, I'm sharing my experience from Day 3 of the 30-Day Terraform Challenge, where I deployed my first web server on AWS using Terraform.

By the end of this guide, you'll have provisioned real infrastructure without touching a single console button. Well, maybe just your keyboard.


What You'll Need

  • Terraform installed (v1.0+)
  • An AWS account (free tier works)
  • AWS access keys (keep these safe!)
  • Basic terminal skills

Provider Block vs Resource Block

Before we dive in, let's clarify the two most important Terraform concepts:

Provider Block:

provider "aws" {
  region = "eu-north-1"
}
Enter fullscreen mode Exit fullscreen mode

The provider block tells Terraform which cloud platform to use. Think of it as introducing Terraform to your cloud provider and saying "we'll be working together."

Resource Block:

resource "aws_instance" "web_server" {
  ami           = "ami-0c48e6b25760f0b7d"
  instance_type = "t3.micro"
}
Enter fullscreen mode Exit fullscreen mode

Resource blocks define the actual infrastructure components. Each one creates something realβ€”a server, a database, a network. The provider handles the connection; resources handle the creation.


Step-by-Step Deployment

Step 1: Set Up Your Project

mkdir terraform-day3-server
cd terraform-day3-server
Enter fullscreen mode Exit fullscreen mode

Step 2: Create main.tf

Create a file called main.tf with this configuration:

# Provider configuration
provider "aws" {
  region = "eu-north-1"  # Stockholm region
}

# Security group - controls traffic to your server
resource "aws_security_group" "web_sg" {
  name        = "day3-web-sg"
  description = "Allow HTTP traffic"

  # Allow HTTP from anywhere
  ingress {
    description = "HTTP from internet"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  # Allow all outbound traffic
  egress {
    description = "All outbound traffic"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "day3-web-sg"
  }
}

# Get the latest Amazon Linux 2 AMI
data "aws_ami" "amazon_linux_2" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}

# EC2 instance with web server
resource "aws_instance" "web_server" {
  ami           = data.aws_ami.amazon_linux_2.id
  instance_type = "t3.micro"  # Free tier eligible in eu-north-1

  vpc_security_group_ids = [aws_security_group.web_sg.id]
  associate_public_ip_address = true

  # Script runs when instance starts
  user_data = <<-EOF
    #!/bin/bash
    yum update -y
    yum install -y httpd
    systemctl start httpd
    systemctl enable httpd
    echo "<html>
    <head>
        <title>Terraform Day 3 Challenge</title>
        <style>
            body { font-family: Arial, sans-serif; text-align: center; padding: 50px; background: #f0f2f5; }
            h1 { color: #333; }
            .success { color: #00a86b; }
        </style>
    </head>
    <body>
        <h1>βœ… Day 3 Challenge Success!</h1>
        <p>Your first Terraform-deployed server is running</p>
        <p class='success'>Deployed on: $(date)</p>
        <p>Server IP: $(curl -s http://169.254.169.254/latest/meta-data/public-ipv4)</p>
    </body>
    </html>" > /var/www/html/index.html
  EOF

  tags = {
    Name = "day3-terraform-server"
  }
}

# Output useful information
output "public_ip" {
  value = aws_instance.web_server.public_ip
}

output "website_url" {
  value = "http://${aws_instance.web_server.public_ip}"
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Deploy!

Run these commands in order:

# Initialize Terraform (downloads AWS provider)
terraform init

# See what will be created
terraform plan

# Create the infrastructure
terraform apply
Enter fullscreen mode Exit fullscreen mode

Type yes when prompted. After a minute or two, you'll see:

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:
public_ip = "13.48.12.34"
website_url = "http://13.48.12.34"
Enter fullscreen mode Exit fullscreen mode

Step 4: Verify It Works

Copy the URL from the output and paste it in your browser. You should see your custom webpage with the deployment date and server IP.

Step 5: Clean Up (Seriously, Do This)

terraform destroy
Enter fullscreen mode Exit fullscreen mode

Type yes when prompted. This prevents unexpected charges on your AWS bill.


Architecture Diagram

Understanding the Terraform Workflow

Command What It Does
terraform init Downloads provider plugins, sets up backend
terraform plan Shows what will change without actually changing anything
terraform apply Creates or updates infrastructure
terraform destroy Removes all resources

Think of plan as a preview and apply as the final execution. Always review the plan before applying!


Key Takeaways

  1. Provider blocks configure which cloud platform to use
  2. Resource blocks define actual infrastructure components
  3. Security groups are like firewall rules for your instances
  4. User data automates software installation and configuration
  5. Always destroy resources after learning to avoid costs
  6. terraform plan is your safety net - use it!

Top comments (0)