Skip to content

Enables ECS Exec #65

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: release/0.2.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -232,6 +254,7 @@ For any issues relating to this module, [raise an issue against this repo.](http
| <a name="input_cloudfront_class"></a> [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 |
| <a name="input_cloudfront_function_301_redirects"></a> [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)` | <pre>{<br> "^(.*)index\\.php$": "$1"<br>}</pre> | no |
| <a name="input_ecs_cpu"></a> [ecs\_cpu](#input\_ecs\_cpu) | The CPU limit password to the Wordpress container definition. | `number` | `256` | no |
| <a name="input_ecs_healthcheck_enabled"></a> [ecs\_healthcheck\_enabled](#input\_ecs\_healthcheck\_enabled) | Runs an healtchcheck against the container. | `bool` | `true` | no |
| <a name="input_ecs_memory"></a> [ecs\_memory](#input\_ecs\_memory) | The memory limit password to the Wordpress container definition. | `number` | `512` | no |
| <a name="input_graviton_codebuild_enabled"></a> [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 |
| <a name="input_graviton_fargate_enabled"></a> [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 |
Expand All @@ -252,6 +275,8 @@ For any issues relating to this module, [raise an issue against this repo.](http
| <a name="input_wordpress_admin_user"></a> [wordpress\_admin\_user](#input\_wordpress\_admin\_user) | The username of the default wordpress admin user. | `string` | `"supervisor"` | no |
| <a name="input_wordpress_memory_limit"></a> [wordpress\_memory\_limit](#input\_wordpress\_memory\_limit) | The memory to allow the Wordpress process to use (in M) | `string` | `"256M"` | no |
| <a name="input_wordpress_subdomain"></a> [wordpress\_subdomain](#input\_wordpress\_subdomain) | The subdomain used for the Wordpress container. | `string` | `"wordpress"` | no |
| <a name="input_wp2static_s3_addon_version"></a> [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 |
| <a name="input_wp2static_version"></a> [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 |
Expand Down Expand Up @@ -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 |
Expand All @@ -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 |
<!-- END_TF_DOCS -->
71 changes: 49 additions & 22 deletions ecs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion modules/codebuild/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This module sets up the build to take a vanilla Wordpress image and bake customi
| <a name="input_site_name"></a> [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 |
| <a name="input_wordpress_ecr_repository"></a> [wordpress\_ecr\_repository](#input\_wordpress\_ecr\_repository) | The ECR repository where the Wordpress image is stored. | `string` | n/a | yes |
| <a name="input_wp2static_s3_addon_version"></a> [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 |
| <a name="input_wp2static_version"></a> [wp2static\_version](#input\_wp2static\_version) | Version of WP2Static to use from https://github.com/leonstafford/wp2static/releases | `string` | `"7.1.7"` | no |
| <a name="input_wp2static_version"></a> [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.
Expand Down
110 changes: 57 additions & 53 deletions task-definitions/wordpress.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
})}

}
]
6 changes: 6 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down