logo

When I started planning on writing a blog as part of emparting technology information on the wider world I started to think what components would go in to it.

If you dont mind hosting a Virtual Machine with WordPress then it is really quite simple as AWS Marketplace has a WordPress Virtual Machine that can be consumed directly. And for simple use cases that may be sufficient since it gives you a Linux VM with WordPress and a MariaDB instance installed together.

But I dont want to manage and update virtual machines and I also want to ensure High Availability at every component I possibly could so I began thinking of the serverless architecture approach and after a few hours of thinking I came up with the below pattern diagram

wordpress serverless architecture

And there is a really good article on running WordPress in Fargate using Elastic File Services (EFS) Storage as persistent storage. EFS is a great service because it can be attached to multiple linux based instances or containers simultaneously so it works great as shared storage at scale. A link to this blog article is here: AWS Blog – Running WordPress On Amazon ECS With Fargate

The only problem I found with that approach was that it had some manual handling and there was separate steps between building the Infrastructure and configuring the Task Definition for Fargate. So I went to AWS CDK which is a programmatic mechanism to create Cloudformation templates using several common programming languages including Typescript and Python. I tend to use Typescript although I also write code in Python.

I found the development process interesting because I had not really built Fargate infrastructure before so I became very familiar with how Task Definitions and Container Definitions are composed in CDK but lets start at the top. I wont go in too deep to the Code as I will include a link to the Github repository where I host it at the bottom of this post.

Requirements:

  •  Familiarity with AWS Infrastructure
  • Familiarity with AWS CDK
  • A domain hosted in AWS Route53 (Optional but needed if you want to automate the Certificate management)
  • Access to an AWS Environment. AWS Offer a free tier for new users which provides a substantial amount of hours per month on multiple resources and can help practicing this in a low cost environment.

I used CDK 2.0 to write this code (it is not as of this writing Generally Available but the Developer preview at 2.0 RC20 is in my view stable enough for all the components I needed). If you have written code in CDK 1.0 and want to know how to switch over to 2.0 it is incredibly simple (I moved an entire app of a dozen or more modules to CDK 2.0 within an hour or two) and I suggest you read this page.

Setting up a VPC

If you have an existing environment you may already have a VPC but the code repo I created for this pattern builds one with a standard architecture across 2 availability zones.

 

Simple VPC Architecture

I think the best architecture approach from a security perspective is a multi tiered approach where there is separation between components in the Network architecture and then Network Access Control Lists (NACLs) can be used to ensure only the appropriate traffic flows between subnets.

Here is a 3 Tier Approach:

  1. Public Subnets host NAT Gateways and Load Balancers
  2. ECS Subnets host Fargate Clusters and VPC Endpoints
  3. Data Subnets host Aurora Serverless Cluster and EFS Mountpoints

Note: My preferred architecture would be to use a Privatelink VPC Interface endpoint for Container Registry Access but at the moment that unfortunately is not supported by AWS for Containers hosted in AWS ECR Public Gallery. I have raised with AWS to hopefully add support in future as a Privatelink connection is less expensive to operate than a NAT Gateway.

 There really isn’t much to building a VPC in AWS with CD. You define the Cidr (I use a Variable in this case to pass in the value), number of AZs and a split of the available IPs across subnet tiers.

[et_pb_dmb_code_snippet code=”Ly8gQ3JlYXRlIFZQQyAoLzI0KQogICAgdnBjPW5ldyBlYzIuVnBjKHRoaXMsIndvcmRwcmVzc1ZwYyIsewogICAgICBjaWRyOiB2cGNDaWRyLAogICAgICBtYXhBenM6IDIsCiAgICAgCiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb246IFsKICAgICAgICB7CiAgICAgICAgICBuYW1lOiAnQXBwbGljYXRpb24nLAogICAgICAgICAgY2lkck1hc2s6IDI2LAogICAgICAgICAgc3VibmV0VHlwZTogZWMyLlN1Ym5ldFR5cGUuUFJJVkFURSwgLy9lbmFibGVkIFByaXZhdGUgYWNjZXNzIGR1ZSB0byBFQ1IgcmVxdWlyZW1lbnQKICAvLyAgICAgICAgc3VibmV0VHlwZTogZWMyLlN1Ym5ldFR5cGUuSVNPTEFURUQsCiAgICAgICAgICAKICAgICAgICAgIAogICAgICAgICAgfSwKICAgIAogICAgICB7CiAgICAgIG5hbWU6ICdQdWJsaWMnLAogICAgICBjaWRyTWFzazogMjcsCiAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBVQkxJQwogICAgICAKICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICBuYW1lOiAnRGF0YScsCiAgICAgICAgICBjaWRyTWFzazogMjgsCiAgICAgICAgICBzdWJuZXRUeXBlOiBlYzIuU3VibmV0VHlwZS5JU09MQVRFRAogICAgICAgICAgCiAgICAgICAgICAKICAgICAgICB9LAogICAgICAKICAgICAgXQogICAgICAKICAgICAgfSk7Cg==” _builder_version=”4.10.7″ _module_preset=”default” global_colors_info=”{}”]Ly8gQ3JlYXRlIFZQQyAoLzI0KQogICAgdnBjPW5ldyBlYzIuVnBjKHRoaXMsIndvcmRwcmVzc1ZwYyIsewogICAgICBjaWRyOiB2cGNDaWRyLAogICAgICBtYXhBenM6IDIsCiAgICAgCiAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb246IFsKICAgICAgICB7CiAgICAgICAgICBuYW1lOiAnQXBwbGljYXRpb24nLAogICAgICAgICAgY2lkck1hc2s6IDI2LAogICAgICAgICAgc3VibmV0VHlwZTogZWMyLlN1Ym5ldFR5cGUuUFJJVkFURSwgLy9lbmFibGVkIFByaXZhdGUgYWNjZXNzIGR1ZSB0byBFQ1IgcmVxdWlyZW1lbnQKICAvLyAgICAgICAgc3VibmV0VHlwZTogZWMyLlN1Ym5ldFR5cGUuSVNPTEFURUQsCiAgICAgICAgICAKICAgICAgICAgIAogICAgICAgICAgfSwKICAgIAogICAgICB7CiAgICAgIG5hbWU6ICdQdWJsaWMnLAogICAgICBjaWRyTWFzazogMjcsCiAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBVQkxJQwogICAgICAKICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICBuYW1lOiAnRGF0YScsCiAgICAgICAgICBjaWRyTWFzazogMjgsCiAgICAgICAgICBzdWJuZXRUeXBlOiBlYzIuU3VibmV0VHlwZS5JU09MQVRFRAogICAgICAgICAgCiAgICAgICAgICAKICAgICAgICB9LAogICAgICAKICAgICAgXQogICAgICAKICAgICAgfSk7Cg==[/et_pb_dmb_code_snippet]

But VPC and Network Architecture deployment is not why we are here. Its pretty  well written all over the blogosphere.

It is what you do with the network architecture in this pattern I find the most interesting.

 

Load Balancer, Certificate and Route 53

As I said in the requirements Route 53 is optional but if you have your Public Zone hosted in Route 53 you can fully automate the creation of and management of the Load Balancer Alias and the SSL Certificate for your page. Amazon have a great certificate service called Certificate Manager which provides free public SSL certificates for use with AWS Services. It doesnt support AWS EC2 Web Servers (which will require a public 3rd party trusted Certificate) but since we are not using any Servers in our infrastructure ACM will suit us perfectly.

