Deploying WordPress on AWS with Terraform

2 min read

Overview

In this project, I used Terraform to provision a complete WordPress stack on Amazon Web Services.

This post shows how I spun up a fully working WordPress site onto an AWS EC2 instance using infrastructure-as-code, with everything reproducible and version-controlled.


What This Project Demonstrates

  • Infrastructure provisioning with Terraform
  • EC2 instance configuration
  • Security group management
  • Automating setup with user data scripts
  • Debugging real-world deployment issues

Tech Stack

  • AWS EC2
  • Terraform
  • Bash (user data script)
  • WordPress + Apache

Step 1 - Initial EC2 Setup

I started by configuring the AWS provider and creating a basic EC2 instance.

tf
resource "aws_instance" "web" {
  ami           = var.ami_id
  instance_type = var.instance_type
}

To make the configuration reusable, I defined inputs in variables.tf and exposed key details (like public IP) using outputs.tf.

Deployment Commands

shell
terraform init
terraform validate
terraform plan
terraform apply

I copied the AWS provider from the terraform docs. The repo was ready to be initialised for terraform so I ran terraform init.

Screenshot_20260406_123208.pngScreenshot_20260406_123145.pngScreenshot_20260406_123233.png

On the AWS Management Console, the instance is healthy and up and running.


First Issue - Instance Not Accessible

After deployment, the EC2 instance was running but not reachable via browser.

Root Cause

No security group rules were configured → no inbound traffic allowed.

Fix

  • Destroy the existing infrastructure:
shell
terraform destroy
  • Rebuild with proper networking configuration
Screenshot_20260406_124022.png

Step 2 - Configuring Security Groups

I added a security group to allow:

  • HTTP (port 80)
  • SSH (port 22)
tf
resource "aws_security_group" "wordpress_sg" {
  name = "wordpress_sg"


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


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

Step 3 - Automating WordPress Installation

To avoid manual setup, I used a user data script (user_data.sh) to install:

  • Apache
  • PHP
  • WordPress

I found a tutorial on the AWS docs for installing wordpress and used this to make my user_data script.

tf
resource "aws_instance" "web" {
  ami                    = var.ami_id
  instance_type          = var.instance_type
  user_data              = file("./user_data.sh")
  vpc_security_group_ids = [aws_security_group.wordpress_sg.id]
}

This script runs automatically when the instance boots.


Step 4 - Redeploy and Verify

After updating the configuration:

shell
terraform apply

Two resources are built, the instance security group and the instance itself.

Screenshot_20260406_145112.png

This time, navigating to the public IP opened the WordPress setup page successfully.

Screenshot_20260406_145144.png

Final Result

A fully working WordPress site deployed using Terraform:

  • Infrastructure defined as code
  • Automated server configuration
  • Publicly accessible endpoint
Screenshot_20260406_145325.png

Key Learnings

  • Security groups are critical - without them, your instances are unreachable
  • Terraform is declarative - if something is missing, it won’t “guess”
  • User data scripts = automation power - no manual server setup needed
  • Debugging infra issues is often about networking first, not code

Project Structure

shell
.
├── main.tf
├── variables.tf
├── outputs.tf
└── user_data.sh