- Part 1 – Introduction
- Part 2 – Launching EC2 with AWS-CLI and Installing LEMP Stack
- Part 3 – Automating WordPress and Nginx Installation and configuration
What, Why, and How
Hello and welcome to this series about automating my personal Portfolio/Resume/CV.
Throughout this series, I’m going to be trying to automate the deployment of my website you currently viewing, from provisioning the infrastructure on AWS all the way to installing and configuring the application stack itself with the goal to create a fault-tolerant, highly available, and highly scalable three-tier production application.
Since I don’t wanna write any front-end code or design anything as this mainly for fun and not profit, applying what am learning as am studying for the AWS associates exams, I will be using WordPress so I can simply use a template and have a killer looking website in less than a couple of hours.
Disclaimer, I”m no expert in this yet, am just a regular joe who likes to automate his stuff as I find it fun and also the best way for me to learn and pick up new things so that aside let’s get back to the blog.
- Figuring out the Tech Stack
- Launching an EC2 instance
- Installing LEMP Stack on RHEL-8
The Tech Stack
Since we using WordPress some stuff gonna be non-negotiable, according to wordpress.org here are the requirements:
- PHP version 7.4 or greater.
- MySQL version 5.6 or greater OR MariaDB version 10.1 or greater.
- Apache or Nginx is what they recommend for the webserver(it’s not required to use one of these two, you can use another web server than nobody knows about)
So the only options I can choose from are what webserver and database I will be running(they both MySQL at the end of the day).
Because long live open source, I will be going with MariaDB and I find Nginx configuration syntax more readable and straightforward for me than Apache, also between me and you for job hunting-related reasons, am gonna go with Nginx.
Having decided on everything, I’m going to start from the ground and learn as I go while documenting this process and taking you on that journey with me one layer of abstraction at a time not literally but you get the idea!
I will start by installing everything manually to understand how everything fits together (as this my first time dealing with anything Php), and what is actually needed, so bear with me this will be a long series.
So first things first I’m going to spin an ec2 t2.micro and try to install everything manually and see how that gonna go, I will try to not use the console at all unless I can’t find another way because it’s way easier to automate what I type in the terminal, very smart right 😀
Launching an EC2 instance
So in order to create an EC2 instance, I need at least 3 things
- Create a key pair to use it to ssh to the instance.
- Create a security group to allow both SSH and HTTP.
- Get the AMI ID for the OS am going to be using which in this case REHL-8 and I will launch it in the Paris region as it has the least latency to where am currently located if you wanna figure out that for yourself you can simply use cloudping.info.
- Launch the instance using all the previous resources.
1.Creating the key pair
aws ec2 create-key-pair --key-name ParisKey --query 'KeyMaterial' --output text > ~/.ssh/parisKey.pem --region eu-west-3 chmod 400 ~/.ssh/parisKey.pem
Starting off by creating the key then adding the –query option to extract the “KeyMaterial” section which is the section that contains the data of the key as I need that to so I can create a file on my local machine to use it later on to ssh.
The second command just modifies the permissions of the key so nobody except me can read it. Since this is a private key, and it contains sensitive information, and also SSH will not allow us tp use it if it was too open.
2.Creating a security group:
I will be using the default VPC for the sake of simplicity for now, until later when I create my own custom VPC, so let’s get the default VPC ID.
aws ec2 describe-vpcs --region eu-west-3
Then I will use that Id that returns from the above command to create a security group.
aws ec2 create-security-group --group-name ssh-http --description "Allows SSH and HTTP traffic" --vpc-id $vpc-id
Then allowing both 22 and 80 ports for any device which is not ideal for production to open ssh like that but this is not the blog post to follow for production at this stage.
aws ec2 authorize-security-group-ingress --group-id $SG-ID --protocol tcp --port 22 --cidr 0.0.0.0/0 --region eu-west-3 aws ec2 authorize-security-group-ingress --group-id $SG-ID --protocol tcp --port 80 --cidr 0.0.0.0/0 --region eu-west-3
now I will double-check that both ports are open successfully by looking at the “IpPermissions” after running
aws ec2 describe-security-groups --group-id $SG-ID --region eu-west-3
3.Finding the AMI ID for RHEL-8:
After going through the docs here and checking the manual pages.
aws ec2 describe-images help
I didn’t have any luck figuring out how to filter and return the red-hat AMI’s at all, then I turned to my lovely friend google and instantly landed on this solution for an open issue about this in the past and as it turned out Redhat AMI’s all are published under one owner ID “309956199498”, and finally after figuring the right filters,
aws ec2 describe-images --owners 309956199498 --filters "Name=name,Values=RHEL-8.2.0*" "Name=architecture,Values=x86_64" --region eu-west-3 --output table --region eu-west-3
I got more than one AMI back and unfortunately, after another search to confirm, I figured out that AWS doesn’t return any specific values to understand which AMI is free-tier eligible and this when I gave up and had to use the console to know the Id of the free-tier eligible AMI.
Now I have the key pair, AMI Id and the security group so let’s launch the EC2 instance.
4.Launch the EC2 instance:
aws ec2 run-instances --image-id ami-09e973def6bd1ad96 --count 1 --instance-type t2.micro --key-name ParisKey --security-group-ids $SG-ID --region eu-west-3
This one is pretty self-explanatory I’m just passing the resources Ids that we created.
Now I put all this previous commands in a stupid script and we have this,
#!/bin/bash #No error handling for the sake of simplicty echo "Enter the region: " read REGION echo "**********" echo "Enter the key pair name: " read KEY_PAIR_NAMEecho " " echo "**********" echo "Enter AMI Image Id: " read AMI_ID #Create the keyPair for ssh aws ec2 create-key-pair --key-name $KEY_PAIR_NAME --query 'KeyMaterial' --output text > ~/.ssh/$KEY_PAIR_NAME.pem --region $REGION echo "Key pair created sucessfully and saved to ~/.ssh/$KEY_PAIR_NAME." chmod 400 ~/.ssh/$KEY_PAIR_NAME.pem #Assumimg I have only one vpc in that region the default one VPC_ID=`aws ec2 describe-vpcs --query 'Vpcs.VpcId' --output text --region $REGION` echo "Successfully got the default VPC ID $VPC_ID....." SG_ID=`aws ec2 create-security-group --group-name ssh-http --description "Allows SSH and HTTP traffic" --vpc-id $VPC_ID --query 'GroupId' --output text --region $REGION` echo "Successfully created the security group with Id $SG_ID....." echo "Allowing SSH & HTTP traffic on $SG_ID......" aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol tcp --port 22 --cidr 0.0.0.0/0 --region $REGION aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol tcp --port 80 --cidr 0.0.0.0/0 --region $REGION echo "Launching the instance....." aws ec2 run-instances --image-id $AMI_ID --count 1 --instance-type t2.micro --key-name $KEY_PAIR_NAME --security-group-ids $SG_ID --region $REGION
Now let’s SSH to the instance.
ssh ec2-user@PUBLIC-IP -i ~/.ssh/parisKey.pem
To avoid running sudo before each command am just gonna upgrade myself to the root user
Installing LEMP Stack on EC2 RHEL 8 Instance
As any program I can compile it from source or install a pre-built package, I don’t have any special needs to try to compile it from the source so am I just gonna install a prebuilt package.
There seem to be two ways to install a prebuilt package according to the docs, I can add the Nginx repo to yum and install it from there or I can just install it from the OS repository, for the sake of simplicity, I will just update yum and install it from the OS repo directly.
yum update -y yum install nginx
Next, I will start the service and also make sure it gets started again if the instance reboots/.
systemctl enable --now nginx
Just to make sure that the webserver is running as expected am gonna try to fetch the local host
if you see a bunch of HTML coming back then everything is working as expected so far, now let’s move to the DB.
yum module install mariadb systemctl enable --now mariadb mysql --version mysql_secure_installation
The same spiel again, however, this is time am installing it using the application-streams introduced in RHEL-8 then simply starting it and making sure it gets started on reboot, and lastly securing MariaDB by running the
yum install php php-fpm php-json php-mysqlnd php-json -y
In order to serve WordPress through Nginx, beside the standard language package, I will need as well a FastCGI( binary protocol for interfacing interactive programs with a web server) package which is to put it in a simple way protocol that Nginx uses to process PHP code. The package I will be using is
php-fpm besides that, I’m also installing
php-mysqlnd which is from its name a native driver that allows PHP to talk with MariaDB.
php-fpm runs as the
apache user. Since we are using Nginx, we need to change that
#We need to change the following two lines from apache to nginx user = nginx group = nginx
Now having everything configured lets run php-fpm
systemctl enable --now php-fpm
Lets test everything works
I will create a simple php file
Then add a simple one liner that returns the php info
<?php phpinfo(); ?>
and lastly reload nginx to apply changes
systemctl reload nginx
Now we can use our browser and hitting the instance public-ip/info.php in my case its 18.104.22.168/info.php and you should see the full info about this php version.
So in this part, I launched an RHEL-8 EC2 instance using the AWS-CLI and then installed LEMP stack on it, I will try to automate WordPress and Nginx installation and configuration using a couple of bash scripts as a start, I’m still not solid on how I will pull this off but this is the beauty of doing this, so thank you for reading so far and I will see you in the next one, cheers!