Building Highly Available Web Application on AWS

Table of contents

Introduction

I recently had the opportunity to go through an incredibly insightful lab on AWS Skill Builder, which guided me through deploying a highly available WordPress application. The hands-on labs provided by AWS are incredibly interactive, and they offer a step-by-step approach that helped me learn and implement real-world cloud architectures. In this blog, I’ll take you through the entire lab experience and share how I created a highly available, scalable WordPress application using several AWS services.

I want to extend my thanks to AWS Skill Builder for offering such an engaging and valuable learning experience. If you’re interested, feel free to check out the lab for yourself here.

Architecture Diagram

Below is the architecture diagram representing the lab environment:

The architecture diagram of the lab environment.

The following list details the major resources in the diagram:

  • A single AWS Region with one VPC and two Availability Zones.

  • Each Availability Zone contains a public subnet, an app subnet, and a database subnet.

  • The NAT gateways are located in the public subnet of each Availability Zone.

  • An Application Load Balancer and an Auto Scaling group that has app servers in the app subnets of both Availability Zones.

  • Each app server communicates with an EFS mount target in its own subnet to reach the Amazon EFS file system, which is not inside an Availability Zone.

  • All app servers communicate with an Aurora primary DB instance in one of the database subnets. The other database subnet holds the Aurora replica.

  • An Amazon ElastiCache in database subnet that acts as a caching layer.

AWS Services Used

Throughout this lab, several AWS services were key to implementing the architecture:

  1. Amazon EC2 (Elastic Compute Cloud)
    EC2 instances serve as the compute resources for the WordPress application. By using EC2, we could launch virtual servers to run the WordPress app and manage the underlying infrastructure.

  2. Amazon RDS (Relational Database Service)
    RDS is used to manage the relational database for the WordPress application. It simplifies database provisioning, patching, and backups, ensuring that the database can scale with the application while remaining highly available and durable.

  3. Auto Scaling
    Auto Scaling automatically adjusts the number of EC2 instances based on demand, ensuring that the WordPress application can scale up or down as needed. This ensures that performance is maintained without over-provisioning resources, which can lead to cost savings.

  4. Elastic Load Balancer (ELB)
    ELB is used to distribute incoming web traffic evenly across multiple EC2 instances. This ensures that no single instance is overwhelmed with traffic and allows for fault tolerance by rerouting traffic if an instance goes down.

  5. Amazon EFS (Elastic File System)
    EFS provides scalable, shared file storage for the application tier. It’s used by multiple EC2 instances, allowing the WordPress application to share data across instances, even if they’re running in different Availability Zones.

  6. Amazon Aurora
    Aurora is a high-performance, MySQL and PostgreSQL-compatible relational database service. In this lab, we used Amazon Aurora as the database engine for WordPress, ensuring high availability and scalability of the database.

  7. AWS Fault Injection Simulator
    This service was crucial for testing the fault tolerance of the application. By simulating failures in the infrastructure (e.g., an Availability Zone outage), we could ensure that the application would remain highly available and resilient in case of real-world failures.

  8. Amazon CloudFront
    CloudFront is a content delivery network (CDN) that caches and delivers content (like images, JavaScript, and videos) from edge locations around the world. By using CloudFront, we could reduce latency and improve performance for global users accessing the WordPress site.

Lab Steps

🧩Task 1: Configure the Network

In this task, we use AWS CloudFormation to automate the provisioning of foundational networking components required for a highly available application architecture.

1.1 Navigate to the CloudFormation Console

  • In the AWS Management Console, we navigate to the top search bar, search for CloudFormation and select it.

1.2 Create the CloudFormation Stack

  • We choose Create stack → With new resources (standard).

  • We select Amazon S3 URL as the template source and paste the provided Task1TemplateUrl into the S3 URL field.

  • We set the Stack name as: VPCStack.

  • Leave default parameters as-is.

  • Skip optional settings and continue to the Review page.

  • Choose Submit to deploy the stack.

The stack may take a few minutes to finish creating all the resources. You can track its status using the Events tab.

