Configure WordPress on AWS EC2 with RDS MySQL using TERRAFORM

Welcome again to another blog on getting started with Terraform!

The terraform code that we are going to build in this blog will help you achieve the following: (It is good to know the basics!)

1. Launch an AWS EC2 instance.

2. Configure the instance with Apache Webserver.

3. Download PHP application “WordPress”.

4. Configure a MySQL Database server using AWS RDS that the WordPress application will use at the backend.

3. Finally, get the endpoint/connection string and other details to launch & connect to the WordPress site.

So, let’s get started!

Since we want to work with AWS, and as you might have already guessed, the first thing we will need is a provider declaration.

Hence, open up your workspace and create a new file named main.tf and start typing….

provider “aws” {region = “ap-south-1”profile = “default”}

You can use the region according to your preference. Make sure you have aws CLI configured in your system already and that you get a similar output as below when you type,

aws configure list-profiles

If not, you might want to look at this first.

Create a Security Group for your ‘to be launched’ AWS EC2 instance.

resource “aws_security_group” “FESG” {name = “fesgtf”ingress{cidr_blocks = [ “0.0.0.0/0” ]description = “allow ssh”from_port = 22to_port = 22protocol = “tcp”}ingress {cidr_blocks = [ “0.0.0.0/0” ]description = “allow http”from_port = 0to_port = 80protocol = “tcp”}egress{cidr_blocks = [ “0.0.0.0/0” ]description = “permit all”from_port = 0to_port = 0protocol = “-1”}}

The resource name for security groups is aws_security_group and the keywords are self-explanatory. Ingress block specifies the inbound rules which open port 22 and 80 for outside connections. Egress block specifies the outbound rules which allows all traffic to pass the firewall.

Create an AWS EC2 instance

resource “aws_instance” “wordpressfrontend” {ami = “ami-010aff33ed5991201”instance_type = “t2.micro”key_name = “shellws”security_groups = [ “fesgtf” ]tags = {app = “wordpress”role = “frontend”}}

We used the resource name aws_instance, and note that I used the security group created in step 2. You can omit writing that if you haven’t explicitly created a security group. Also, change the key_name parameter value to the name of the key you have.

If you don’t have a key pair, you can create one using the AWS CLI quickly. Type in the below command for that:

aws ec2 create-key-pair — key-name TFkey

Create an Elastic IP source

resource “aws_eip” “wpip” {instance = aws_instance.wordpressfrontend.idvpc = truetags = {app = “wordpress”}}

This resource creates an Elastic IP and attaches to our instance launched in step 3. It allows us to allocate a static public IP to the instance.

The id in aws_instance.wordpressfrontend.id is known as the attribute. It is among the many attributes, which, result from creating a particular resource. The id, in this case, is a result of the wordpressfrontend AWS EC2 instance that we launched in step 3.

Create an RDS MySQL instance.

Before we create an RDS instance, we can provide a facility to the user to provide a database password of their choice. So, we will create an input variable here.

variable “dbpassword” {type = stringdefault = “terraform”}

Now, we create an AWS DB instance and notice that we reference the input variable to the password parameter here.

resource “aws_db_instance” “wordpressbackend” {instance_class = “db.t3.micro”engine = “mysql”publicly_accessible = falseallocated_storage = 20name = “wordpress”username = “admin”password = var.dbpasswordskip_final_snapshot = truetags = {app = “mysql”}}

Create a null_resource to configure the AWS EC2 instance as a web server and install WordPress & PHP.

Inside the null_resource, we will have a remote-exec provisioner and a connection block.

The connection block is to provide the information used for connecting with the AWS EC2 instance, and the remote-exec invokes a script on a remote resource after it is created.

Here we have two null_resource. The first configure the apache server and downloads WordPress, while the second installs PHP.

resource “null_resource” “configweb12” {connection {type = “ssh”user = “ec2-user”private_key = file(“<path-to-private-key>”)host = aws_instance.wordpressfrontend.public_ip}provisioner “remote-exec” {inline = [“sudo yum install httpd -y”,“sudo systemctl start httpd”,“sudo systemctl enable httpd”,“sudo wget https://wordpress.org/wordpress-5.7.2.tar.gz",“sudo tar -xzf wordpress-5.7.2.tar.gz”,“sudo cp -r wordpress/* /var/www/html/”]}}resource “null_resource” “configphp” {connection {type = “ssh”user = “ec2-user”private_key = file(“C:/Users/insiyah/Downloads/shellws.pem”)host = aws_instance.wordpressfrontend.public_ip}provisioner “remote-exec” {inline = [“sudo yum install -y amazon-linux-extras”,“sudo amazon-linux-extras enable php7.2”,“sudo yum clean metadata -y”,“sudo yum install php-cli php-pdo php-fpm php-json php-mysqlnd -y”,“sudo systemctl restart httpd”]}}

Print the information for signing up to install WordPress.

We can use outputs to print certain values in the CLI output after running terraform apply.

output “WebServerIP” {value = aws_instance.wordpressfrontend.public_ipdescription = “Web Server IP Address”}output “DatabaseName” {value = aws_db_instance.wordpressbackend.namedescription = “The Database Name!”}output “DatabaseUserName” {value = aws_db_instance.wordpressbackend.usernamedescription = “The Database Name!”}output “DBConnectionString” {value = aws_db_instance.wordpressbackend.endpointdescription = “The Database connection String!”}

After you complete writing your code, run

terraform init

This will initialize your terraform workspace and download the required plugins.

Then, run the below command,

terraform plan

This will output the changes that will be made.

Finally, to run the script,

terraform apply

Type in your password when prompted, and then type yes.

When the execution completes, you can go to the webserver IP and install WordPress by pointing your browser to http://<ip>//wp-admin/install.php

You will be asked to give the information about the DB Host, username, password, etc.

After completing the steps, you will land on your WordPress site.

Find the complete source code here.

Software Engineer | DevOps Enthusiast | Writer