If you dont have a hosted Zone in Route 53 then you need to have a certificate created and validated in advance before you can create a HTTPS listener through CDK. In the next update to my CDK app I will be adding support for passing in an existing ACM Certificate ARN for use in the HTTPS listener.

The Following Code Snippet builds all of this together and creates what may be quite a complicated piece of code in Cloudformation down. It also allows for the creation of a HTTPS Listener (if Route 53 Hosted zone is provided), creates and validates the certificate and creates a target group which will be consumed later by Fargate.

[et_pb_dmb_code_snippet code=”CiAgICBjb25zdCBsYj1uZXcgZWxidjIuQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIodGhpcywgJ1dvcmRwcmVzc0xCJywgewogICAgICB2cGMsCiAgICAgIGludGVybmV0RmFjaW5nOiB0cnVlCiAgICB9KTsgIAoKICAgIAoKICAgIGNvbnN0IHRhcmdldEdyb3VwSHR0cCA9IG5ldyBlbGJ2Mi5BcHBsaWNhdGlvblRhcmdldEdyb3VwKAogICAgICB0aGlzLAogICAgICAid29yZHByZXNzIiwKICAgICAgewogICAgICAgIHBvcnQ6IDgwLAogICAgICAgIHZwYywKICAgICAgICBwcm90b2NvbDogZWxidjIuQXBwbGljYXRpb25Qcm90b2NvbC5IVFRQLAogICAgICAgIHRhcmdldFR5cGU6IGVsYnYyLlRhcmdldFR5cGUuSVAsCiAgICAgIH0KICAgICk7CiAgICAKICAgIAogICAgICAgIHRhcmdldEdyb3VwSHR0cC5jb25maWd1cmVIZWFsdGhDaGVjayh7CiAgICAgICAgICBwYXRoOiAiLyIsCiAgICAgICAgICBwcm90b2NvbDogZWxidjIuUHJvdG9jb2wuSFRUUCwKICAgICAgICB9KTsKICAgICAgICAKCiAgICBsZXQgbGlzdGVuZXI6ZWxidjIuQXBwbGljYXRpb25MaXN0ZW5lcgogICAgCiAgICBpZiAocHJvcHM/LnJvdXRlNTNkb21haW4gIT0gdW5kZWZpbmVkKSB7CiAgICAgIGNvbnN0IHpvbmUgPSByb3V0ZTUzLkhvc3RlZFpvbmUuZnJvbUxvb2t1cCh0aGlzLCBgYWNtcm91dGU1M3pvbmVgLCB7CiAgICAgICAgZG9tYWluTmFtZTogcHJvcHM/LnJvdXRlNTNkb21haW4sCiAgICAgIH0pOwogICAgCiAgICAgIGxldCBkb21haW5uYW1lPXByb3BzLndvcmRwcmVzc0ZRRE4hOwogICAgICAvLyBTU0wgY2VydGlmaWNhdGUgZm9yIHRoZSBkb21haW4gCiAgICAgIGNvbnN0IGNlcnQgPSBuZXcgY2VydGlmaWNhdGVtYW5hZ2VyLkNlcnRpZmljYXRlKHRoaXMsImNlcnRpZmljYXRlIiwKICAgICAgICB7CiAgICAgICAgICBkb21haW5OYW1lOiBkb21haW5uYW1lLAogICAgICAgICAgdmFsaWRhdGlvbjogY2VydGlmaWNhdGVtYW5hZ2VyLkNlcnRpZmljYXRlVmFsaWRhdGlvbi5mcm9tRG5zKHpvbmUpLAogICAgICAgICAgc3ViamVjdEFsdGVybmF0aXZlTmFtZXM6IFtgd3d3LiR7ZG9tYWlubmFtZX1gXQogICAgICAgICAgCiAgICAgICAgfSk7CgogICAgICAgIAogICAgICAgIC8vIG9ubHkgYWxsb3cgSFRUUFMgY29ubmVjdGlvbnMgCiAgICAgICAgbGlzdGVuZXIgPSBsYi5hZGRMaXN0ZW5lcignSFRUUFNMaXN0ZW5lcicsIHsKICAgICAgICAgIG9wZW46IHRydWUsCiAgICAgICAgICBwb3J0OiA0NDMsCiAgICAgICAgICBjZXJ0aWZpY2F0ZXM6IFtjZXJ0XSwKICAgICAgICAgIGRlZmF1bHRUYXJnZXRHcm91cHM6IFt0YXJnZXRHcm91cEh0dHBdCiAgCiAgICAgICB9KTsKCiAgICAgICBsYi5hZGRSZWRpcmVjdCh7CiAgICAgICAgc291cmNlUHJvdG9jb2w6IGVsYnYyLkFwcGxpY2F0aW9uUHJvdG9jb2wuSFRUUCwKICAgICAgICBzb3VyY2VQb3J0OiA4MCwKICAgICAgICB0YXJnZXRQcm90b2NvbDogZWxidjIuQXBwbGljYXRpb25Qcm90b2NvbC5IVFRQUywKICAgICAgICB0YXJnZXRQb3J0OiA0NDMsCiAgICAgIH0pOwoKICAgICAgLy9DcmVhdGUgUm91dGUgNTMgQWxpYXMgcmVjb3JkIGZvciBSb3V0ZSA1MyBab25lIHJvb3QgYW5kIENOQU1FIGZvciBXV1cKICAgICAgaWYgKHByb3BzLlNldFJvdXRlNTNSb290VVJMID09PSB0cnVlKSB7CiAgICAgICAgbmV3IHJvdXRlNTMuQVJlY29yZCh0aGlzLCAnQWxpYXNSZWNvcmQnLCB7CiAgICAgICAgICB6b25lLAogICAgICAgICAgdGFyZ2V0OiByb3V0ZTUzLlJlY29yZFRhcmdldC5mcm9tQWxpYXMobmV3IHJvdXRlNTNfdGFyZ2V0cy5Mb2FkQmFsYW5jZXJUYXJnZXQobGIpKSwKICAgICAgICAgIAogICAgICAgIH0pOwoKICAgICAgICBuZXcgcm91dGU1My5DbmFtZVJlY29yZCh0aGlzLCAnV1dXQ05BTUUnLCB7CiAgICAgICAgICByZWNvcmROYW1lOiAnd3d3JywKICAgICAgICAgIHpvbmUsCiAgICAgICAgICBkb21haW5OYW1lOiB6b25lLnpvbmVOYW1lCiAgICAgICAgfSk7CgogICAgICB9CiAgICB9IGVsc2UgewoKICAgICAgLy9IVFRQIE9ubHkgbGlzdGVuZXIgd2hlbiBubyBjZXJ0aWZpY2F0ZSBpcyBwcm92aWRlZAogICAgICBsaXN0ZW5lciA9IGxiLmFkZExpc3RlbmVyKCdIVFRQTGlzdGVuZXInLCB7CiAgICAgICAgcG9ydDogODAsCiAgICAgICAgb3BlbjogdHJ1ZSwKICAgICAgICBkZWZhdWx0VGFyZ2V0R3JvdXBzOiBbdGFyZ2V0R3JvdXBIdHRwXQogICAgICB9KTsKCiAgICB9Cg==” _builder_version=”4.10.7″ _module_preset=”default” global_colors_info=”{}”]CiAgICBjb25zdCBsYj1uZXcgZWxidjIuQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIodGhpcywgJ1dvcmRwcmVzc0xCJywgewogICAgICB2cGMsCiAgICAgIGludGVybmV0RmFjaW5nOiB0cnVlCiAgICB9KTsgIAoKICAgIAoKICAgIGNvbnN0IHRhcmdldEdyb3VwSHR0cCA9IG5ldyBlbGJ2Mi5BcHBsaWNhdGlvblRhcmdldEdyb3VwKAogICAgICB0aGlzLAogICAgICAid29yZHByZXNzIiwKICAgICAgewogICAgICAgIHBvcnQ6IDgwLAogICAgICAgIHZwYywKICAgICAgICBwcm90b2NvbDogZWxidjIuQXBwbGljYXRpb25Qcm90b2NvbC5IVFRQLAogICAgICAgIHRhcmdldFR5cGU6IGVsYnYyLlRhcmdldFR5cGUuSVAsCiAgICAgIH0KICAgICk7CiAgICAKICAgIAogICAgICAgIHRhcmdldEdyb3VwSHR0cC5jb25maWd1cmVIZWFsdGhDaGVjayh7CiAgICAgICAgICBwYXRoOiAiLyIsCiAgICAgICAgICBwcm90b2NvbDogZWxidjIuUHJvdG9jb2wuSFRUUCwKICAgICAgICB9KTsKICAgICAgICAKCiAgICBsZXQgbGlzdGVuZXI6ZWxidjIuQXBwbGljYXRpb25MaXN0ZW5lcgogICAgCiAgICBpZiAocHJvcHM/LnJvdXRlNTNkb21haW4gIT0gdW5kZWZpbmVkKSB7CiAgICAgIGNvbnN0IHpvbmUgPSByb3V0ZTUzLkhvc3RlZFpvbmUuZnJvbUxvb2t1cCh0aGlzLCBgYWNtcm91dGU1M3pvbmVgLCB7CiAgICAgICAgZG9tYWluTmFtZTogcHJvcHM/LnJvdXRlNTNkb21haW4sCiAgICAgIH0pOwogICAgCiAgICAgIGxldCBkb21haW5uYW1lPXByb3BzLndvcmRwcmVzc0ZRRE4hOwogICAgICAvLyBTU0wgY2VydGlmaWNhdGUgZm9yIHRoZSBkb21haW4gCiAgICAgIGNvbnN0IGNlcnQgPSBuZXcgY2VydGlmaWNhdGVtYW5hZ2VyLkNlcnRpZmljYXRlKHRoaXMsImNlcnRpZmljYXRlIiwKICAgICAgICB7CiAgICAgICAgICBkb21haW5OYW1lOiBkb21haW5uYW1lLAogICAgICAgICAgdmFsaWRhdGlvbjogY2VydGlmaWNhdGVtYW5hZ2VyLkNlcnRpZmljYXRlVmFsaWRhdGlvbi5mcm9tRG5zKHpvbmUpLAogICAgICAgICAgc3ViamVjdEFsdGVybmF0aXZlTmFtZXM6IFtgd3d3LiR7ZG9tYWlubmFtZX1gXQogICAgICAgICAgCiAgICAgICAgfSk7CgogICAgICAgIAogICAgICAgIC8vIG9ubHkgYWxsb3cgSFRUUFMgY29ubmVjdGlvbnMgCiAgICAgICAgbGlzdGVuZXIgPSBsYi5hZGRMaXN0ZW5lcignSFRUUFNMaXN0ZW5lcicsIHsKICAgICAgICAgIG9wZW46IHRydWUsCiAgICAgICAgICBwb3J0OiA0NDMsCiAgICAgICAgICBjZXJ0aWZpY2F0ZXM6IFtjZXJ0XSwKICAgICAgICAgIGRlZmF1bHRUYXJnZXRHcm91cHM6IFt0YXJnZXRHcm91cEh0dHBdCiAgCiAgICAgICB9KTsKCiAgICAgICBsYi5hZGRSZWRpcmVjdCh7CiAgICAgICAgc291cmNlUHJvdG9jb2w6IGVsYnYyLkFwcGxpY2F0aW9uUHJvdG9jb2wuSFRUUCwKICAgICAgICBzb3VyY2VQb3J0OiA4MCwKICAgICAgICB0YXJnZXRQcm90b2NvbDogZWxidjIuQXBwbGljYXRpb25Qcm90b2NvbC5IVFRQUywKICAgICAgICB0YXJnZXRQb3J0OiA0NDMsCiAgICAgIH0pOwoKICAgICAgLy9DcmVhdGUgUm91dGUgNTMgQWxpYXMgcmVjb3JkIGZvciBSb3V0ZSA1MyBab25lIHJvb3QgYW5kIENOQU1FIGZvciBXV1cKICAgICAgaWYgKHByb3BzLlNldFJvdXRlNTNSb290VVJMID09PSB0cnVlKSB7CiAgICAgICAgbmV3IHJvdXRlNTMuQVJlY29yZCh0aGlzLCAnQWxpYXNSZWNvcmQnLCB7CiAgICAgICAgICB6b25lLAogICAgICAgICAgdGFyZ2V0OiByb3V0ZTUzLlJlY29yZFRhcmdldC5mcm9tQWxpYXMobmV3IHJvdXRlNTNfdGFyZ2V0cy5Mb2FkQmFsYW5jZXJUYXJnZXQobGIpKSwKICAgICAgICAgIAogICAgICAgIH0pOwoKICAgICAgICBuZXcgcm91dGU1My5DbmFtZVJlY29yZCh0aGlzLCAnV1dXQ05BTUUnLCB7CiAgICAgICAgICByZWNvcmROYW1lOiAnd3d3JywKICAgICAgICAgIHpvbmUsCiAgICAgICAgICBkb21haW5OYW1lOiB6b25lLnpvbmVOYW1lCiAgICAgICAgfSk7CgogICAgICB9CiAgICB9IGVsc2UgewoKICAgICAgLy9IVFRQIE9ubHkgbGlzdGVuZXIgd2hlbiBubyBjZXJ0aWZpY2F0ZSBpcyBwcm92aWRlZAogICAgICBsaXN0ZW5lciA9IGxiLmFkZExpc3RlbmVyKCdIVFRQTGlzdGVuZXInLCB7CiAgICAgICAgcG9ydDogODAsCiAgICAgICAgb3BlbjogdHJ1ZSwKICAgICAgICBkZWZhdWx0VGFyZ2V0R3JvdXBzOiBbdGFyZ2V0R3JvdXBIdHRwXQogICAgICB9KTsKCiAgICB9Cg==[/et_pb_dmb_code_snippet]