1.3 View Created Resources

  • On the Resources tab, we review components like VPCs, Subnets, Route Tables, and more.

  • On the Events tab, we track the step-by-step progress of resource creation.

  • On the Outputs tab, we note down important values like VPC ID, Subnet IDs, etc., which will be referenced in later tasks.

🎥 Video Walkthrough



🗄️Task 2: Create an Amazon RDS Database

This task walks you through deploying a highly available and fully managed relational database using Amazon Aurora (MySQL-compatible) within Amazon RDS. This database will support the backend of the WordPress application.

2.1 Navigate to the Amazon RDS Console

  • We use the AWS Console search bar to go to Amazon RDS.

2.2 Create a New Aurora Database

  • We go to Databases → Create database.

  • We choose Standard create.

  • Under Engine options we select Aurora (MySQL Compatible) and Choose Production template.

2.3 Configure Database Settings

  • DB Cluster Identifier: MyDBCluster

  • Master Username: admin

  • Password: Use LabPassword

  • DB Instance Class: db.t3.medium (burstable class)

  • Multi-AZ Deployment: Enabled via Aurora Replica in a different AZ

2.4 Networking Configuration

  • VPC: LabVPC

  • DB Subnet Group: labdbsubnetgroup

  • Public Access: No

  • VPC Security Group: Use the custom security group (RDSSecurityGroup), remove default

2.5 Additional Settings

  • Initial DB Name: WPDatabase

  • Port: Default 3306

  • Enhanced Monitoring: Disabled

  • Encryption: Disabled

  • Auto Minor Version Upgrade: Disabled

  • Deletion Protection: Disabled

  • We then click on Create database

Aurora cluster creation takes a few minutes. It consists of two instances placed in different Availability Zones.


🔍 2.6 Save Connection Metadata

After creation we save the Writer endpoint, Master username, and Database name as we will use these values when connecting WordPress to the database.

🎥 Video Walkthrough

⚡Task 3: Create an Amazon ElastiCache for Memcached

In this task, we set up a Memcached caching layer using Amazon ElastiCache to enhance database performance. By caching frequently accessed data, ElastiCache helps reduce latency and lighten the load on the RDS database created in the previous step. ts user experience but also reduces unnecessary load on the RDS database.


3.1 Navigate to ElastiCache Console

  • We open the Amazon ElastiCache service via the AWS Management Console.

3.2 Create a Memcached Cluster

  • In the left navigation pane, we select Memcached caches and choose Create Memcached cache.

Cluster Info

  • Name: MyWPCache

Cluster Settings

  • Node type: cache.t3.micro (cost-effective and suitable for light workloads)

  • Number of nodes: 2 (to increase availability and distribute cache load)

Connectivity

  • Subnet group: cachesubnetgroup

  • Security Group:

    • We click Manage and select the existing security group ElastiCacheSecurityGroup

    • Confirm selection

  • We click NextNextCreate

A highly available Memcached cluster named MyWPCache is deployed. It now acts as a caching layer for the WordPress application.

🎥 Video Walkthrough


📂 Task 4: Create an Amazon EFS File System

In this task, we create a shared storage layer using Amazon Elastic File System (EFS). This NFS (Network File System)-based storage is accessible by multiple application servers across different Availability Zones, enabling high availability and scalability for the WordPress application. This ensures that multiple EC2 instances running the WordPress app can mount and share the same file system, which is essential for session data, media uploads, and other persistent storage needs.


4.1 Navigate to the Amazon EFS Console

  • We search for EFS in the AWS Management Console.

4.2 Create the File System

  • We click on Create file system, then choose Customize.

General Settings

  • Name: myWPEFS

  • Automatic backups: Disabled

  • Tags: Key: Name, Value: myWPEFS

Click Next.

Networking Access

  • VPC: LabVPC

Mount Targets

  • Availability Zone (a):

    • Subnet ID: AppSubnet1

    • Security Group: EFSMountTargetSecurityGroup (Remove default)

  • Availability Zone (b):

    • Subnet ID: AppSubnet2

    • Security Group: EFSMountTargetSecurityGroup (Remove default)

Click Next.

File System Policy

We skip configuration (not needed for this lab) and click Next

