Designing a Highly Available Web App Infrastructure

This activity starts with an app running on a single EC2 instance in a single availability zone. Then I make it highly available by cloning it and deploying it in an Auto Scaling group behind an Elastic Load Balancer that spans two availability zones.

  • Create an image of an existing Amazon EC2 instance and use it to launch new instances.
  • Expand an Amazon VPC to additional Availability Zones.
  • Create VPC Subnets and Route Tables.
  • Create an AWS NAT Gateway.
  • Create a Load Balancer.
  • Create an Auto Scaling group.

I have a starting state VPC in which I build out a reference app server. Then I build up the primitives towards high availability.

Setting Up  The  Starting State VPC

The VPC will have a CIDR block of giving us an IPv4 range between and (Not all are usable as AWS reserves some)



The diagram below highlights the starting state of the VPC.


Deploying A Web App on EC2

Build a VPC and deploy a web app onto an EC2 instance using a user data script to configure the server and application code.


  • Create IAM role with EC2 as a trusted entity with full access to S3 and DynamoDB.
  • Set up an S3 bucket to serve images and static content and for for the web app to copy files to.
  • Setup a DynamoDB table where the web app will write records to.
  • Setup a VPC with a CIDR block, public subnet, internet gateway and a public route table allowing egress to the IGW and associate the route table with the public subnet.
  • Launch an EC2 instance in the public subnet with a public IP and the IAM role, tags, and https security group.
    • Configure a user-data shell script to prep the server and application code:
      • install httpd24 and php56
      • Download, unzip and deploy the web app and source files
      • Download and install the AWS SDK for PHP
      • Determine current region fetching the meta-data/placement/availability zone and instantiate a REGION variable
      • Invoke AWS s3api to list buckets and instantiate a BUCKET variable
      • Copy  jquery and image source files to new S3 buckets and set public read ACLs using the BUCKET and REGION vars
      • Inject the BUCKET and REGION variables into the PHP code using sed
      • Populate DynamoDB tables with data from JSON source files
      • Ensure httpd is configured to start automatically
      • Start the httpd daemon
# Install Apache Web Server and PHP
yum remove -y httpd php
yum install -y httpd24 php56
# Download Lab files
wget https://us-west-2-aws-training.s3.amazonaws.com/awsu-ilt/AWS-100-ARC/v5.2/lab-1-webapp/scripts/lab1src.zip
unzip lab1src.zip -d /tmp/
mv /tmp/lab1src/*.php /var/www/html/
# Download and install the AWS SDK for PHP
wget https://github.com/aws/aws-sdk-php/releases/download/3.15.9/aws.zip
unzip aws -d /var/www/html
# Determine Region
AZ=`curl --silent`
# Copy files to Amazon S3 bucket with name webapp-*
BUCKET=`aws s3api list-buckets --query "Buckets[?starts_with(Name, 'webapp-')].Name | [0]" --output text`
aws s3 cp /tmp/lab1src/jquery/ s3://$BUCKET/jquery/ --recursive --acl public-read --region $REGION
aws s3 cp /tmp/lab1src/images/ s3://$BUCKET/images/ --recursive --acl public-read --region $REGION
aws s3 ls s3://$BUCKET/ --region $REGION --recursive
# Configure Region and Bucket to use
sed -i "2s/%region%/$REGION/g" /var/www/html/*.php
sed -i "3s/%bucket%/$BUCKET/g" /var/www/html/*.php
# Copy data into DynamoDB table
aws dynamodb batch-write-item --request-items file:///tmp/lab1src/scripts/services1.json --region $REGION
aws dynamodb batch-write-item --request-items file:///tmp/lab1src/scripts/services2.json --region $REGION
aws dynamodb batch-write-item --request-items file:///tmp/lab1src/scripts/services3.json --region $REGION
# Turn on web server
chkconfig httpd on
service httpd start


Resulting Architecture