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?)
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
Login to AWS Console
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
MySQL – version 5.7.22 Production Template which will allow Multi-AZ DB instance
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
Security, Identity, & Compliance > IAM > Roles > Create role
AWS service - EC2
Permissions policies > AmazonS3FullAccess
Role name: S3forWP
EC2
Launch instance > Amazon Linux 2 AMI
T2 micro - all default except IAM role: S3ForWP - Advanced Details - User data - bootstrap script
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
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
Sorry, but I can’t write the wp-config.php file Copy/paste text
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
Login to WP
See the WP Dashboard
Add post
Add photos to Media
Check website post
Right click copy image address
Paste in browser and confirm EC2 Public IP address
Media files should be located on EC2 in wp-content folder
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
cd /var/www/html
nano .htaccess
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
nano httpd.conf
Find
Edit AllowOverride ALL
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
Create Application Load balancer
Compute > EC2 > Load balancers – Create load balancer
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
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
/1 * root aws s3 sync --delete s3://markbradley-wp-code /var/www/html
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
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
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
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
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
References
[1] WordPress versions codex.wordpress.org/WordPress_Versions
[2]WordPress and PHP Version Compatibility make.wordpress.org/core/handbook/references..