Review and Create

  • We review the configuration and click Create

An Amazon EFS file system named myWPEFS is created and the File system status changes to Available after a few minutes.

🎥 Video Walkthrough


🌐Task 5: Create an Application Load Balancer

In this task, we set up a public-facing Application Load Balancer (ALB) that distributes incoming traffic across EC2 instances hosting WordPress. This enhances fault tolerance, high availability, and performance.


🎯 Task 5.1: Navigate to the EC2 Console

We open the AWS Management Console and search for and select EC2.

🎯 Task 5.2: Create a Target Group

A Target Group is a set of resources (like EC2 instances or IPs) that an Application Load Balancer (ALB) routes traffic to. It enables load balancing, health checks, and routing based on listener rules.

Steps

  • In the left navigation pane, we choose Target Groups and then click on Create target group

Basic Configuration

  • Target type: Instances

  • Target group name: myWPTargetGroup

  • VPC: LabVPC

Health Check Settings

  • Health check path: /wp-login.php

  • Advanced health check settings:

    • Healthy threshold: 2

    • Unhealthy threshold: 10

    • Timeout: 50

    • Interval: 60

we click on Next, then Create target group

🎯 Task 5.3: Create an Application Load Balancer

Now, let's set up the ALB that will handle web traffic to your WordPress instances.

Steps

  • In the left navigation pane, we select Load Balancer and Choose Create Load Balancer

  • Under Application Load Balancer, we click Create

Basic Configuration

  • Load balancer name: myWPAppALB

Network Mapping

  • VPC: LabVPC

  • Subnets:

    • Availability Zone 1: PublicSubnet1

    • Availability Zone 2: PublicSubnet2

Security Groups

  • Remove the default group (click X)

  • Select AppInstanceSecurityGroup

Listeners and Routing

  • For HTTP:80, choose:

    • Target Group: myWPTargetGroup

We click on Create load balancer

📄 Final Steps

  • We click on View load balancer and wait until State = Active

  • We copy the DNS name to a text editor (you’ll use this to access WordPress later)

🎥 Video Walkthrough


🚀Task 6: Create a Launch Template using CloudFormation

In this task, we used an AWS CloudFormation template to automatically deploy a Launch Template for WordPress on EC2, integrated with Amazon Aurora and EFS. This approach ensures repeatable, automated, and scalable deployments.

🧭 Task 6.1: Navigate to the CloudFormation Console

  • From the AWS Management Console we search bar, type and select CloudFormation

🏗️ Task 6.2: Create the CloudFormation Stack

Steps

  1. We click on Create stack and choose With new resources (standard)

Specify Template

  • SWe select: Amazon S3 URL and paste the Task6TemplateUrl (which is provided in the lab instructions) and then click Next.

Specify Stack Details

  • Stack name: WPLaunchConfigStack

📥 Parameters (We fill in with values copied in previous tasks):

ParameterValue (Example)
DB Namemywpdatabase (from Task 2)
Database endpointmydbcluster.cluster-xxxxxx.rds.amazonaws.com (from Task 2)
Database User Nameadmin (from Task 2)
Database PasswordLabPassword (from lab info)
WordPress admin usernamewpadmin (default)
WordPress admin passwordLabPassword
WordPress admin emailyour-email@example.com
Instance Typet3.medium (default)
ALBDnsNamemyWPAppALB-xxxxxxxxxx.elb.amazonaws.com (from Task 5)
LatestAL2AmiId(leave default)
WPElasticFileSystemIDfs-xxxxxxxx (from Task 4)

✅ Ensure you're using the correct initial DB name, writer endpoint, and file system ID from previous tasks.

  • We click on Next

⚙️ Configure Stack Options

We leave all settings as default

  • We click on Next → Review and Submit.

🕒 Monitor Stack Creation

  • We will be redirected to the Stack Details page

  • Status will show as: CREATE_IN_PROGRESS

  • Periodically we click the Refresh button and wait for status to change to CREATE_COMPLETE

⏳ This may take around 5 minutes

🔍Task 6.3: View Created Resources