Assuming Route53 and ACM are used the above snipped results in an ACM Certificate, HTTP and HTTPS Load Balancer (HTTP Redirection enabled) and a CNAME and Alias record created for Route 53 pointing to the Load Balancer.

If Route 53 Hosted Zone is not used then a load balancer with a HTTP Listener is created.

Storage and Databases

Going completely server less means requiring a persistent storage mechanism that can survive beyond the lifecycle of the container. With Fargate that used to be difficult but in 2020 AWS brought its very good server less storage solution to Fargate. With EFS Support added you can mount an EFS storage point in one or more Fargate Containers simultaneously allowing for persistent storage that is consistent within a scalable container environment.

Setting up an EFS File System in CDK is a 3 step approach. First you create the volume with mount points, then you create an access point (for defining permissions and allowing the container to access it) and then you create mount points and finally you allow connectivity to the EFS Endpoint (Security Groups) as well as define IAM permissions in the Task Role.

We are using Public ECR Gallery Bitnami container for WordPress which uses /bitnami/wordpress as mount so this container mounts /bitnami onto the EFS storage and the subfolder wordpress is therefore persistent.

[et_pb_dmb_code_snippet code=”Ly8xLiBDcmVhdGUgRmlsZSBTeXN0ZW0KICAgIGNvbnN0IGVmc3ZvbHVtZT1uZXcgZWZzLkZpbGVTeXN0ZW0odGhpcywgJ1dvcmRQcmVzc0Vmc0ZpbGVTeXN0ZW0nLCB7CiAgICAgIHZwYzogdnBjLCAvL2Fzc29jaWF0ZSB3aXRoIGV4aXN0aW5nIHZwYwogICAgICBsaWZlY3ljbGVQb2xpY3k6IGVmcy5MaWZlY3ljbGVQb2xpY3kuQUZURVJfMTRfREFZUywgLy8gZmlsZXMgYXJlIG5vdCB0cmFuc2l0aW9uZWQgdG8gaW5mcmVxdWVudCBhY2Nlc3MgKElBKSBzdG9yYWdlIGJ5IGRlZmF1bHQKICAgICAgcGVyZm9ybWFuY2VNb2RlOiBlZnMuUGVyZm9ybWFuY2VNb2RlLkdFTkVSQUxfUFVSUE9TRSwgLy8gZGVmYXVsdAogICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LlNOQVBTSE9ULAogICAgICB2cGNTdWJuZXRzOmRhdGFzdWJuZXRzLAogICAgICBzZWN1cml0eUdyb3VwOmVmc3NnCiAgICB9KTsKCi8vMi4gQ3JlYXRlIEFjY2VzcyBQb2ludAogICAgY29uc3QgZWZzYWNjZXNzcG9pbnQgPSBuZXcgZWZzLkFjY2Vzc1BvaW50KHRoaXMsICdjb250YWluZXJtb3VudCcsIHsKICAgICAgZmlsZVN5c3RlbTogZWZzdm9sdW1lLAogICAgICBwYXRoOicvYml0bmFtaScsCiAgICAgIGNyZWF0ZUFjbDogewogICAgICAgIG93bmVyR2lkOiAnMTAwMCcsCiAgICAgICAgb3duZXJVaWQ6ICcxMDAwJywKICAgICAgICBwZXJtaXNzaW9uczogJzA3NzcnCiAgICAgICAgCiAgICAgIH0KICAgIH0pOwoKICBlZnNzZy5jb25uZWN0aW9ucy5hbGxvd0Zyb20oZmFyZ2F0ZXNnLCBlYzIuUG9ydC50Y3AoMjA0OSksICdhbGxvdyBFRlMgY29ubmVjdGl2aXR5IGZyb20gRmFyZ2F0ZScpCg==” _builder_version=”4.10.7″ _module_preset=”default” global_colors_info=”{}”]Ly8xLiBDcmVhdGUgRmlsZSBTeXN0ZW0KICAgIGNvbnN0IGVmc3ZvbHVtZT1uZXcgZWZzLkZpbGVTeXN0ZW0odGhpcywgJ1dvcmRQcmVzc0Vmc0ZpbGVTeXN0ZW0nLCB7CiAgICAgIHZwYzogdnBjLCAvL2Fzc29jaWF0ZSB3aXRoIGV4aXN0aW5nIHZwYwogICAgICBsaWZlY3ljbGVQb2xpY3k6IGVmcy5MaWZlY3ljbGVQb2xpY3kuQUZURVJfMTRfREFZUywgLy8gZmlsZXMgYXJlIG5vdCB0cmFuc2l0aW9uZWQgdG8gaW5mcmVxdWVudCBhY2Nlc3MgKElBKSBzdG9yYWdlIGJ5IGRlZmF1bHQKICAgICAgcGVyZm9ybWFuY2VNb2RlOiBlZnMuUGVyZm9ybWFuY2VNb2RlLkdFTkVSQUxfUFVSUE9TRSwgLy8gZGVmYXVsdAogICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LlNOQVBTSE9ULAogICAgICB2cGNTdWJuZXRzOmRhdGFzdWJuZXRzLAogICAgICBzZWN1cml0eUdyb3VwOmVmc3NnCiAgICB9KTsKCi8vMi4gQ3JlYXRlIEFjY2VzcyBQb2ludAogICAgY29uc3QgZWZzYWNjZXNzcG9pbnQgPSBuZXcgZWZzLkFjY2Vzc1BvaW50KHRoaXMsICdjb250YWluZXJtb3VudCcsIHsKICAgICAgZmlsZVN5c3RlbTogZWZzdm9sdW1lLAogICAgICBwYXRoOicvYml0bmFtaScsCiAgICAgIGNyZWF0ZUFjbDogewogICAgICAgIG93bmVyR2lkOiAnMTAwMCcsCiAgICAgICAgb3duZXJVaWQ6ICcxMDAwJywKICAgICAgICBwZXJtaXNzaW9uczogJzA3NzcnCiAgICAgICAgCiAgICAgIH0KICAgIH0pOwoKICBlZnNzZy5jb25uZWN0aW9ucy5hbGxvd0Zyb20oZmFyZ2F0ZXNnLCBlYzIuUG9ydC50Y3AoMjA0OSksICdhbGxvdyBFRlMgY29ubmVjdGl2aXR5IGZyb20gRmFyZ2F0ZScpCg==[/et_pb_dmb_code_snippet]

