diff --git a/README.md b/README.md index beae3d8..bd0419c 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,28 @@ in your module definition. Gentle reminder that no backup options are currently bundled with this module - the most effective means would be to generate and retain a backup from within Wordpress for maximum flexibility. We recommend the UpdraftPlus plugin. +## Permanent Redirects + +Basic url path based permanent redirects are supported via the CloudFront function. The variable `cloudfront_function_301_redirects` can be set with a custom map of match to destination mappings. + +Some aspects that need to be taken into consideration for the match: + +* It's a regular expression +* Group replacements are supported +* Runs in a Javascript function, escaping needs to be taken into consideration +* Passed through a TF var, so escaping that needs to be taking into account as well + +An example to match a path like `/category-name`, a suitable match would be `"^\\/(category-name)$"`. Breaking down the `\\/` part, the first `\` tells TF to escape the second `\`, which is the Regex escape for the `/` character. + +An example: + +``` +cloudfront_function_301_redirects = { + # Redirects /travel to /category/travel/ + "^\\/(travel)$": "/category/$1/", +} +``` + ## Troubleshooting If you experience issues with the publish element of WP2Static, you can retry. It can be more reliable to proceed to @@ -232,6 +254,7 @@ For any issues relating to this module, [raise an issue against this repo.](http | [cloudfront\_class](#input\_cloudfront\_class) | The [price class](https://aws.amazon.com/cloudfront/pricing/) for the distribution. One of: PriceClass\_All, PriceClass\_200, PriceClass\_100 | `string` | `"PriceClass_All"` | no | | [cloudfront\_function\_301\_redirects](#input\_cloudfront\_function\_301\_redirects) | A list of key value pairs of Regex match and destination for 301 redirects at CloudFront. | `map(any)` |
{
"^(.*)index\\.php$": "$1"
} | no |
| [ecs\_cpu](#input\_ecs\_cpu) | The CPU limit password to the Wordpress container definition. | `number` | `256` | no |
+| [ecs\_healthcheck\_enabled](#input\_ecs\_healthcheck\_enabled) | Runs an healtchcheck against the container. | `bool` | `true` | no |
| [ecs\_memory](#input\_ecs\_memory) | The memory limit password to the Wordpress container definition. | `number` | `512` | no |
| [graviton\_codebuild\_enabled](#input\_graviton\_codebuild\_enabled) | Flag that controls whether CodeBuild should use Graviton-based build agents in [supported regions](https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-compute-types.html). | `bool` | `false` | no |
| [graviton\_fargate\_enabled](#input\_graviton\_fargate\_enabled) | Flag that controls whether ECS Fargate should use Graviton-based containers in [supported regions]https://docs.aws.amazon.com/AmazonECS/latest/developerguide/AWS_Fargate-Regions.html). | `bool` | `false` | no |
@@ -252,6 +275,8 @@ For any issues relating to this module, [raise an issue against this repo.](http
| [wordpress\_admin\_user](#input\_wordpress\_admin\_user) | The username of the default wordpress admin user. | `string` | `"supervisor"` | no |
| [wordpress\_memory\_limit](#input\_wordpress\_memory\_limit) | The memory to allow the Wordpress process to use (in M) | `string` | `"256M"` | no |
| [wordpress\_subdomain](#input\_wordpress\_subdomain) | The subdomain used for the Wordpress container. | `string` | `"wordpress"` | no |
+| [wp2static\_s3\_addon\_version](#input\_wp2static\_s3\_addon\_version) | Version of the WP2Static S3 Add-on to use from https://github.com/leonstafford/wp2static-addon-s3/releases/ | `string` | `"1.0"` | no |
+| [wp2static\_version](#input\_wp2static\_version) | Version of WP2Static to use from https://github.com/WP2Static/wp2static/releases | `string` | `"7.1.7"` | no |
## Modules
| Name | Source | Version |
@@ -293,8 +318,10 @@ For any issues relating to this module, [raise an issue against this repo.](http
| [aws_efs_file_system.wordpress_persistent](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/efs_file_system) | resource |
| [aws_efs_mount_target.wordpress_efs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/efs_mount_target) | resource |
| [aws_iam_policy.wordpress_bucket_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
+| [aws_iam_policy.wordpress_ecs_exec](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role.wordpress_task](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.wordpress_bucket_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
+| [aws_iam_role_policy_attachment.wordpress_ecs_exec](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.wordpress_role_attachment_cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.wordpress_role_attachment_ecs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_rds_cluster.serverless_wordpress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster) | resource |
@@ -315,5 +342,6 @@ For any issues relating to this module, [raise an issue against this repo.](http
| [random_password.serverless_wordpress_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
| [aws_iam_policy_document.ecs_assume_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.wordpress_bucket_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
+| [aws_iam_policy_document.wordpress_ecs_exec](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
diff --git a/ecs.tf b/ecs.tf
index 13a65e3..75c217d 100644
--- a/ecs.tf
+++ b/ecs.tf
@@ -44,6 +44,19 @@ data "aws_iam_policy_document" "wordpress_bucket_access" {
}
}
+data "aws_iam_policy_document" "wordpress_ecs_exec" {
+ statement {
+ actions = [
+ "ssmmessages:CreateControlChannel",
+ "ssmmessages:CreateDataChannel",
+ "ssmmessages:OpenControlChannel",
+ "ssmmessages:OpenDataChannel"
+ ]
+ effect = "Allow"
+ resources = ["*"]
+ }
+}
+
resource "aws_iam_policy" "wordpress_bucket_access" {
name = "${var.site_name}_WordpressBucketAccess"
description = "The role that allows Wordpress task to do necessary operations"
@@ -55,6 +68,17 @@ resource "aws_iam_role_policy_attachment" "wordpress_bucket_access" {
policy_arn = aws_iam_policy.wordpress_bucket_access.arn
}
+resource "aws_iam_policy" "wordpress_ecs_exec" {
+ name = "${var.site_name}_WordpressECSExec"
+ description = "Allows ECS Exec to the Wordpress container"
+ policy = data.aws_iam_policy_document.wordpress_ecs_exec.json
+}
+
+resource "aws_iam_role_policy_attachment" "wordpress_ecs_exec" {
+ role = aws_iam_role.wordpress_task.name
+ policy_arn = aws_iam_policy.wordpress_ecs_exec.arn
+}
+
resource "aws_iam_role" "wordpress_task" {
name = "${var.site_name}_WordpressTaskRole"
assume_role_policy = data.aws_iam_policy_document.ecs_assume_role_policy.json
@@ -106,24 +130,25 @@ resource "aws_cloudwatch_log_group" "wordpress_container" {
resource "aws_ecs_task_definition" "wordpress_container" {
family = "${var.site_name}_wordpress"
container_definitions = templatefile("${path.module}/task-definitions/wordpress.json", {
- db_host = aws_rds_cluster.serverless_wordpress.endpoint,
- db_user = aws_rds_cluster.serverless_wordpress.master_username,
- db_password = random_password.serverless_wordpress_password.result,
- db_name = aws_rds_cluster.serverless_wordpress.database_name,
- wordpress_image = "${aws_ecr_repository.serverless_wordpress.repository_url}:latest",
- wp_dest = "https://${var.site_prefix}.${var.site_domain}",
- wp_region = var.s3_region,
- wp_bucket = module.cloudfront.wordpress_bucket_id,
- container_dns = "${var.wordpress_subdomain}.${var.site_domain}",
- container_dns_zone = var.hosted_zone_id,
- container_cpu = var.ecs_cpu,
- container_memory = var.ecs_memory
- efs_source_volume = "${var.site_name}_wordpress_persistent"
- wordpress_admin_user = var.wordpress_admin_user
- wordpress_admin_password = var.wordpress_admin_password
- wordpress_admin_email = var.wordpress_admin_email
- site_name = var.site_name
- wordpress_memory_limit = var.wordpress_memory_limit
+ db_host = aws_rds_cluster.serverless_wordpress.endpoint
+ db_user = aws_rds_cluster.serverless_wordpress.master_username
+ db_password = random_password.serverless_wordpress_password.result
+ db_name = aws_rds_cluster.serverless_wordpress.database_name
+ wordpress_image = "${aws_ecr_repository.serverless_wordpress.repository_url}:latest"
+ wp_dest = "https://${var.site_prefix}.${var.site_domain}"
+ wp_region = var.s3_region
+ wp_bucket = module.cloudfront.wordpress_bucket_id
+ container_dns = "${var.wordpress_subdomain}.${var.site_domain}"
+ container_dns_zone = var.hosted_zone_id
+ container_cpu = var.ecs_cpu
+ container_memory = var.ecs_memory
+ container_healthcheck_enabled = var.ecs_healthcheck_enabled
+ efs_source_volume = "${var.site_name}_wordpress_persistent"
+ wordpress_admin_user = var.wordpress_admin_user
+ wordpress_admin_password = var.wordpress_admin_password
+ wordpress_admin_email = var.wordpress_admin_email
+ site_name = var.site_name
+ wordpress_memory_limit = var.wordpress_memory_limit
})
runtime_platform {
@@ -220,10 +245,12 @@ resource "aws_security_group_rule" "wordpress_sg_egress_3306" {
resource "aws_ecs_service" "wordpress_service" {
- name = "${var.site_name}_wordpress"
- task_definition = "${aws_ecs_task_definition.wordpress_container.family}:${aws_ecs_task_definition.wordpress_container.revision}"
- cluster = aws_ecs_cluster.wordpress_cluster.arn
- desired_count = var.launch
+ name = "${var.site_name}_wordpress"
+ task_definition = "${aws_ecs_task_definition.wordpress_container.family}:${aws_ecs_task_definition.wordpress_container.revision}"
+ cluster = aws_ecs_cluster.wordpress_cluster.arn
+ desired_count = var.launch
+ enable_execute_command = true
+
# iam_role =
capacity_provider_strategy {
capacity_provider = var.graviton_fargate_enabled ? (contains(local.graviton_fargate_regions_unsupported, data.aws_region.current) ? "FARGATE_SPOT" : "FARGATE") : "FARGATE_SPOT"
diff --git a/main.tf b/main.tf
index be2e09b..572f1b5 100644
--- a/main.tf
+++ b/main.tf
@@ -31,7 +31,7 @@ module "cloudfront" {
}
depends_on = [aws_acm_certificate_validation.wordpress_site,
module.waf]
-
+
cloudfront_class = var.cloudfront_class
waf_acl_arn = var.waf_enabled ? module.waf[0].waf_acl_arn : null
cloudfront_function_301_redirects = var.cloudfront_function_301_redirects
diff --git a/modules/codebuild/README.md b/modules/codebuild/README.md
index 3797cc4..4ff068e 100644
--- a/modules/codebuild/README.md
+++ b/modules/codebuild/README.md
@@ -16,7 +16,7 @@ This module sets up the build to take a vanilla Wordpress image and bake customi
| [site\_name](#input\_site\_name) | The unique name for this instance of the module. Required to deploy multiple wordpress instances to the same AWS account (if desired). | `string` | n/a | yes |
| [wordpress\_ecr\_repository](#input\_wordpress\_ecr\_repository) | The ECR repository where the Wordpress image is stored. | `string` | n/a | yes |
| [wp2static\_s3\_addon\_version](#input\_wp2static\_s3\_addon\_version) | Version of the WP2Static S3 Add-on to use from https://github.com/leonstafford/wp2static-addon-s3/releases/ | `string` | `"1.0"` | no |
-| [wp2static\_version](#input\_wp2static\_version) | Version of WP2Static to use from https://github.com/leonstafford/wp2static/releases | `string` | `"7.1.7"` | no |
+| [wp2static\_version](#input\_wp2static\_version) | Version of WP2Static to use from https://github.com/WP2Static/wp2static/releases | `string` | `"7.1.7"` | no |
## Modules
No modules.
diff --git a/task-definitions/wordpress.json b/task-definitions/wordpress.json
index 543e596..64aa2d6 100644
--- a/task-definitions/wordpress.json
+++ b/task-definitions/wordpress.json
@@ -1,56 +1,60 @@
[
- ${jsonencode({
- "cpu": tonumber(container_cpu),
- "environment": [
- {"name": "ECS_ENABLE_CONTAINER_METADATA", "value": "true"},
- {"name": "WORDPRESS_DB_HOST", "value": "${db_host}"},
- {"name": "WORDPRESS_DB_USER", "value": "${db_user}"},
- {"name": "WORDPRESS_DB_PASSWORD", "value": "${db_password}"},
- {"name": "WORDPRESS_DB_NAME", "value": "${db_name}"},
- {"name": "WPSTATIC_DEST", "value": "${wp_dest}"},
- {"name": "WPSTATIC_REGION", "value": "${wp_region}"},
- {"name": "WPSTATIC_BUCKET", "value": "${wp_bucket}"},
- {"name": "CONTAINER_DNS", "value": "${container_dns}"},
- {"name": "CONTAINER_DNS_ZONE", "value": "${container_dns_zone}"},
- {"name": "WORDPRESS_ADMIN_USER", "value": "${wordpress_admin_user}"},
- {"name": "WORDPRESS_ADMIN_PASSWORD", "value": "${wordpress_admin_password}"},
- {"name": "WORDPRESS_ADMIN_EMAIL", "value": "${wordpress_admin_email}"},
- {"name": "WP_MEMORY_LIMIT", "value": "${wordpress_memory_limit}"}
- ],
- "essential": true,
- "image": "${wordpress_image}",
- "memory": tonumber(container_memory),
- "name": "wordpress",
- "portMappings": [
- {
- "containerPort": 80,
- "hostPort": 80,
- "protocol": "tcp"
+ {
+ "cpu": ${tonumber(container_cpu)},
+ "environment": [
+ {"name": "ECS_ENABLE_CONTAINER_METADATA", "value": "true"},
+ {"name": "WORDPRESS_DB_HOST", "value": "${db_host}"},
+ {"name": "WORDPRESS_DB_USER", "value": "${db_user}"},
+ {"name": "WORDPRESS_DB_PASSWORD", "value": "${db_password}"},
+ {"name": "WORDPRESS_DB_NAME", "value": "${db_name}"},
+ {"name": "WPSTATIC_DEST", "value": "${wp_dest}"},
+ {"name": "WPSTATIC_REGION", "value": "${wp_region}"},
+ {"name": "WPSTATIC_BUCKET", "value": "${wp_bucket}"},
+ {"name": "CONTAINER_DNS", "value": "${container_dns}"},
+ {"name": "CONTAINER_DNS_ZONE", "value": "${container_dns_zone}"},
+ {"name": "WORDPRESS_ADMIN_USER", "value": "${wordpress_admin_user}"},
+ {"name": "WORDPRESS_ADMIN_PASSWORD", "value": "${wordpress_admin_password}"},
+ {"name": "WORDPRESS_ADMIN_EMAIL", "value": "${wordpress_admin_email}"},
+ {"name": "WP_MEMORY_LIMIT", "value": "${wordpress_memory_limit}"}
+ ],
+ "essential": true,
+ "image": "${wordpress_image}",
+ "memory": ${tonumber(container_memory)},
+ "name": "wordpress",
+ "portMappings": [
+ {
+ "containerPort": 80,
+ "hostPort": 80,
+ "protocol": "tcp"
+ }
+ ],
+ "mountPoints" : [
+ {
+ "sourceVolume": "${efs_source_volume}",
+ "containerPath": "/var/www/html",
+ "readOnly": false
+ }
+ ],
+ %{if container_healthcheck_enabled }
+ "healthCheck": {
+ "retries": 10,
+ "command": [ "CMD-SHELL", "curl -f http://localhost:80/ || exit 1" ],
+ "timeout": 5,
+ "interval": 10,
+ "startPeriod": 60
+ },
+ %{ endif }
+ "volumesFrom" : [],
+ "logConfiguration": {
+ "logDriver": "awslogs",
+ "options": {
+ "awslogs-group": "/aws/ecs/${site_name}-serverless-wordpress-container",
+ "awslogs-region": "${wp_region}",
+ "awslogs-stream-prefix": "ecs"
+ }
+ },
+ "linuxParameters": {
+ "initProcessEnabled": true
}
- ],
- "mountPoints" : [
- {
- "sourceVolume": "${efs_source_volume}",
- "containerPath": "/var/www/html",
- "readOnly": false
- }
- ],
- "healthCheck": {
- "retries": 10,
- "command": [ "CMD-SHELL", "curl -f http://localhost:80/ || exit 1" ],
- "timeout": 5,
- "interval": 10,
- "startPeriod": 60
- },
- "volumesFrom" : [],
- "logConfiguration": {
- "logDriver": "awslogs",
- "options": {
- "awslogs-group": "/aws/ecs/${site_name}-serverless-wordpress-container",
- "awslogs-region": "${wp_region}",
- "awslogs-stream-prefix": "ecs"
- }
- }
- })}
-
+ }
]
diff --git a/variables.tf b/variables.tf
index b9f204e..b8dc880 100644
--- a/variables.tf
+++ b/variables.tf
@@ -79,6 +79,12 @@ variable "ecs_memory" {
description = "The memory limit password to the Wordpress container definition."
}
+variable "ecs_healthcheck_enabled" {
+ default = true
+ description = "Runs an healtchcheck against the container."
+ type = bool
+}
+
variable "snapshot_identifier" {
description = "To create the RDS cluster from a previous snapshot in the same region, specify it by name."
type = string