AWS Tip

Best AWS, DevOps, Serverless, and more from top Medium writers .

Follow publication

From Scratch to Scalable: Deploying WordPress on AWS with EC2, RDS, and Terraform

What is WordPress?

WordPress is a free and open-source Content Management System (CMS) that allows users to create and manage digital content. It’s a popular platform for building websites, blogs, and online applications.

Read more: What is WordPress?

What is RDS?

RDS stands for Relational Database Service, a cloud-based relational database management system offered by Amazon Web Services (AWS). It provides a scalable, secure, and managed database service for various database engines, including MySQL, PostgreSQL, Oracle, and SQL Server.

Read more: https://medium.com/p/e321099d3ac5

What is EC2?

EC2 stands for Elastic Compute Cloud, a cloud-based virtual machine service offered by AWS. It provides scalable, on-demand computing resources for a variety of workloads, including web servers, databases, and applications.

Read more: https://medium.com/@nupmanyu/launch-ec2-instance-attach-ebs-volume-using-aws-cli-49403c268d3e

What is Terraform?

Terraform is an infrastructure as code (IaC) tool that allows users to define and manage cloud and on-premises infrastructure using a human-readable configuration file. It supports multiple cloud providers, including AWS, Azure, and Google Cloud.

Read more: https://medium.com/devops-dev/understanding-terraform-workflow-plan-apply-and-destroy-75b5f64c58b1

Let us now start with the Implementation

Step 1: Install Terraform and Create main.tf File or file with .tf extension.

sudo yum install yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo
sudo yum install terraform

Step 2: Configure Provider and Create VPC .

provider "aws" {
region = "ap-south-1" # Asia Pacific (Mumbai)
}
resource "aws_vpc" "my_vpc" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true

tags = {
Name = "MyVPC"
}
}

Step 3: Create Subnets .

resource "aws_subnet" "public_subnet_1" {
vpc_id = aws_vpc.my_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-south-1a"

tags = {
Name = "PublicSubnet1"
}
}

resource "aws_subnet" "public_subnet_2" {
vpc_id = aws_vpc.my_vpc.id
cidr_block = "10.0.2.0/24"
availability_zone = "ap-south-1b"

tags = {
Name = "PublicSubnet2"
}
}

Step 4: Create Internet Gateway and Route Tables. Associate Route Tables with Subnets.

#Internet gateway.

resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.my_vpc.id

tags = {
Name = "MyIGW"
}
}

#Routing Table.

resource "aws_route_table" "public" {
vpc_id = aws_vpc.my_vpc.id

route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}

tags = {
Name = "PublicRouteTable"
}
}

resource "aws_route_table_association" "public_association_1" {
subnet_id = aws_subnet.public_subnet_1.id
route_table_id = aws_route_table.public.id
}

resource "aws_route_table_association" "public_association_2" {
subnet_id = aws_subnet.public_subnet_2.id
route_table_id = aws_route_table.public.id
}
Subnets.

Step 5: Create Security Group .

resource "aws_security_group" "wordpress_sg" {
vpc_id = aws_vpc.my_vpc.id

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"]
}

tags = {
Name = "WordPressSG"
}
}
security group.

Step 6: Create Key Pair and Save It.

resource "tls_private_key" "my_key" {
algorithm = "RSA"
}

resource "aws_key_pair" "deployer" {
key_name = "test-key"
public_key = tls_private_key.my_key.public_key_openssh
}

resource "null_resource" "save_key_pair" {
provisioner "local-exec" {
command = "echo ${tls_private_key.my_key.private_key_pem} > mykey.pem"
}
}

# Save the private key locally in CloudShell or the directory if using AWS cli.
resource "local_file" "private_key" {
content = tls_private_key.my_key.private_key_pem
filename = "/home/cloudshell-user/mykey.pem" # Path for CloudShell
}
mykey.pem

Step 7: Create RDS Instance .


resource "aws_db_instance" "wordpress_rds" {
engine = "postgres"
engine_version = "16.3" # Use the specific version
instance_class = "db.t3.micro" # Suitable instance class for small workloads
allocated_storage = 20
db_name = "wordpress_db"
username = "test"
password = "test1234"
db_subnet_group_name = aws_db_subnet_group.my_db_subnet_group.name
vpc_security_group_ids = [aws_security_group.wordpress_sg.id]

skip_final_snapshot = true
publicly_accessible = false

tags = {
Name = "PostgreSQL RDS Instance"
}
}

Step 8: Create EC2 Instance .

resource "aws_instance" "wordpress" {
ami = "ami-0522ab6e1ddcc7055" # Valid AMI ID for ap-south-1
instance_type = "t2.micro"
key_name = aws_key_pair.deployer.key_name
vpc_security_group_ids = [aws_security_group.wordpress_sg.id]
subnet_id = aws_subnet.public_subnet_1.id

tags = {
Name = "wordpress-instance"
}
}

Step 9: Verify Resources Creation.

terraform plan.
terraform apply.
successfully applied.
ec2 instance.
RDS database.

Step 10: Install docker on the instance and pull wordpress image and add user data to resource or go to Step 11.

#ADD this data to ec2 resource.
user_data = <<-EOF
#!/bin/bash
sudo apt-get update
sudo apt-get install -y docker.io
sudo systemctl start docker
sudo apt-get install -y docker.io
sudo systemctl enable docker
sudo systemctl enable docker
sudo docker pull wordpress
sudo docker run -d --name wordpress -e WORDPRESS_DB_HOST=${aws_db_instance.wordpress_rds.endpoint} -e WORDPRESS_DB_USER=test -e WORDPRESS_DB_PASSWORD=addyourpassword -e WORDPRESS_DB_NAME=wordpress_db -p 9000:80 wordpress

Step 11 : Connect to the instance manually and then install docker.

     yum install docker
systemtclt start docker
systemtctl start docker
sudo systemctl start docker
docker images
docker pull wordpress
docker run -d --name wordpress -e WORDPRESS_DB_HOST=terraform-20240927091947563700000004.c5gk0siig490.ap-south-1.rds.amazonaws.com -e WORDPRESS_DB_USER=test -e WORDPRESS_DB_PASSWORD=test1234 -e WORDPRESS_DB_NAME=wordpress_db -p 9000:80 wordpress
commands.
running at 9000.

Step 12:Result.

Wordpress.
yourpublicip:9000
login.
Wordpress.

Step 13: Destroy.

terraform destroy.
terraform destroy.

The configuration is very big so here we can use the concepts of modules in terraform. Terraform modules allow us to break down our infrastructure code into smaller, reusable pieces that can be easily managed and composed together.In our case, we could create separate modules for:

  • VPC and subnets.
  • Security groups.
  • Instances (e.g., WordPress instance).
  • Databases (e.g., RDS instance).
  • Key pairs and SSH configuration.

Thank you for reading………..

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in AWS Tip

Best AWS, DevOps, Serverless, and more from top Medium writers .

Written by Naman Sharma

Hi there! I'm excited to be sharing my ideas with you on this platform. I'm a curious and creative individual with a passion for exploring new topics.

No responses yet

Write a response