CDK completely abstracts away the complex cloudformation involved in creating a security group. With supported CDK Constructs (such as Security Groups) you can simply define as was done above that you need to allow connections from one security group to another in 1 line. The Security groups are also created using a simple CDK construct that doesnt require creating Egress or Ingress Rules.

Next we move on to Database which is one of the most interesting parts for me since I have never actually had a use case yet in my personal architecture for Aurora Serverless but now I am consistently thinking of more. Aurora Serverless completely abstracts away the requirement to define compute and pay for a particular Database instance size. It scales as compute needs scale. You simply define the minimum and maximum consumption you want for your architecture. I kept the defaults (2 Capacity Units min, 16 Max).

Note: For WordPress MariaDB and MySQLDB are supported Databases. Aurora Serverless Supports PostGreSQL and MySQL Database Solutions so this architecture used MySQL

[et_pb_dmb_code_snippet code=”ICAgY29uc3QgYXVyb3JhRGF0YWJhc2VDbHVzdGVyID0gbmV3IHJkcy5TZXJ2ZXJsZXNzQ2x1c3Rlcih0aGlzLCAnRGF0YWJhc2UnLCB7CiAgICAgIGVuZ2luZTogcmRzLkRhdGFiYXNlQ2x1c3RlckVuZ2luZS5BVVJPUkFfTVlTUUwsCiAgICAgIGNyZWRlbnRpYWxzOiByZHMuQ3JlZGVudGlhbHMuZnJvbVNlY3JldChkYnBhc3N3b3JkKSwKICAgICAgcGFyYW1ldGVyR3JvdXA6ICByZHMuUGFyYW1ldGVyR3JvdXAuZnJvbVBhcmFtZXRlckdyb3VwTmFtZSh0aGlzLCAnUGFyYW1ldGVyR3JvdXAnLCAnZGVmYXVsdC5hdXJvcmEtbXlzcWw1LjcnKSwKICAgICAgZGVmYXVsdERhdGFiYXNlTmFtZTogJ3dvcmRwcmVzcycsCiAgICAgIAogICAgICB2cGM6IHZwYywKICAgICAgc2VjdXJpdHlHcm91cHM6IFtkYlNlY3VyaXR5R3JvdXBdLAogICAgICAvL3N0b3JhZ2VFbmNyeXB0aW9uS2V5OiBkYXRhYmFzZUtleSwKICAgICAgZGVsZXRpb25Qcm90ZWN0aW9uOiBmYWxzZSwKICAgICAgc3VibmV0R3JvdXA6IG5ldyByZHMuU3VibmV0R3JvdXAodGhpcywgJ2F1cm9yYWRic3VibmV0cycsIHsKICAgICAgICB2cGNTdWJuZXRzOiBkYXRhc3VibmV0cywKICAgICAgICB2cGM6IHZwYywKICAgICAgICBkZXNjcmlwdGlvbjogJ3N1Ym5ldHMgZm9yIEF1cm9yYSBzZXJ2ZXJsZXNzIGNsdXN0ZXInCiAgICAgIH0pCiAgICB9KTs=” _builder_version=”4.10.7″ _module_preset=”default” global_colors_info=”{}”]ICAgY29uc3QgYXVyb3JhRGF0YWJhc2VDbHVzdGVyID0gbmV3IHJkcy5TZXJ2ZXJsZXNzQ2x1c3Rlcih0aGlzLCAnRGF0YWJhc2UnLCB7CiAgICAgIGVuZ2luZTogcmRzLkRhdGFiYXNlQ2x1c3RlckVuZ2luZS5BVVJPUkFfTVlTUUwsCiAgICAgIGNyZWRlbnRpYWxzOiByZHMuQ3JlZGVudGlhbHMuZnJvbVNlY3JldChkYnBhc3N3b3JkKSwKICAgICAgcGFyYW1ldGVyR3JvdXA6ICByZHMuUGFyYW1ldGVyR3JvdXAuZnJvbVBhcmFtZXRlckdyb3VwTmFtZSh0aGlzLCAnUGFyYW1ldGVyR3JvdXAnLCAnZGVmYXVsdC5hdXJvcmEtbXlzcWw1LjcnKSwKICAgICAgZGVmYXVsdERhdGFiYXNlTmFtZTogJ3dvcmRwcmVzcycsCiAgICAgIAogICAgICB2cGM6IHZwYywKICAgICAgc2VjdXJpdHlHcm91cHM6IFtkYlNlY3VyaXR5R3JvdXBdLAogICAgICAvL3N0b3JhZ2VFbmNyeXB0aW9uS2V5OiBkYXRhYmFzZUtleSwKICAgICAgZGVsZXRpb25Qcm90ZWN0aW9uOiBmYWxzZSwKICAgICAgc3VibmV0R3JvdXA6IG5ldyByZHMuU3VibmV0R3JvdXAodGhpcywgJ2F1cm9yYWRic3VibmV0cycsIHsKICAgICAgICB2cGNTdWJuZXRzOiBkYXRhc3VibmV0cywKICAgICAgICB2cGM6IHZwYywKICAgICAgICBkZXNjcmlwdGlvbjogJ3N1Ym5ldHMgZm9yIEF1cm9yYSBzZXJ2ZXJsZXNzIGNsdXN0ZXInCiAgICAgIH0pCiAgICB9KTs=[/et_pb_dmb_code_snippet]

