Skip to content

feat: Add support for advanced deployment configurations (i.e. - blue/green deployment) #322

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

Merged
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
4 changes: 2 additions & 2 deletions README.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions examples/complete/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ Note that this example may create resources which will incur monetary charges on
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.4 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.4 |

## Modules

Expand Down
2 changes: 1 addition & 1 deletion examples/complete/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 6.0"
version = ">= 6.4"
}
}
}
2 changes: 1 addition & 1 deletion examples/container-definition/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Note that this example may create resources which will incur monetary charges on
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.4 |
| <a name="requirement_local"></a> [local](#requirement\_local) | >= 2.5 |

## Providers
Expand Down
2 changes: 1 addition & 1 deletion examples/container-definition/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 6.0"
version = ">= 6.4"
}
local = {
source = "hashicorp/local"
Expand Down
4 changes: 2 additions & 2 deletions examples/ec2-autoscaling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ Note that this example may create resources which will incur monetary charges on
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.4 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.4 |

## Modules

Expand Down
2 changes: 1 addition & 1 deletion examples/ec2-autoscaling/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 6.0"
version = ">= 6.4"
}
}
}
7 changes: 5 additions & 2 deletions examples/fargate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ Note that this example may create resources which will incur monetary charges on
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.4 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.4 |

## Modules

Expand All @@ -49,6 +49,9 @@ Note that this example may create resources which will incur monetary charges on

| Name | Type |
|------|------|
| [aws_iam_role.ecs_elb_permissions](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.ecs_elb_management_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.ecs_service_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_service_discovery_http_namespace.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/service_discovery_http_namespace) | resource |
| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
| [aws_ssm_parameter.fluentbit](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source |
Expand Down
145 changes: 143 additions & 2 deletions examples/fargate/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,26 @@ module "ecs_service" {
# Enables ECS Exec
enable_execute_command = true

# for blue/green deployments
deployment_configuration = {
strategy = "BLUE_GREEN"
bake_time_in_minutes = 2

# example config using lifecycle hooks
# lifecycle_hook = {
# success = {
# hook_target_arn = aws_lambda_function.hook_success.arn
# role_arn = aws_iam_role.global.arn
# lifecycle_stages = ["POST_SCALE_UP", "POST_TEST_TRAFFIC_SHIFT"]
# }
# failure = {
# hook_target_arn = aws_lambda_function.hook_failure.arn
# role_arn = aws_iam_role.global.arn
# lifecycle_stages = ["TEST_TRAFFIC_SHIFT", "POST_PRODUCTION_TRAFFIC_SHIFT"]
# }
# }
}

# Container definition(s)
container_definitions = {

Expand Down Expand Up @@ -152,6 +172,14 @@ module "ecs_service" {
target_group_arn = module.alb.target_groups["ex_ecs"].arn
container_name = local.container_name
container_port = local.container_port

# for blue/green deployments
advanced_configuration = {
alternate_target_group_arn = module.alb.target_groups["ex_ecs_alternate"].arn
production_listener_rule = module.alb.listener_rules["ex_http/production"].arn
test_listener_rule = module.alb.listener_rules["ex_http/test"].arn
role_arn = aws_iam_role.ecs_elb_permissions.arn
}
}
}

Expand All @@ -176,6 +204,12 @@ module "ecs_service" {
}

tags = local.tags

depends_on = [
aws_iam_role.ecs_elb_permissions,
aws_iam_role_policy_attachment.ecs_service_role,
aws_iam_role_policy_attachment.ecs_elb_management_role
]
}

################################################################################
Expand Down Expand Up @@ -278,8 +312,60 @@ module "alb" {
port = 80
protocol = "HTTP"

forward = {
target_group_key = "ex_ecs"
fixed_response = {
content_type = "text/plain"
message_body = "404: Page not found"
status_code = "404"
}

# for blue/green deployments
rules = {
production = {
priority = 1
actions = [
{
type = "weighted-forward"
target_groups = [
{
target_group_key = "ex_ecs"
weight = 100
},
{
target_group_key = "ex_ecs_alternate"
weight = 0
}
]
}
]
conditions = [
{
path_pattern = {
values = ["/*"]
}
}
]
}
test = {
priority = 2
actions = [
{
type = "weighted-forward"
target_groups = [
{
target_group_key = "ex_ecs_alternate"
weight = 100
}
]
}
]
conditions = [
{
path_pattern = {
values = ["/*"]
}
}
]
}
}
}
}
Expand Down Expand Up @@ -308,6 +394,31 @@ module "alb" {
# ECS will attach the IPs of the tasks to this target group
create_attachment = false
}

# for blue/green deployments
ex_ecs_alternate = {
backend_protocol = "HTTP"
backend_port = local.container_port
target_type = "ip"
deregistration_delay = 5
load_balancing_cross_zone_enabled = true

health_check = {
enabled = true
healthy_threshold = 5
interval = 30
matcher = "200"
path = "/"
port = "traffic-port"
protocol = "HTTP"
timeout = 5
unhealthy_threshold = 2
}

# There's nothing to attach here in this definition. Instead,
# ECS will attach the IPs of the tasks to this target group
create_attachment = false
}
}

tags = local.tags
Expand All @@ -329,3 +440,33 @@ module "vpc" {

tags = local.tags
}

resource "aws_iam_role" "ecs_elb_permissions" {
name = "${local.name}-ecs-elb-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = [
"ecs-tasks.amazonaws.com",
"ecs.amazonaws.com",
]
}
}
]
})
}

# for example purposes only
resource "aws_iam_role_policy_attachment" "ecs_service_role" {
role = aws_iam_role.ecs_elb_permissions.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole"
}

resource "aws_iam_role_policy_attachment" "ecs_elb_management_role" {
role = aws_iam_role.ecs_elb_permissions.name
policy_arn = "arn:aws:iam::aws:policy/AmazonECSInfrastructureRolePolicyForLoadBalancers"
}
2 changes: 1 addition & 1 deletion examples/fargate/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 6.0"
version = ">= 6.4"
}
}
}
1 change: 1 addition & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ module "service" {
capacity_provider_strategy = each.value.capacity_provider_strategy
cluster_arn = module.cluster.arn
deployment_circuit_breaker = each.value.deployment_circuit_breaker
deployment_configuration = each.value.deployment_configuration
deployment_controller = each.value.deployment_controller
deployment_maximum_percent = each.value.deployment_maximum_percent
deployment_minimum_healthy_percent = each.value.deployment_minimum_healthy_percent
Expand Down
4 changes: 2 additions & 2 deletions modules/cluster/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,13 @@ module "ecs_cluster" {
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.4 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.4 |

## Modules

Expand Down
2 changes: 1 addition & 1 deletion modules/cluster/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 6.0"
version = ">= 6.4"
}
}
}
4 changes: 2 additions & 2 deletions modules/container-definition/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,13 @@ module "example_ecs_container_definition" {
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.4 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.4 |

## Modules

Expand Down
2 changes: 1 addition & 1 deletion modules/container-definition/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 6.0"
version = ">= 6.4"
}
}
}
Loading