LAMP Stack

LAMP Stack

LAMP is the fluorescent lightbulb of the internet. It’s utilitarian and does its job well, even if it doesn’t have the glow of an incandescent light nor the novelty of an LED bulb.

A huge portion of the internet is brought to you by open-source software. One of those programming languages is something that is used by nearly 80 percent of sites on the internet, and a huge chunk of the people using that programming language on their server are using three key tools—the operating system Linux, the HTTP server Apache, and the database system MySQL. Together these tools combined with PHP into one of the greatest killer apps the open-source community ever produced: the LAMP stack. (Get it?)

visual-representation-of-the-lamp-stack-pnap.png

Linux: The operating system (OS) makes up our first layer. Linux sets the foundation for the stack model. All other layers run on top of this layer.

Apache: The second layer consists of web server software, typically Apache Web Server. This layer resides on top of the Linux layer. Web servers are responsible for translating from web browsers to their correct website.

MySQL: Our third layer is where databases live. MySQL stores details that can be queried by scripting to construct a website. MySQL usually sits on top of the Linux layer alongside Apache/layer 2. In high end configurations, MySQL can be off loaded to a separate host server.

PHP: Sitting on top of them all is our fourth and final layer. The scripting layer consists of PHP and/or other similar web programming languages. Websites and Web Applications run within this layer.

Five popular web tools that use or have used LAMP and PHP

• WordPress • Facebook • Wikipedia • Tumblr • Slack

LAMP is certainly an older web technology and often unloved for this reason. It’s an old design in the modern era, and often loses out on some of the advantages that we’ve gained since. But just because it doesn’t have those modern upsides doesn’t mean it’s all downside. Modern developers often don’t have a great opinion of LAMP stacks, even though the servers that rely on it are just about everywhere!

WordPress LAMP Stack on AWS

OK let's have some fun and setup a WordPress LAMP Stack on AWS!

We will create a fault tolerant WordPress site with high availability. A WP Admin will manage the site and content directly accessing on an EC2 instance that will upload both code and media to S3. Users will access the website through a load balancer to a group of EC2 instances that will download the code and media from S3. CloudFront will host and cache media files for performance.

This could be a typical small proof of concept example for a customer. We can use this as a real-life case study to create a fault tolerant WordPress site. We'll skip through the steps in AWS and will not document every small configuration detail. Please note this is a temporary environment and security considerations may be open. Production would use HTTPS 443 instead of HTTP port 80 and other restrictions.

Manually setting up a system yourself is a great way to help you understand how each cloud components are connected. In future blogs I hope to show you other methods to create a LAMP stack including using AWS Elastic Beanstalk and Serverless!

Components Used

  • IAM Roles
  • Security Groups
  • VPC
  • EC2
  • S3
  • Elastic Load Balancer
  • Availability Zones
  • Auto Scaling Groups
  • Amazon RDS Multi-AZ MySQL
  • CloudFront
  • Route 53
  • Linux
  • Apache
  • PHP
  • WordPress

How easy is setup?

Architecture Diagram

100.JPG

Login to AWS Console

Console.JPG

Networking & Content Delivery > VPC > Security Groups

Create two new security groups in my default VPC

WebDMZ - port 22, 80 - source: 0.0.0.0/0

RDS-MYSQL/Aurora - port 3306 - source: Security group name for WebDMZ

Database > RDS > Create database

2.JPG

MySQL – version 5.7.22 Production Template which will allow Multi-AZ DB instance

51.JPG

Enter a DB instance identifier name with Master name and password

For test and billing purposes we will use a T2 Micro 20GB General Purpose SSD

Create DB instance that is not publicly accessible and in Default VPC choosing existing VPC security groups - RDS-MYSQL/Aurora

S3 > Create bucket

Create two S3 buckets

markbradley-wp-code / Bucket and objects not public

markbradley-wp-media / Public Access

CloudFront > Distribution > Create distribution

Create a distribution and use the S3 media bucket for the Origin Name and S3 FQDN for Origin Domain

8.JPG

Security, Identity, & Compliance > IAM > Roles > Create role

AWS service - EC2

Permissions policies > AmazonS3FullAccess

Role name: S3forWP

EC2

Launch instance > Amazon Linux 2 AMI

101.JPG

T2 micro - all default except IAM role: S3ForWP - Advanced Details - User data - bootstrap script

12.JPG

Bootstrap script

Update

Install Apache, PHP, PHP-MySQL packages

Copy a healthy.html file in the /var/www/html folder

Download/install WordPress

Add Tag: Name / WPWriteNode

Select WebDMZ for Security Group (port 22, 80)

Login to EC2 using Public IPv4 address with Key pair

21.JPG

Elevate privileges to sudo su

Check WordPress files present

Check Apache service is started

WordPress Configuration

Database > RDS > Databases - Select database and copy Endpoint info

Open browser and EC2 IP address for WordPress GUI

Enter endpoint for Database Host and Database name, username, and password

13.JPG

Sorry, but I can’t write the wp-config.php file Copy/paste text

14.JPG

nano wp-config.php Copy/Paste - Ctrl-X - Y

Go back to GUI and click “Run the Installation”

Complete the welcome screen to install WP