Not shown above (but in the code repo) is that preceding this an AWS Secret in AWS Secrets Manager is created with generated password and a defined username.

And the Credentials for the Database are created by consuming that secret. The Really Cool thing about doing this is you can actually automate Rotating of the Secret and Password within the Database. That is a bit beyond the scope of this blog but the next update to the code base in github will hopefully have that included.

Fargate

I have been building up to this part but before I go in deep on it I might just quickly touch on the components that make up a Fargate environment.

Fargate is a type of Environment operating in AWS Elastic Container Service. Alternative options for Fargate are ECS with Hosted EC2 and Kubernetes clusters which both involve compute infrastructure to some degree and my point here was to limit that as much as possible.

Fargate uses Task Definitions to define the Container, Compute requirements, network architecture and placement within the network. The container definitions define the image, environment variables, secrets, EFS Mounts, etc.

First thing to do is define the Role used by the Task and execution. There can be a role for each Task and Executions but I defined one in this case. It was simply given access to EFS (Full Access limited only to the single file system created earlier). It also is granted access to get images and get authorization Tokens for both ECR Private and public registries.

 

[et_pb_dmb_code_snippet code=”ICAgICAgICAgIGNvbnN0IHRhc2tSb2xlID0gbmV3IGlhbS5Sb2xlKHRoaXMsICJ3b3JkcHJlc3N0YXNrLXJvbGUiLCB7CiAgICAgICAgICAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCJlY3MtdGFza3MuYW1hem9uYXdzLmNvbSIpLAogICAgICAgICAgICByb2xlTmFtZTogInRhc2stcm9sZSIsCiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAiUm9sZSB0aGF0IHRoZSBhcGkgdGFzayBkZWZpbml0aW9ucyB1c2UgdG8gcnVuIHRoZSBhcGkgY29kZSIsCiAgICAgICAgICB9KTsKICAgIAogICAgICAgICAgdGFza1JvbGUuYXR0YWNoSW5saW5lUG9saWN5KAogICAgICAgICAgICBuZXcgaWFtLlBvbGljeSh0aGlzLCAiZWZzLWFjY2Vzcy1wb2xpY3kiLCB7CiAgICAgICAgICAgICAgc3RhdGVtZW50czogWwogICAgICAgICAgICAgICAgLy8gcG9saWNpZXMgdG8gYWxsb3cgYWNjZXNzIHRvIG90aGVyIEFXUyBzZXJ2aWNlcyBmcm9tIHdpdGhpbiB0aGUgY29udGFpbmVyIGUuZyBTRVMgKFNpbXBsZSBFbWFpbCBTZXJ2aWNlKQogICAgICAgICAgICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoewogICAgICAgICAgICAgICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csCiAgICAgICAgICAgICAgICAgIGFjdGlvbnM6IFsKICAgICAgICAgICAgICAgICAgICAiZWxhc3RpY2ZpbGVzeXN0ZW06KiIsCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICByZXNvdXJjZXM6IFtlZnN2b2x1bWUuZmlsZVN5c3RlbUFybl0sCiAgICAgICAgICAgICAgICB9KSwKICAgICAgICAgICAgICBdLAogICAgICAgICAgICB9KQogICAgICAgICAgKTsKCiAgICAgICAgICB0YXNrUm9sZS5hdHRhY2hJbmxpbmVQb2xpY3koCiAgICAgICAgICAgIG5ldyBpYW0uUG9saWN5KHRoaXMsICJlY3MtYWNjZXNzLXBvbGljeSIsIHsKICAgICAgICAgICAgICBzdGF0ZW1lbnRzOiBbCiAgICAgICAgICAgICAgICAvLyBwb2xpY2llcyB0byBhbGxvdyBhY2Nlc3MgdG8gb3RoZXIgQVdTIHNlcnZpY2VzIGZyb20gd2l0aGluIHRoZSBjb250YWluZXIgZS5nIFNFUyAoU2ltcGxlIEVtYWlsIFNlcnZpY2UpCiAgICAgICAgICAgICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7CiAgICAgICAgICAgICAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVywKICAgICAgICAgICAgICAgICAgYWN0aW9uczogWwogICAgICAgICAgICAgICAgICAgICJlY3I6R2V0QXV0aG9yaXphdGlvblRva2VuIiwKICAgICAgICAgICAgICAgICAgICAiZWNyOkJhdGNoQ2hlY2tMYXllckF2YWlsYWJpbGl0eSIsCiAgICAgICAgICAgICAgICAgICAgImVjcjpHZXREb3dubG9hZFVybEZvckxheWVyIiwKICAgICAgICAgICAgICAgICAgICAiZWNyLXB1YmxpYzpHZXRBdXRob3JpemF0aW9uVG9rZW4iLAogICAgICAgICAgICAgICAgICAgICJlY3I6QmF0Y2hHZXRJbWFnZSIsCiAgICAgICAgICAgICAgICAgICAgImxvZ3M6Q3JlYXRlTG9nU3RyZWFtIiwKICAgICAgICAgICAgICAgICAgICAibG9nczpQdXRMb2dFdmVudHMiCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICByZXNvdXJjZXM6IFsiKiJdLAogICAgICAgICAgICAgICAgfSksCiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgfSkKICAgICAgICAgICk7″ _builder_version=”4.10.7″ _module_preset=”default” global_colors_info=”{}”]ICAgICAgICAgIGNvbnN0IHRhc2tSb2xlID0gbmV3IGlhbS5Sb2xlKHRoaXMsICJ3b3JkcHJlc3N0YXNrLXJvbGUiLCB7CiAgICAgICAgICAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCJlY3MtdGFza3MuYW1hem9uYXdzLmNvbSIpLAogICAgICAgICAgICByb2xlTmFtZTogInRhc2stcm9sZSIsCiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAiUm9sZSB0aGF0IHRoZSBhcGkgdGFzayBkZWZpbml0aW9ucyB1c2UgdG8gcnVuIHRoZSBhcGkgY29kZSIsCiAgICAgICAgICB9KTsKICAgIAogICAgICAgICAgdGFza1JvbGUuYXR0YWNoSW5saW5lUG9saWN5KAogICAgICAgICAgICBuZXcgaWFtLlBvbGljeSh0aGlzLCAiZWZzLWFjY2Vzcy1wb2xpY3kiLCB7CiAgICAgICAgICAgICAgc3RhdGVtZW50czogWwogICAgICAgICAgICAgICAgLy8gcG9saWNpZXMgdG8gYWxsb3cgYWNjZXNzIHRvIG90aGVyIEFXUyBzZXJ2aWNlcyBmcm9tIHdpdGhpbiB0aGUgY29udGFpbmVyIGUuZyBTRVMgKFNpbXBsZSBFbWFpbCBTZXJ2aWNlKQogICAgICAgICAgICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoewogICAgICAgICAgICAgICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csCiAgICAgICAgICAgICAgICAgIGFjdGlvbnM6IFsKICAgICAgICAgICAgICAgICAgICAiZWxhc3RpY2ZpbGVzeXN0ZW06KiIsCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICByZXNvdXJjZXM6IFtlZnN2b2x1bWUuZmlsZVN5c3RlbUFybl0sCiAgICAgICAgICAgICAgICB9KSwKICAgICAgICAgICAgICBdLAogICAgICAgICAgICB9KQogICAgICAgICAgKTsKCiAgICAgICAgICB0YXNrUm9sZS5hdHRhY2hJbmxpbmVQb2xpY3koCiAgICAgICAgICAgIG5ldyBpYW0uUG9saWN5KHRoaXMsICJlY3MtYWNjZXNzLXBvbGljeSIsIHsKICAgICAgICAgICAgICBzdGF0ZW1lbnRzOiBbCiAgICAgICAgICAgICAgICAvLyBwb2xpY2llcyB0byBhbGxvdyBhY2Nlc3MgdG8gb3RoZXIgQVdTIHNlcnZpY2VzIGZyb20gd2l0aGluIHRoZSBjb250YWluZXIgZS5nIFNFUyAoU2ltcGxlIEVtYWlsIFNlcnZpY2UpCiAgICAgICAgICAgICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7CiAgICAgICAgICAgICAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVywKICAgICAgICAgICAgICAgICAgYWN0aW9uczogWwogICAgICAgICAgICAgICAgICAgICJlY3I6R2V0QXV0aG9yaXphdGlvblRva2VuIiwKICAgICAgICAgICAgICAgICAgICAiZWNyOkJhdGNoQ2hlY2tMYXllckF2YWlsYWJpbGl0eSIsCiAgICAgICAgICAgICAgICAgICAgImVjcjpHZXREb3dubG9hZFVybEZvckxheWVyIiwKICAgICAgICAgICAgICAgICAgICAiZWNyLXB1YmxpYzpHZXRBdXRob3JpemF0aW9uVG9rZW4iLAogICAgICAgICAgICAgICAgICAgICJlY3I6QmF0Y2hHZXRJbWFnZSIsCiAgICAgICAgICAgICAgICAgICAgImxvZ3M6Q3JlYXRlTG9nU3RyZWFtIiwKICAgICAgICAgICAgICAgICAgICAibG9nczpQdXRMb2dFdmVudHMiCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICByZXNvdXJjZXM6IFsiKiJdLAogICAgICAgICAgICAgICAgfSksCiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgfSkKICAgICAgICAgICk7[/et_pb_dmb_code_snippet]

