Blog-Background

My Solution Architect Associate Resume Project Part 2 – Launching EC2 With AWS CLI and Installing LEMP Stack

"What I cannot create, I do not understand" Richard Feynman

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.

Objective

  • 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

I have the AWS CLI version 2 installed and configured on my local machine simply follow the previous links if you want to follow along and don’t have it.

So in order to create an EC2 instance, I need at least 3 things

  1. Create a key pair to use it to ssh to the instance.
  2. Create a security group to allow both SSH and HTTP.
  3. 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.
  4. 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[0].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

sudo su

Installing LEMP Stack on EC2 RHEL 8 Instance

Installing Nginx

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

curl localhost

if you see a bunch of HTML coming back then everything is working as expected so far, now let’s move to the DB.

Installing MariaDB

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 mysql_secure_installation script.

Installing PHP

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.

By default, php-fpm runs as the apache user. Since we are using Nginx, we need to change that

vi /etc/php-fpm.d/www.conf
#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

vi /var/share/nginx/html/info.php

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 35.180.188.241/info.php and you should see the full info about this php version.

Wrapping Up

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!

Share this post

Share on facebook
Share on twitter
Share on linkedin
Share on pinterest
Share on print
Share on email
Recent Comments

    Leave a Reply

    Your email address will not be published.