DEV Community

Aisalkyn Aidarova
Aisalkyn Aidarova

Posted on

Terraform Provisioners — FULL HANDS-ON LAB

STEP 1 — Create AWS Key Pair (IMPORTANT)

Go to:

  • AWS → EC2 → Key Pairs → Create Key Pair

Fill:

  • Name: terraform-key
  • Type: RSA
  • Format: .pem

Download file → it goes to:

~/Downloads/terraform-key.pem
Enter fullscreen mode Exit fullscreen mode

Move key to project folder

mkdir ~/terraform-provisioners
cd ~/terraform-provisioners
mv ~/Downloads/terraform-key.pem .
Enter fullscreen mode Exit fullscreen mode

Fix permissions (CRITICAL)

chmod 400 terraform-key.pem
Enter fullscreen mode Exit fullscreen mode

Why?

SSH will fail without this.


STEP 2 — Create Terraform File

touch main.tf
Enter fullscreen mode Exit fullscreen mode

STEP 3 — Write CORRECT main.tf

Copy EXACTLY:

provider "aws" {
  region = "us-east-1"
}

# -----------------------------
# GET LATEST AMAZON LINUX AMI
# -----------------------------
data "aws_ami" "amazon_linux" {
  most_recent = true

  owners = ["amazon"]

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

# -----------------------------
# SECURITY GROUP
# -----------------------------
resource "aws_security_group" "web_sg" {
  name = "terraform-provisioner-sg"

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

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

# -----------------------------
# EC2 INSTANCE
# -----------------------------
resource "aws_instance" "web" {
  ami           = data.aws_ami.amazon_linux.id
  instance_type = "t2.micro"

  key_name = "terraform-key"

  vpc_security_group_ids = [aws_security_group.web_sg.id]

  # -----------------------------
  # REMOTE EXEC (on EC2)
  # -----------------------------
  provisioner "remote-exec" {
    inline = [
      "sudo yum update -y",
      "sudo yum install nginx -y",
      "sudo systemctl start nginx",
      "sudo systemctl enable nginx"
    ]

    connection {
      type        = "ssh"
      user        = "ec2-user"
      private_key = file("terraform-key.pem")
      host        = self.public_ip
    }
  }

  # -----------------------------
  # LOCAL EXEC (on your machine)
  # -----------------------------
  provisioner "local-exec" {
    command = "echo ${self.public_ip} > public_ip.txt"
  }

  # -----------------------------
  # DESTROY PROVISIONER
  # -----------------------------
  provisioner "local-exec" {
    when    = destroy
    command = "echo Destroying EC2 instance..."
  }

  tags = {
    Name = "provisioner-lab"
  }
}
Enter fullscreen mode Exit fullscreen mode

STEP 4 — Initialize Terraform

terraform init
Enter fullscreen mode Exit fullscreen mode

STEP 5 — Apply

terraform apply -auto-approve
Enter fullscreen mode Exit fullscreen mode

WHAT HAPPENS

Phase 1 — Infrastructure

  • Terraform creates:

    • Security group
    • EC2 instance

Phase 2 — Provisioning

remote-exec

  • SSH into EC2
  • Runs:

    • install nginx
    • start nginx

local-exec

  • Runs on YOUR machine
  • Creates:
public_ip.txt
Enter fullscreen mode Exit fullscreen mode

STEP 6 — Verify

Get IP

cat public_ip.txt
Enter fullscreen mode Exit fullscreen mode

Open browser

http://<IP>
Enter fullscreen mode Exit fullscreen mode

You should see:

Welcome to nginx!
Enter fullscreen mode Exit fullscreen mode

STEP 7 — Debug (VERY IMPORTANT SKILL)

Test SSH manually

ssh -i terraform-key.pem ec2-user@<IP>
Enter fullscreen mode Exit fullscreen mode

If this fails → Terraform would fail too.


STEP 8 — Understand Provisioners

Provisioner Runs where Purpose
remote-exec EC2 install software
local-exec local machine save data
destroy before delete cleanup

STEP 9 — Failure Demo (IMPORTANT)

Break command:

"wrong-command"
Enter fullscreen mode Exit fullscreen mode

Run:

terraform apply
Enter fullscreen mode Exit fullscreen mode

Result:

  • Apply fails
  • Resource becomes TAINTED

STEP 10 — Fix failure behavior

on_failure = continue
Enter fullscreen mode Exit fullscreen mode

STEP 11 — Destroy

terraform destroy -auto-approve
Enter fullscreen mode Exit fullscreen mode

You will see:

Destroying EC2 instance...
Enter fullscreen mode Exit fullscreen mode

FINAL UNDERSTANDING

Flow:

Terraform → Create EC2
         → SSH (remote-exec)
         → Install nginx
         → Save IP (local-exec)
Enter fullscreen mode Exit fullscreen mode

MOST IMPORTANT RULES

  1. .pem must exist locally
  2. chmod 400 required
  3. key_name must match AWS
  4. SSH must work manually
  5. Provisioners run AFTER creation

INTERVIEW ANSWER (VERY IMPORTANT)

Provisioners allow Terraform to configure infrastructure after creation by executing commands locally or remotely, but they are not recommended for production due to lack of idempotency and debugging complexity.

Top comments (0)