Creating a Fargate Environment in CDK requires creating a Cluster, Service, Task and Container defintion. Each component has its own needs. WordPress also has required environment variables which come from the source ECR reference. The important thing to understand is that you need to have a IAM permission in the policy as defined above to authorize access to any repository (even public gallery ones) or else the pull may fail or be degraded.

I placed the Fargate  creation down the bottom of the code base because it uses resources created in previous sections (EFS, Load Balancer, Aurora) and effectively brings it all together

 

 

[et_pb_dmb_code_snippet code=”Y29uc3QgZmFyZ2F0ZXRhc2s9bmV3IGVjcy5GYXJnYXRlVGFza0RlZmluaXRpb24odGhpcywgImZhcmdhdGV0YXNrIiwgewogICAgCiAgICBmYW1pbHk6ICJ3b3JkcHJlc3MiLCAgIAogICAgbWVtb3J5TGltaXRNaUI6IDIwNDgsCiAgICBjcHU6IDI1NiwKICAgIHRhc2tSb2xlOiB0YXNrUm9sZSwKICAgIGV4ZWN1dGlvblJvbGU6IHRhc2tSb2xlLAogICAgdm9sdW1lczogW3sKICAgICAgZWZzVm9sdW1lQ29uZmlndXJhdGlvbjogewogICAgICAgIGZpbGVTeXN0ZW1JZDogZWZzdm9sdW1lLmZpbGVTeXN0ZW1JZCwKICAgICAgICB0cmFuc2l0RW5jcnlwdGlvbjogJ0VOQUJMRUQnLAogICAgICAgIAogICAgICB9LAogICAgICAKICAgICAgCiAgICAgIG5hbWU6ICd3b3JkcHJlc3MtZGF0YScKICAgICAgCiAgICB9XSwKICAgIAogICAKCiAgICAKICAgIH0pOwoKIAogICAgbGV0IGltYWdlc291cmNlOiBzdHJpbmc7CiAgICBpZiAocHJvcHM/LnByaXZhdGVFQ1IgIT0gdW5kZWZpbmVkKSB7CiAgICAgIGltYWdlc291cmNlPXByb3BzPy5wcml2YXRlRUNSCiAgICB9IGVsc2UgewogICAgICBpbWFnZXNvdXJjZT0ncHVibGljLmVjci5hd3MvYml0bmFtaS93b3JkcHJlc3M6bGF0ZXN0JwogICAgfQoKCiAgICBjb25zdCBjb250YWluZXJkZWYgPSBuZXcgZWNzLkNvbnRhaW5lckRlZmluaXRpb24odGhpcywgJ3dvcmRwcmVzcy1jb250YWluZXInLCB7CiAgICAgIHRhc2tEZWZpbml0aW9uOiBmYXJnYXRldGFzaywKICAgICAgaW1hZ2U6IGVjcy5Db250YWluZXJJbWFnZS5mcm9tUmVnaXN0cnkoaW1hZ2Vzb3VyY2UpLAogICAgICBtZW1vcnlMaW1pdE1pQjo1MTIsCiAgICAgIHBvcnRNYXBwaW5nczogW3sKICAgICAgICBjb250YWluZXJQb3J0OiA4MDgwLAogICAgICAgIHByb3RvY29sOiBlY3MuUHJvdG9jb2wuVENQCiAgICAgIH1dLAogICAgICAKICAgICAgCiAgICAgIGxvZ2dpbmc6ICBlY3MuTG9nRHJpdmVycy5hd3NMb2dzICh7IHN0cmVhbVByZWZpeDogJ1dvcmRQcmVzc0xvZ3MnIH0pLAogICAgICBlbnZpcm9ubWVudDogewogICAgICAgIAogICAgICAgICAgLy9FbnZpcm9ubWVudCB2YXJpYWJsZXMgcGFzcyBmcm9tIEF1cm9yYSBEZXBsb3ltZW50CiAgICAgICAgICBNQVJJQURCX0hPU1Q6IGF1cm9yYURhdGFiYXNlQ2x1c3Rlci5jbHVzdGVyRW5kcG9pbnQuaG9zdG5hbWUsCiAgICAgICAgICAKICAgICAgICAgIFdPUkRQUkVTU19EQVRBQkFTRV9OQU1FOiAnd29yZHByZXNzJywKICAgICAgICAgIFBIUF9NRU1PUllfTElNSVQ6ICI1MTJNIiwKICAgICAgICAgIGVuYWJsZWQ6ICJmYWxzZSIsCiAgICAgICAgICBBTExPV19FTVBUWV9QQVNTV09SRDoibm8iLAogICAgICAgICAgV09SRFBSRVNTX1RBQkxFX1BSRUZJWDogJ3dwXycKICAgICAgfSwKICAgICAgCiAgICAgIAogICAgICBzZWNyZXRzOiB7CiAgICAgICAgV09SRFBSRVNTX0RBVEFCQVNFX1BBU1NXT1JEOiBlY3MuU2VjcmV0LmZyb21TZWNyZXRzTWFuYWdlcihkYnBhc3N3b3JkLCAncGFzc3dvcmQnKSwKICAgICAgICBXT1JEUFJFU1NfREFUQUJBU0VfVVNFUjogZWNzLlNlY3JldC5mcm9tU2VjcmV0c01hbmFnZXIoZGJwYXNzd29yZCwgJ3VzZXJuYW1lJyksCgogICAgICB9LAogICAgfSk7CgogICAgICAKICAgICAgY29udGFpbmVyZGVmLmFkZE1vdW50UG9pbnRzKHsKICAgICAgCiAgICAgIGNvbnRhaW5lclBhdGg6ICcvYml0bmFtaS93b3JkcHJlc3MnLAogICAgICBzb3VyY2VWb2x1bWU6ICd3b3JkcHJlc3MtZGF0YScsCiAgICAgIHJlYWRPbmx5OiBmYWxzZSwKICAgIH0pOwogICAgCgogICAgY29uc3QgZWNzY2x1c3Rlcj1uZXcgZWNzLkNsdXN0ZXIodGhpcywgImVjc2NsdXN0ZXIiLCB7CiAgICAgIHZwYzogdnBjLAogICAgICBjbHVzdGVyTmFtZTogIldvcmRQcmVzcyIsCiAgICAgIAogICAgICB9KTsgICAgCiAgICAgICAgICAKCgoKICAgIGNvbnN0IGZhcmdhdGVTZXJ2aWNlPW5ldyBlY3MuRmFyZ2F0ZVNlcnZpY2UodGhpcywgImZhcmdhdGVzZXJ2aWNlIix7CiAgICB0YXNrRGVmaW5pdGlvbjogZmFyZ2F0ZXRhc2ssCiAgICBjbHVzdGVyOiBlY3NjbHVzdGVyLAogICAgdnBjU3VibmV0czogYXBwZGF0YXN1Ym5ldHMsCiAgICBkZXNpcmVkQ291bnQ6MSwKICAgIHNlY3VyaXR5R3JvdXBzOltmYXJnYXRlc2ddLAogICAgc2VydmljZU5hbWU6ICd3b3JkcHJlc3MnLAogICAgCgogICAgfSk7CgogICAgZmFyZ2F0ZVNlcnZpY2UuYXR0YWNoVG9BcHBsaWNhdGlvblRhcmdldEdyb3VwKHRhcmdldEdyb3VwSHR0cCk7CgogICAgLy9TdXBwb3J0IFNjYWxpbmcgYmFzZWQgb24gcGVyZm9ybWFuY2UKCiAgICBjb25zdCBzY2FsaW5nID0gZmFyZ2F0ZVNlcnZpY2UuYXV0b1NjYWxlVGFza0NvdW50KHsgbWF4Q2FwYWNpdHk6IDMgfSk7CnNjYWxpbmcuc2NhbGVPbkNwdVV0aWxpemF0aW9uKCdDcHVTY2FsaW5nJywgewogIHRhcmdldFV0aWxpemF0aW9uUGVyY2VudDogNTAKfSk7CgpzY2FsaW5nLnNjYWxlT25SZXF1ZXN0Q291bnQoJ1JlcXVlc3RTY2FsaW5nJywgewogIHJlcXVlc3RzUGVyVGFyZ2V0OiAxMDAwMCwKICB0YXJnZXRHcm91cDogdGFyZ2V0R3JvdXBIdHRwCn0p” _builder_version=”4.10.7″ _module_preset=”default” global_colors_info=”{}”]Y29uc3QgZmFyZ2F0ZXRhc2s9bmV3IGVjcy5GYXJnYXRlVGFza0RlZmluaXRpb24odGhpcywgImZhcmdhdGV0YXNrIiwgewogICAgCiAgICBmYW1pbHk6ICJ3b3JkcHJlc3MiLCAgIAogICAgbWVtb3J5TGltaXRNaUI6IDIwNDgsCiAgICBjcHU6IDI1NiwKICAgIHRhc2tSb2xlOiB0YXNrUm9sZSwKICAgIGV4ZWN1dGlvblJvbGU6IHRhc2tSb2xlLAogICAgdm9sdW1lczogW3sKICAgICAgZWZzVm9sdW1lQ29uZmlndXJhdGlvbjogewogICAgICAgIGZpbGVTeXN0ZW1JZDogZWZzdm9sdW1lLmZpbGVTeXN0ZW1JZCwKICAgICAgICB0cmFuc2l0RW5jcnlwdGlvbjogJ0VOQUJMRUQnLAogICAgICAgIAogICAgICB9LAogICAgICAKICAgICAgCiAgICAgIG5hbWU6ICd3b3JkcHJlc3MtZGF0YScKICAgICAgCiAgICB9XSwKICAgIAogICAKCiAgICAKICAgIH0pOwoKIAogICAgbGV0IGltYWdlc291cmNlOiBzdHJpbmc7CiAgICBpZiAocHJvcHM/LnByaXZhdGVFQ1IgIT0gdW5kZWZpbmVkKSB7CiAgICAgIGltYWdlc291cmNlPXByb3BzPy5wcml2YXRlRUNSCiAgICB9IGVsc2UgewogICAgICBpbWFnZXNvdXJjZT0ncHVibGljLmVjci5hd3MvYml0bmFtaS93b3JkcHJlc3M6bGF0ZXN0JwogICAgfQoKCiAgICBjb25zdCBjb250YWluZXJkZWYgPSBuZXcgZWNzLkNvbnRhaW5lckRlZmluaXRpb24odGhpcywgJ3dvcmRwcmVzcy1jb250YWluZXInLCB7CiAgICAgIHRhc2tEZWZpbml0aW9uOiBmYXJnYXRldGFzaywKICAgICAgaW1hZ2U6IGVjcy5Db250YWluZXJJbWFnZS5mcm9tUmVnaXN0cnkoaW1hZ2Vzb3VyY2UpLAogICAgICBtZW1vcnlMaW1pdE1pQjo1MTIsCiAgICAgIHBvcnRNYXBwaW5nczogW3sKICAgICAgICBjb250YWluZXJQb3J0OiA4MDgwLAogICAgICAgIHByb3RvY29sOiBlY3MuUHJvdG9jb2wuVENQCiAgICAgIH1dLAogICAgICAKICAgICAgCiAgICAgIGxvZ2dpbmc6ICBlY3MuTG9nRHJpdmVycy5hd3NMb2dzICh7IHN0cmVhbVByZWZpeDogJ1dvcmRQcmVzc0xvZ3MnIH0pLAogICAgICBlbnZpcm9ubWVudDogewogICAgICAgIAogICAgICAgICAgLy9FbnZpcm9ubWVudCB2YXJpYWJsZXMgcGFzcyBmcm9tIEF1cm9yYSBEZXBsb3ltZW50CiAgICAgICAgICBNQVJJQURCX0hPU1Q6IGF1cm9yYURhdGFiYXNlQ2x1c3Rlci5jbHVzdGVyRW5kcG9pbnQuaG9zdG5hbWUsCiAgICAgICAgICAKICAgICAgICAgIFdPUkRQUkVTU19EQVRBQkFTRV9OQU1FOiAnd29yZHByZXNzJywKICAgICAgICAgIFBIUF9NRU1PUllfTElNSVQ6ICI1MTJNIiwKICAgICAgICAgIGVuYWJsZWQ6ICJmYWxzZSIsCiAgICAgICAgICBBTExPV19FTVBUWV9QQVNTV09SRDoibm8iLAogICAgICAgICAgV09SRFBSRVNTX1RBQkxFX1BSRUZJWDogJ3dwXycKICAgICAgfSwKICAgICAgCiAgICAgIAogICAgICBzZWNyZXRzOiB7CiAgICAgICAgV09SRFBSRVNTX0RBVEFCQVNFX1BBU1NXT1JEOiBlY3MuU2VjcmV0LmZyb21TZWNyZXRzTWFuYWdlcihkYnBhc3N3b3JkLCAncGFzc3dvcmQnKSwKICAgICAgICBXT1JEUFJFU1NfREFUQUJBU0VfVVNFUjogZWNzLlNlY3JldC5mcm9tU2VjcmV0c01hbmFnZXIoZGJwYXNzd29yZCwgJ3VzZXJuYW1lJyksCgogICAgICB9LAogICAgfSk7CgogICAgICAKICAgICAgY29udGFpbmVyZGVmLmFkZE1vdW50UG9pbnRzKHsKICAgICAgCiAgICAgIGNvbnRhaW5lclBhdGg6ICcvYml0bmFtaS93b3JkcHJlc3MnLAogICAgICBzb3VyY2VWb2x1bWU6ICd3b3JkcHJlc3MtZGF0YScsCiAgICAgIHJlYWRPbmx5OiBmYWxzZSwKICAgIH0pOwogICAgCgogICAgY29uc3QgZWNzY2x1c3Rlcj1uZXcgZWNzLkNsdXN0ZXIodGhpcywgImVjc2NsdXN0ZXIiLCB7CiAgICAgIHZwYzogdnBjLAogICAgICBjbHVzdGVyTmFtZTogIldvcmRQcmVzcyIsCiAgICAgIAogICAgICB9KTsgICAgCiAgICAgICAgICAKCgoKICAgIGNvbnN0IGZhcmdhdGVTZXJ2aWNlPW5ldyBlY3MuRmFyZ2F0ZVNlcnZpY2UodGhpcywgImZhcmdhdGVzZXJ2aWNlIix7CiAgICB0YXNrRGVmaW5pdGlvbjogZmFyZ2F0ZXRhc2ssCiAgICBjbHVzdGVyOiBlY3NjbHVzdGVyLAogICAgdnBjU3VibmV0czogYXBwZGF0YXN1Ym5ldHMsCiAgICBkZXNpcmVkQ291bnQ6MSwKICAgIHNlY3VyaXR5R3JvdXBzOltmYXJnYXRlc2ddLAogICAgc2VydmljZU5hbWU6ICd3b3JkcHJlc3MnLAogICAgCgogICAgfSk7CgogICAgZmFyZ2F0ZVNlcnZpY2UuYXR0YWNoVG9BcHBsaWNhdGlvblRhcmdldEdyb3VwKHRhcmdldEdyb3VwSHR0cCk7CgogICAgLy9TdXBwb3J0IFNjYWxpbmcgYmFzZWQgb24gcGVyZm9ybWFuY2UKCiAgICBjb25zdCBzY2FsaW5nID0gZmFyZ2F0ZVNlcnZpY2UuYXV0b1NjYWxlVGFza0NvdW50KHsgbWF4Q2FwYWNpdHk6IDMgfSk7CnNjYWxpbmcuc2NhbGVPbkNwdVV0aWxpemF0aW9uKCdDcHVTY2FsaW5nJywgewogIHRhcmdldFV0aWxpemF0aW9uUGVyY2VudDogNTAKfSk7CgpzY2FsaW5nLnNjYWxlT25SZXF1ZXN0Q291bnQoJ1JlcXVlc3RTY2FsaW5nJywgewogIHJlcXVlc3RzUGVyVGFyZ2V0OiAxMDAwMCwKICB0YXJnZXRHcm91cDogdGFyZ2V0R3JvdXBIdHRwCn0p[/et_pb_dmb_code_snippet]