We next navigate to the Resources tab in our stack. We can now see thew following:-

  • Launch Template

  • IAM Roles

  • Security Groups

  • Instance Profile

  • Auto Scaling Group

  • EC2 Instance with WordPress pre-configured

🎥 Video Walkthrough


🛠️ Task 7: Create Application Servers with Auto Scaling and Load Balancing

In this task, we bring our WordPress application to life by deploying EC2 instances in an Auto Scaling Group (ASG) behind an Application Load Balancer (ALB). This ensures high availability, automatic scaling, and fault tolerance.

🚀Task 7.1: Creating an Auto Scaling Group

Step-by-step Configuration:

  1. Navigate to EC2 Dashboard
    From the AWS Console, search for EC2.

  2. In the left pane, under Auto Scaling, click Auto Scaling Groups.

  3. Click Create Auto Scaling group

⚙️ Configure Group Settings:

  • Auto Scaling group name: WP-ASG

  • Launch Template: Choose LabLaunchTemplate (created via CloudFormation in Task 6)

  • Click Next

🌐 Configure Network:

  • VPC: Select LabVPC

  • Subnets: Choose both AppSubnet1 and AppSubnet2

  • Click Next

⚖️ Attach Load Balancer:

  • We enable Attach to an existing load balancer

  • We choose: myWPTargetGroup | HTTP

  • We enable Elastic Load Balancing health checks

  • We leave grace period at 300 seconds and click Next

📏 Configure Group Size & Scaling Policy:

  • Desired capacity: 2

  • Minimum capacity: 2

  • Maximum capacity: 4

  • We enable Target tracking scaling policy

  • We enable CloudWatch group metrics collection and click on Next

🏷️ Add Tags:

  • We add a tag:

    • Key: Name

    • Value: wp-ha-app

and click on Next, then Create Auto Scaling group

Auto Scaling group WP-ASG with 1 scaling policy and CloudWatch metrics collection enabled

Verifying Auto Scaling Activity

  1. In Auto Scaling Groups, we click on WP-ASG

  2. We check the Activity tab:

    • Status should progress from PreInServiceSuccessful
  3. In Instance management tab:

    • We should see 2 EC2 instances in InService state, and

    • Health Status will be Healthy

🕒 This can take a few minutes. Use the refresh button 🔄 if needed.

🔍 Task 7.2: Verify Target Group Health

  1. We then navigate to Target Groups and click myWPTargetGroup

  2. In the Targets tab, we must ensure that both EC2 instances are showing as ‘Healthy’

⚠️ It might take up to 5 minutes for instances to pass the health check.

🌐 Task 7.3: Login to WordPress

  1. Next we go to Load Balancers in the EC2 Dashboard and copy the DNS name of myWPAppALB

  2. We append /wp-login.php at the end of the URL, for example:

bashCopyEdithttp://myWPAppALB-xxxxxx.elb.amazonaws.com/wp-login.php
  1. We paste the URL in a new browser tab

📝 WordPress Login:

  • Username: wpadmin

  • Password: LabPassword (from lab instructions)

and click on Log in

🎉 Now we can see the WordPress dashboard — fully deployed, scalable, and highly available!

🎥 Video Walkthrough


🧪Task 8: Chaos Testing with AWS Fault Injection Simulator

To validate that our WordPress application is truly highly available, we’ll conduct a chaos engineering experiment using AWS Fault Injection Simulator (FIS). This simulates real-world failure scenarios—in this case, an Availability Zone (AZ) outage—and ensures our architecture can self-heal.


💡 Assumption to Test

If one of the AZs experiences an outage, the application must continue to serve traffic.
The Auto Scaling Group (ASG) should launch new instances in healthy AZs, and the Load Balancer should reroute traffic automatically.

🚀 Task 8.1: Open AWS Fault Injection Simulator

  1. We go to the AWS Console and in the top search bar, type AWS FIS and select it.

🧭 Task 8.2: Create Chaos Test Scenario

📝 Template Setup

  • We click on Create experiment template (from Create experiment from scenario dropdown).

  • Description: Terminate instances in an AZ to simulate AZ outage

  • Name (optional): TerminateInstancesinAZ

  • Account targeting: Select This AWS account

  • We click on Next