15.JPG

Login to WP

24.JPG

See the WP Dashboard

17.JPG

Add post

Add photos to Media

Check website post

Right click copy image address

Paste in browser and confirm EC2 Public IP address

27.JPG

Media files should be located on EC2 in wp-content folder

28.JPG

CMD line copy files to S3

aws s3 cp /var/www/html/wp-content/uploads/2022/02 s3://markbradley-wp-media –recursive

aws s3 cp /var/www/html s3://markbradley-wp-code –recursive

After copy verify files

aws s3 ls s3://markbradley-wp-code

URL rewrite rule for CloudFront

Networking & Content Delivery > CloudFront - Distributed domain name

38.JPG

cd /var/www/html

nano .htaccess

39.JPG

Edit current CloudFront URL to include CloudFront Distributed domain name

Copy/Paste

Ctrl+X – Y

aws s3 sync /var/www/html s3://markbradley-wp-code

This will upload and change the edited .htaccess file in S3

This file will now point to CloudFront

Configure Apache for URL rewrites

cd /etc/httpd

ls

cd conf

ls

34.JPG

nano httpd.conf

35.JPG

Find

36.JPG

Edit AllowOverride ALL

37.JPG

Ctrl+X - Y

service httpd restart

Validate CloudFront is now hosting media files

Open WP in browser and check post and images

Right click copy image address

Paste in browser and confirm CloudFront address and not EC2 instance

50.JPG

Create Application Load balancer

Compute > EC2 > Load balancers – Create load balancer

18.JPG

Application Load Balancer – HTTP HTTPS

Internet Facing - IPv4 – HTTP - All Availability Zones

Select Existing Security Group - WebDMZ

New Target Group - MyWPInstances

Target Type: Instance - Protocol: HTTP - Port: 80

Health Check - Protocol: HTTP - Path: /healthy.html

40.JPG

Configure ReadNode EC2 for AMI to download S3 content and use for Auto Scale Group

Configure WriteNode EC2 to upload S3 content

Setup a cron job

The cron command-line utility is a job scheduler that can run tasks at fixed times, dates, or intervals

Login EC2

cd /etc

nano crontab

42.JPG

/1 * root aws s3 sync --delete s3://markbradley-wp-code /var/www/html

44.JPG

Ctrl+X > Y > service crond restart

This task will download the S3 folder contents for the read node instance – Copy from S3 to local folder

Test update to S3

Add file hello.txt to s3://markbradley-wp-code

Check EC2

cd /var/www/html

hello.txt

cat hello.txt > displays text content

Create Template for WPReadNode EC2

Compute > EC2 - Select instance > Action > Image > Create Image

Image Name: WPReadNode

Image Description: This is the default read node for WP

Images > AMIs - check image is available

45.JPG

Login to WP WriteNode EC2

sudo su

cd /var/www/html/etc

clear

nano crontab

/1 * root aws s3 sync --delete /var/www/html s3://markbradley-wp-code

/1 * root aws s3 sync --delete /var/www/html/wp-content/uploads s3://markbradley-wp-media

Ctrl+X > Y

This task will upload the local folder contents to S3 for the write node instance.

Test update to S3

cd /var/www/html

echo "This is a TEST" > test.txt

service crond restart

service httpd status

Check S3

Check s3://markbradley-wp-code has test.txt file

Setup Auto Scaling Groups using new AMI (read nodes)

Compute > EC2 > Auto Scaling Groups

Create Launch Template – LCforWP - My AMIs – WPReadNode – T2.Micro – IAM role: S3ForWP Security Group: WebDMZ

46.JPG

Compute > EC2 > Target Groups – Create target group

MyWPInstances – Target type: instance – HTTP – 80 – Default VPC – HTTP - /healthy.html

Actions – Register and deregister instance / IP targets

Check registered targets – healthy

48.JPG

Create Auto Scaling Group – ASGforWP – 3 instances – default VPC – all subnets

Check - Receive traffic from one or more load balancers

Target Group: MyWPInstances Health Check Type: ELB

47.JPG

Post implementation validation checks

EC2 Dashboard

Check instances running

Target Groups

Check all registered targets - WPReadNode – healthy

WP website

Validate and open HTTP page with domain to view WordPress site hosted via Load Balancer

Open image file to see page and validate CloudFront address.

Edit Write Node EC2 and content is auto copied to S3 and S3 downloaded to Read Nodes EC2

Website is updated with new content

Check autoscaling by terminating running RN instances and verify new replacement instances

Auto Scaling Group – Activity History will confirm terminated instances and new EC2 instances

Check RDS by rebooting instance - primary will failover to secondary

OPTIONAL Add Domain Name to WP site

Networking & Content Delivery > Route 53 > Hosted zones > Create hosted zone

Create a hosted zone for your domain name

After creating Load balancer – Route 53 Alias

Hosted zones – Domain name

Create Record Set

A

Alias - Y

Alias Target: name of load balancer

Routing Policy: Simple

Evaluate Target Health - No

22.JPG

References

[1] WordPress versions codex.wordpress.org/WordPress_Versions

[2]WordPress and PHP Version Compatibility make.wordpress.org/core/handbook/references..