And there it is. The complete pattern architecture I developed to create this blog site using wordpress and make it persistent.

I can add themes, plugins and images and data that needs to be persistent and using EFS storage that data will exist outside the container.

The Task attaches to the Load Balancer and brings the Webpage online. Deployment takes about 20 minutes.

Note: A final note since I would be remiss if I didnt mention costs. All AWS services do have a cost and even serverless architectures have a cost to run. The use of NAT Gateways are the biggest cost element in this architecture for a small wordpress. If the Network architecture is not used for anything but the WordPress then it might be worth using a private ECR WordPress image and then use the Private Endpoints to access it.

Alternatively another low cost option (albeit not a serverless one) is to run a VM in a public subnet as a NAT or Proxy for the HTTPS traffic

Aurora serverless, Load Balancers and Fargate should be low cost (maybe $80-100 per month between them for a low consumption site).

AWS Offer Compute Savings Plans which can be used with Fargate Workloads and can reduce the cost of running the containers by 10+%. I highly recommend if there are ongoing persistent workloads that savings plans or Reservations be consumed

 

I do hope this is of use to some people out there. Thanks for reading.

 

 

References:

GitHub Repo: https://github.com/spudda32/aws-cdk-wordpress

WordPress Public Container: https://gallery.ecr.aws/bitnami/wordpress