🛠️ Define Chaos Action

  • Under Actions, we click + Add action

    • Name: TerminateInstances

    • Action type: EC2aws:ec2:terminate-instances

    • Click Save

🎯 Define Targets

  • In Targets, we click the vertical ellipsis (⋮) → Edit

  • Target method: Resource tags, filters and parameters

We set filters to target instances:

  1. Resource Tag

    • Key: Name

    • Value: wp-ha-app

  2. Resource Filter #1

    • Attribute path: Placement.AvailabilityZone

    • Value: us-west-2a (or your LabRegion + a)

  3. Resource Filter #2

  • We click SaveNext

🔐 Configure IAM Role

  • We select Use an existing IAM role and choose the FIS IAM role: xxxx-FISRole-xxxx

  • Click Next

⚙️ Optional Settings

  • We leave as default → Click Next

✅ Review & Create

  • We review our experiment setup.

  • To confirm creation without a stop condition, we type: create

  • And then Click Create experiment template

We have successfully created experiment template TerminateInstancesinAZ (ID: EXTxxxxxx)

▶️ Task 8.3: Run the Experiment

  1. In the FIS console, we go to Experiment templates

  2. We click the ID of the template that we just created

  3. We click Start experiment and to confirm, we type: start

  4. We then click Start experiment

The Experiment EXPUxxxxxx starts successfully and the status will change to Completed after execution.

🔎 Task 8.4: Observe the Chaos

🖥️ In the WordPress Tab

  • We refresh the /wp-login.php page every few seconds.

Expected Result:
The WordPress site remains available throughout the test. No visible downtime.

📊 In the AWS Console

  1. We go to EC2 → Auto Scaling Groups and click on WP-ASG

  2. Then we navigate to the Activity tab

Expected Events:

  • One instance in us-west-2a is terminated

  • ASG launches a new instance in a different AZ

  • Health checks detect and remove the unhealthy instance

  • Desired capacity is restored automatically

We just ran a chaos test using AWS Fault Injection Simulator! The system:

✅ Detected and replaced failed instances
✅ Maintained application availability
✅ Proved that your architecture can handle AZ outages

This validates that our WordPress deployment is resilient, self-healing, and production-ready.

🎥 Video Walkthrough


🌟Key Takeaways & Learnings from the Lab

  • Understood how to design a secure, multi-AZ VPC with public and private subnets, ensuring proper traffic flow using NAT and internet gateways.

  • Set up EC2 instances using Launch Templates and managed them with an Auto Scaling Group for high availability.

  • Deployed an Application Load Balancer to distribute traffic and learned to configure health checks and target groups.

  • Attached Amazon EFS to multiple EC2 instances for shared storage, ideal for WordPress media content.

  • Used Amazon RDS (Aurora) as a managed, multi-AZ backend database, with private subnet isolation.

  • Integrated Amazon ElastiCache (Memcached) for faster content delivery and reduced DB load.

  • Practiced AWS security fundamentals using Security Groups and NACLs to enforce least privilege.

  • Used AWS Fault Injection Simulator (FIS) to test failure scenarios and validate infrastructure resilience.

  • Leveraged CloudFormation to automate the entire infrastructure deployment with consistency and speed.

🚀Conclusion

This lab was a fantastic opportunity to get hands-on with a wide range of AWS services—like EC2, RDS, ElastiCache, EFS, and Auto Scaling—to deploy a resilient and scalable WordPress application. It helped me understand how each component fits into a real-world architecture and highlighted the value of automation, caching, and high availability.

If you're someone looking to build practical cloud skills, I highly recommend giving this lab a try yourself on AWS Skill Builder. There's no better way to learn than by doing! 💻☁️

Endcard

If you find this blog insightful interesting and worth following, don’t forget to give it a like!

📌 Click that Follow button to stay updated with my latest posts and never miss exciting content.

🔗 Follow me on LinkedIn → rupak1chakraborty

🔥 Stay tuned for the first lab experience—coming soon!

0
Subscribe to my newsletter

Read articles from Rupak Chakraborty directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rupak Chakraborty
Rupak Chakraborty