https://github.com/saloniamatteo/aws-wordpress-deployment
Matteo Salonia's WordPress deployment on AWS
https://github.com/saloniamatteo/aws-wordpress-deployment
aws-cloudformation cloudformation docker docker-wordpress wordpress wordpress-aws wordpress-docker
Last synced: 10 months ago
JSON representation
Matteo Salonia's WordPress deployment on AWS
- Host: GitHub
- URL: https://github.com/saloniamatteo/aws-wordpress-deployment
- Owner: saloniamatteo
- License: mit
- Created: 2025-03-31T09:51:16.000Z (10 months ago)
- Default Branch: master
- Last Pushed: 2025-04-04T20:51:02.000Z (10 months ago)
- Last Synced: 2025-04-04T21:37:26.930Z (10 months ago)
- Topics: aws-cloudformation, cloudformation, docker, docker-wordpress, wordpress, wordpress-aws, wordpress-docker
- Language: Makefile
- Homepage:
- Size: 415 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Wordpress deployment on AWS
This project creates a secure, resilient, scalable, replicable, distributed Wordpress deployment.
The following technologies are used:
- AWS CloudFormation (stack deployment)
- AWS CloudFront
- AWS CloudWatch
- AWS ECS
- AWS EFS
- AWS ELB
- AWS IAM
- AWS KMS
- AWS RDS
- AWS S3
- AWS SNS
- AWS Secrets Manager
- AWS VPC

## Structure
This project is structured as follows:
```
├── Makefile
├── templates
│ └── *.yaml
├── wordpress-dev.json
└── wordpress-prod.json
```
The `templates` folder contains the following:
```
├── alb.yaml
├── cloudfront.yaml
├── cloudwatch.yaml
├── ecs.yaml
├── efs.yaml
├── env.yaml
├── kms.yaml
├── network.yaml
├── rds.yaml
├── s3.yaml
├── secrets-manager.yaml
└── sns.yaml
```
Each file creates a piece of infrastructure.
In order to deploy this stack, `rain merge` is used to create one singular file.
## Prerequisites
In order to deploy this stack & work with it, the following tools are required:
- [rain](https://github.com/aws-cloudformation/rain)
- [jq](https://github.com/jqlang/jq)
## Makefile overrides
The `rain` binary in `Makefile` is called from `RAIN_CMD`, which defaults to `$HOME/go/bin/rain`.
Change this parameter if your path is different!
Example:
```bash
RAIN_CMD=/usr/local/bin/rain make deploy
```
Similarly, the following Makefile variables can be overridden:
- `STACK_NAME`: the name of the stack (default: `WordpressStack`)
- `RAIN_CMD`: path to `rain` (default: `${HOME}/go/bin/rain`)
- `PARAMS_FILE`: path to the development parameters (default: `wordpress-dev.json`)
- `PARAMS_FILE_PROD`: path to the production parameters (default: `wordpress-prod.json`)
## Deploying the stack
Deploying the CloudFormation stack is real easy.
The provided `Makefile` provides the following commands:
- `make lint`: lint the merged CloudFormation template
- `make deploy`: deploy the CloudFormation stack using rain (development values)
- `make deploy-prod`: deploy the CloudFormation stack using rain (production values)
- `make delete`: delete the deployed CloudFormation stack using the AWS CLI
- `make clean`: remove the merged CloudFormation template
Running `make deploy` is an easy, hassle-free way to get started with this stack.
**NOTE**: please set the `AdminEmail` parameter before deploying.
More info below.
### Outputs
The following outputs are produced:
- `CFDomainName`: the CloudFront distribution's publicly-accessible DNS Name. This is the Wordpress deployment's URL.
## Technical design notes
### Admin Email
This stack provides the following CloudWatch Alerts:
- ECS: CPUUtilization average >= 70% for 5 minutes
- RDS: CPUUtilization average >= 70% for 5 minutes
The thresholds (70%) can be changed independently of each other.
Alerts are then relayed to an SNS Topic, which is configured to send
email to the provided `AdminEmail` parameter through an SNS Subscription.
**Don't forget to set this value!** The default is `CHANGEME@example.com`.
### ALB
The Application Load Balancer (ALB) enables stickiness, provided by an LB cookie,
for a total duration of 15 minutes. This value can be changed.
Stickiness needs to be turned on in order to allow logins.
Without it, trying to login would result in a page refresh.
### CloudFront <-> ALB
The ALB only accepts direct traffic from CloudFront, by creating a
[CloudFront VPC Origin](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-vpc-origins.html).
The ALB is internal only, and is therefore placed in all three private subnets.
**NOTE**: the Managed Prefix List ID (`com.amazonaws.global.cloudfront.origin-facing`)
is fetched when running `make deploy` (or `make deploy-prod`), so as to avoid hardcoded values.
This is needed in order to restrict access to the load balancer, and to allow only CloudFront.
### RDS DB Credentials
The credentials used to access the RDS DB (username & password) are generated
automatically (and therefore, stored) by Secrets Manager.
Constraints:
- Username: 16 characters max, no numbers, no punctuation, no uppercase chars, no spaces
- Password: default 32 characters, no spaces, `"@/\` characters excluded
These are then referenced by both RDS and ECS.
Secrets are encrypted using a KMS Key generated by this stack.
The default key encryption used is `AES-128-GCM`.
### RDS Deployment
When `EnvType` is set to `prod` (production), the RDS DB is deployed
with `MultiAZ = true`. Otherwise, the DB is deployed in a single AZ.
**NOTE**: a MultiAZ deployment does not deploy the DB in all three AZs.
Instead, it creates a master instance in a random AZ, and a
secondary/slave instance in another random AZ, totaling two AZs.
The RDS Storage is encrypted with another KMS Key generated by this stack.
**NOTE**: that the provided storage type is `gp2`, which is the one
provided in the free tier. Change this value accordingly.
### VPC
The CIDR of the VPC is (obviously) a parameter. The value in the provided parameter files
is set to `10.14.0.0/16`.
Subsequently, the subnets' CIDRs (both public & private) are not hardcoded,
meaning their values are automatically calculated from the VPC CIDR value,
by using the following formula:
```yaml
!Select [n, !Cidr [ !Ref VPCCIDR, c, 8 ]]
```
Where:
- `n`: generated CIDR number (from 0 to 5; the first 3 are used for the public subnets)
- `c`: how many subnets to create (6)
- `8`: subnet bits (`32 - 24 = 8`); a `/24` address space is assigned for each subnet
### Wordpress version
The wordpress version is parametrized, meaning the `WordpressVersion` parameter
can be used to set a specific version. The recommended default is `latest`.
You can see available versions [here](https://hub.docker.com/_/wordpress).