First resilience architecture in AWS

I‘m super happy, I’ve create today my first resilience architecture in AWS. It was a really awesome experience to implement that solution. I’ve used the following AWS services:

  • AWS VPC
  • AWS Security Groups
  • AWS Route Tables
  • AWS Internet Gateway
  • AWS NAT Gateway
  • AWS EC2
  • AWS EFS
  • AWS RDS
  • AWS Load Balancer
  • AWS ElasticIP

The main idea is to build a resilience WordPress architecture, using EC2 instances and a managed database at the backend.

Here is the architecture design of my solution:

The hardest point here is the network design because I want to archive a highly secure environment so I need one AWS VPC with three subnets (in each AWS DC Zone) like the following:

VPC:

Subnets:

I’ve split those subnet into:

  • Internet facing subnet, where I place my reverse proxies, NAT Gateways, Firewall and more if needed.
  • An app subnet, where the application frontend will be placed. In my case the WordPress webserver
  • A backend subnet which contains my WordPress Database (AWS RDS) and the WordPress website content

In my case the AWS security groups are the best choice

Security group “ExternalWeb”.

That security group allows inbound 80 and 443 access and is bound to the AWS LoadBalancer:

Security group “InternalWeb”.

That security Group allows inbound 80 and 443 access only from the ExternalWeb (Loadbalancer) security group.

Security group “InternalEFS”.

That security group allows any inbound access only from the InternalEFS security group.

But why?

The reason for that is the EFS drive. I’ve stored the WordPress content to that shared storage. Under the hood, each webserver can have an access to the content, but only the webserver!

Security group “InternalData”.

That security group allows any inbound access only from the InternalWeb security group.


Next, I’ve deployed an Internet gateway, used for the external communication to the AWS LoadBalancer. Also used by the NATGateway.


I’ve also create a NATGateway, because my EC2 instances communicate to the Internet. In my case, I’ve build a resilience architecture, which means, I need two NATGateways in different AWS DC zones:

Of course, each NATGateway need his own AWS ElasticIP:


Great, at the moment both gateways are not used, because, there isn’t an AWS route table in place. To fix that issue, I’ve create two route tables:

  • RT-APP-Subnet
  • RT-Public-Subnet

RT-APP-Subnet is bound to the subnets:

and the route configuration:

Important here, the default route 0.0.0.0/0 had the NATgateway as target.

RT-Public-Subnet is bound to the subnets:

and the route configuration:

Important here, the default route 0.0.0.0/0 had the internet gateway as target.


My backend environment contains an AWS RDS managed service based on MySQL. I’ve create a subnet group first to define the internal subnet where the AWS RDS instances should be bound. In my case the subnet

  • Data-AZ-A
  • Data-AZ-B

Next, I’ve created an AWS RDS instance and bound the AWS security group “InternalData”:


Now I can create my shared EFS store. Important part here, I’ve bound the EFS store to the subnets:

  • Data-AZ-A
  • Data-AZ-B

and the AWS security group:

  • InternalEFS

The middle tier includes two AWS EC2 instances bound to the subnet:

  • App-AZ-A
  • App-AZ-B

and the AWS Security Groups:

  • InternalEFS
  • InternalWeb

Okay, not really impressive, but I have one more 🙂 during the installation, I install all required components for WordPress and also mount the EFS volume! Here is the User Data code:

#!/bin/bash
yum update -y
yum install -y httpd mysql php-mysqlnd
amazon-linux-extras install -y php7.2
systemctl start httpd
systemctl enable httpd
echo "fs-dc8f5a84.efs.eu-central-1.amazonaws.com:/ /var/www/html nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2" >>/etc/fstab
mount -a

Okay, the last component is the AWS LoadBalancer. It’s a simple HTTP/HTTPS loadbalancer, bound to the subnet:

  • Public-AZ-A
  • Public-AZ-B

and the AWS security group:

  • ExternalWeb

The LoadBalancer have a port 80 listener (not for productive environment) configured. For the target, I’ve created an AWS target group with both EC2 instances:


It was a really hard work to implement that solution, but I think it’s an AWS well architecture design. In one of my next steps I will show you how you can implement the same solution with the same security and resilience capabilities in Azure.