Skip to content

Commit

Permalink
Initial release of serverless-static-wordpress (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
petewilcock authored Jun 19, 2021
1 parent 682cd83 commit e92d1bd
Show file tree
Hide file tree
Showing 61 changed files with 3,859 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @petewilcock
66 changes: 66 additions & 0 deletions .github/workflows/testsuite-master.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
name: test-suite-master
# yamllint disable-line rule:truthy
on:
push:
branches:
- master
jobs:
tflint:
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- name: setup Terraform
uses: hashicorp/[email protected]
with:
terraform_version: 0.15.5
- name: Terraform init
run: terraform init --backend=false
- name: tflint
uses: reviewdog/action-tflint@master
with:
github_token: ${{ secrets.ACTIONS_TOKEN }}
reporter: github-check
filter_mode: added
flags: --module
level: error
tfsec:
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- name: setup Terraform
uses: hashicorp/[email protected]
with:
terraform_version: 0.15.5
- name: Terraform init
run: terraform init --backend=false
- name: tfsec
uses: reviewdog/action-tfsec@master
with:
github_token: ${{ secrets.ACTIONS_TOKEN }}
reporter: github-check
filter_mode: added
level: warning
misspell:
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- name: misspell
uses: reviewdog/action-misspell@v1
with:
github_token: ${{ secrets.ACTIONS_TOKEN }}
locale: "US"
reporter: github-check
filter_mode: added
level: error
yamllint:
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- name: yamllint
uses: reviewdog/[email protected]
with:
github_token: ${{ secrets.ACTIONS_TOKEN }}
reporter: github-check
filter_mode: added
level: error
93 changes: 93 additions & 0 deletions .github/workflows/testsuite.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
name: test-suite
# yamllint disable-line rule:truthy
on:
pull_request:
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- name: Set up Python
uses: actions/[email protected]
- name: Install prerequisites
run: ./bin/install-ubuntu.sh
- name: Terraform init
run: terraform init --backend=false
- name: pre-commit
uses: pre-commit/[email protected]
env:
AWS_DEFAULT_REGION: eu-west-1
# many of these are covered by better reviewdog linters below
SKIP: >-
terraform_tflint_deep,
no-commit-to-branch,
terraform_tflint_nocreds,
terraform_tfsec
- uses: stefanzweifel/[email protected]
if: ${{ failure() }}
with:
commit_message: Apply automatic changes
commit_options: "--no-verify"
# Optional commit user and author settings
commit_user_name: Linter Bot
commit_user_email: [email protected]
commit_author: Linter Bot <[email protected]>
tflint:
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- name: setup Terraform
uses: hashicorp/[email protected]
with:
terraform_version: 0.15.5
- name: Terraform init
run: terraform init --backend=false
- name: tflint
uses: reviewdog/action-tflint@master
with:
github_token: ${{ secrets.ACTIONS_TOKEN }}
reporter: github-pr-check
filter_mode: added
flags: --module
level: error
tfsec:
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- name: setup Terraform
uses: hashicorp/[email protected]
with:
terraform_version: 0.15.5
- name: Terraform init
run: terraform init --backend=false
- name: tfsec
uses: reviewdog/action-tfsec@master
with:
github_token: ${{ secrets.ACTIONS_TOKEN }}
reporter: github-pr-check
filter_mode: added
level: warning
misspell:
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- name: misspell
uses: reviewdog/action-misspell@v1
with:
github_token: ${{ secrets.ACTIONS_TOKEN }}
locale: "US"
reporter: github-pr-check
filter_mode: added
level: error
yamllint:
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- name: yamllint
uses: reviewdog/[email protected]
with:
github_token: ${{ secrets.ACTIONS_TOKEN }}
reporter: github-pr-check
filter_mode: added
level: error
37 changes: 37 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Build artifacts
modules/cloudfront/lambda_redirect/dst/*
modules/codebuild/codebuild_files/wordpress_docker.zip
modules/codebuild/codebuild_files/php.ini

# Local .terraform directories
**/.terraform/*

# .tfstate files
# *.tfstate
# *.tfstate.*
.terraform.lock.hcl
plan.plan
# Crash log files
crash.log

# Ignore any .tfvars files that are generated automatically for each Terraform run. Most
# .tfvars files are managed as part of configuration and so should be included in
# version control.
#
# example.tfvars

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Include override files you do wish to add to version control using negated pattern
#
# !example_override.tf

# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*

.idea
168 changes: 168 additions & 0 deletions .header.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# terraform-aws-serverless-static-wordpress

[![Test Suite](https://github.com/techtospeech/terraform-aws-serverless-static-wordpress/workflows/test-suite-master/badge.svg?branch=master&event=push)](https://github.com/techtospeech/terraform-aws-serverless-static-wordpress/actions/workflows/testsuite-master.yaml?query=branch%3Amaster+event%3Apush+workflow%3Atest-suite)
<a href="https://twitter.com/intent/follow?screen_name=TechToSpeech"><img src="https://img.shields.io/twitter/follow/TechToSpeech?style=social&logo=twitter" alt="follow on Twitter"></a>

## Introduction

Serverless Static Wordpress is a Community Terraform Module from TechToSpeech that needs nothing more than a registered
domain name with its DNS pointed at AWS.

It creates a complete infrastructure framework that allows you to launch a temporary, transient Wordpress container.
You then log in and customize it like any Wordpress site, and finally publish it as a static site fronted by a global
CloudFront CDN and S3 Origin. When you’re done you shut down the Wordpress container and it costs you almost nothing.

The emphasis is on extremely minimal configuration as the majority of everything you’d need is pre-installed and
pre-configured in line with industry best practices and highly efficient running costs.

## Architecture Overview

![Architecture](docs/serverless-static-wordpress.png)

## Pre-requisites

- A domain name either hosted with AWS, or with its DNS delegated to a Route53 hosted zone.
- A VPC configured with at least one public subnet in your desired deployment region.

## Provider Set-up

Terraform best practice is to configure providers at the top-level module and pass them downwards through implicit
inheritance or explicit passing. Whilst the module and child-modules reference `required_providers`, it is also necessary
for you to provide a regional alias for operations that _must_ be executed in us-east-1 (CloudFront, ACM, and WAF).
As such you should include the following in your provider configuration:

```
terraform {
required_version = "> 0.15.1"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
configuration_aliases = [aws.ue1]
}
}
}
provider "aws" {
alias = "ue1"
region = "us-east-1"
}
```

The `ue1` alias is essential for this module to work correctly.

## Module instantiation example

```
locals {
aws_account_id = "998877676554"
aws_region = "eu-west-1"
site_name = "peterdotcloud"
profile = "peterdotcloud"
site_domain = "peter.cloud"
}
data "aws_caller_identity" "current" {}
module "peterdotcloud_website" {
source = "TechToSpeech/serverless-static-wordpress/aws"
version = "0.1.0"
main_vpc_id = "vpc-e121c09b"
subnet_ids = ["subnet-04b97235","subnet-08fb235","subnet-04b97734"]
aws_account_id = data.aws_caller_identity.current.account_id
# site_name will be used to prepend resource names - use no spaces or special characters
site_name = local.site_name
site_domain = local.site_domain
wordpress_subdomain = "wordpress"
hosted_zone_id = "Z00437553UWAVIRHANGCN"
s3_region = local.aws_region
# Send ECS and RDS events to Slack
slack_webhook = "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
ecs_cpu = 1024
ecs_memory = 2048
cloudfront_aliases = ["www.peter.cloud", "peter.cloud"]
waf_enabled = true
# Provides the toggle to launch Wordpress container
launch = 0
## Passing in Provider block to module is essential
providers = {
aws.ue1 = aws.ue1
}
}
```

Do not to set `launch` to 1 initially as the module uses a Codebuild pipeline to take a vanilla version
of the Wordpress docker container and rebake it to include all of the pre-requisites required to publish the Wordpress
site to S3.

The step to push the required Wordpress container from Dockerhub to your own ECR repository can be tied into your
module instantiation using our [helper module](https://github.com/TechToSpeech/terraform-aws-ecr-mirror) as follows:

Note this requires Docker to be running on your Terraform environment with either a named AWS profile or credentials
otherwise available.
```
module "docker_pullpush" {
source = "TechToSpeech/ecr-mirror/aws"
version = "0.0.6"
aws_account_id = data.aws_caller_identity.current.account_id
aws_region = local.aws_region
docker_source = "wordpress:php7.4-apache"
aws_profile = "peterdotcloud"
ecr_repo_name = module.peterdotcloud_website.wordpress_ecr_repository
ecr_repo_tag = "base"
depends_on = [module.peterdotcloud_website]
}
```

The CodeBuild pipeline takes a couple of minutes to run and pushes back a 'latest' tagged version of the container,
which is what will be used for the Wordpress container. This build either needs to be triggered manually from the
CodeBuild console, or you can use this snippet to trigger the build as part of your Terraform flow:

```
resource "null_resource" "trigger_build" {
triggers = {
codebuild_etag = module.peterdotcloud_website.codebuild_package_etag
}
provisioner "local-exec" {
command = <<-EOT
aws codebuild start-build --project-name "${module.peterdotcloud_website.codebuild_project_name}"
--profile "${local.profile}" --region "${local.aws_region}"
EOT
}
depends_on = [
module.peterdotcloud_website, module.docker_pullpush
]
}
```

Whilst this might feel convoluted (and you might ask: why not just provide a public customized Docker image?), it was
felt important that users should 'own' their own version of the Wordpress container, built transparently from the official Wordpress docker image with full provenance.

Finally, if you wish to fully automate the creation _and_ update of the domain's nameservers if it's registered in
Route53 within the same account, you can add these additional snippets to include this in your flow.

```
resource "aws_route53_zone" "apex" {
name = "peter.cloud"
}
resource "null_resource" "update_nameservers" {
triggers = {
nameservers = aws_route53_zone.apex.id
}
provisioner "local-exec" {
command = <<-EOT
aws route53domains update-domain-nameservers --region us-east-1 --domain-name "${local.site_domain}"
--nameservers Name="${aws_route53_zone.apex.name_servers.0}" Name="${aws_route53_zone.apex.name_servers.1}"
Name="${aws_route53_zone.apex.name_servers.2}" Name="${aws_route53_zone.apex.name_servers.3}" --profile peterdotcloud
EOT
}
depends_on = [aws_route53_zone.apex]
}
```
See [examples](docs/examples) for full set-up example.
Loading

0 comments on commit e92d1bd

Please sign in to comment.