Skip to content

feat: Add support for setting placement constraints separately between service and task definition #93

New issue

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

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

Already on GitHub? # to your account

Merged
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
2 changes: 1 addition & 1 deletion examples/complete/README.md
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ Note that this example may create resources which will incur monetary charges on
| <a name="module_ecs_cluster_disabled"></a> [ecs\_cluster\_disabled](#module\_ecs\_cluster\_disabled) | ../../modules/cluster | n/a |
| <a name="module_ecs_disabled"></a> [ecs\_disabled](#module\_ecs\_disabled) | ../../ | n/a |
| <a name="module_service_disabled"></a> [service\_disabled](#module\_service\_disabled) | ../../modules/service | n/a |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 4.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 |

## Resources

2 changes: 1 addition & 1 deletion examples/complete/main.tf
Original file line number Diff line number Diff line change
@@ -227,7 +227,7 @@ module "alb" {

module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 4.0"
version = "~> 5.0"

name = local.name
cidr = local.vpc_cidr
2 changes: 1 addition & 1 deletion examples/ec2-autoscaling/README.md
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ Note that this example may create resources which will incur monetary charges on
| <a name="module_autoscaling_sg"></a> [autoscaling\_sg](#module\_autoscaling\_sg) | terraform-aws-modules/security-group/aws | ~> 4.0 |
| <a name="module_ecs_cluster"></a> [ecs\_cluster](#module\_ecs\_cluster) | ../../modules/cluster | n/a |
| <a name="module_ecs_service"></a> [ecs\_service](#module\_ecs\_service) | ../../modules/service | n/a |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 4.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 |

## Resources

2 changes: 1 addition & 1 deletion examples/ec2-autoscaling/main.tf
Original file line number Diff line number Diff line change
@@ -320,7 +320,7 @@ module "autoscaling_sg" {

module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 4.0"
version = "~> 5.0"

name = local.name
cidr = local.vpc_cidr
2 changes: 1 addition & 1 deletion examples/fargate/README.md
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ Note that this example may create resources which will incur monetary charges on
| <a name="module_alb_sg"></a> [alb\_sg](#module\_alb\_sg) | terraform-aws-modules/security-group/aws | ~> 4.0 |
| <a name="module_ecs_cluster"></a> [ecs\_cluster](#module\_ecs\_cluster) | ../../modules/cluster | n/a |
| <a name="module_ecs_service"></a> [ecs\_service](#module\_ecs\_service) | ../../modules/service | n/a |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 4.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 |

## Resources

2 changes: 1 addition & 1 deletion examples/fargate/main.tf
Original file line number Diff line number Diff line change
@@ -219,7 +219,7 @@ module "alb" {

module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 4.0"
version = "~> 5.0"

name = local.name
cidr = local.vpc_cidr
3 changes: 2 additions & 1 deletion modules/service/README.md
Original file line number Diff line number Diff line change
@@ -268,7 +268,7 @@ module "ecs_service" {
| <a name="input_network_mode"></a> [network\_mode](#input\_network\_mode) | Docker networking mode to use for the containers in the task. Valid values are `none`, `bridge`, `awsvpc`, and `host` | `string` | `"awsvpc"` | no |
| <a name="input_ordered_placement_strategy"></a> [ordered\_placement\_strategy](#input\_ordered\_placement\_strategy) | Service level strategy rules that are taken into consideration during task placement. List from top to bottom in order of precedence | `any` | `{}` | no |
| <a name="input_pid_mode"></a> [pid\_mode](#input\_pid\_mode) | Process namespace to use for the containers in the task. The valid values are `host` and `task` | `string` | `null` | no |
| <a name="input_placement_constraints"></a> [placement\_constraints](#input\_placement\_constraints) | Configuration block for rules that are taken into consideration during task placement (up to max of 10) | `any` | `{}` | no |
| <a name="input_placement_constraints"></a> [placement\_constraints](#input\_placement\_constraints) | Configuration block for rules that are taken into consideration during task placement (up to max of 10). This is set at the service, see `task_definition_placement_constraints` for setting at the task definition | `any` | `{}` | no |
| <a name="input_platform_version"></a> [platform\_version](#input\_platform\_version) | Platform version on which to run your service. Only applicable for `launch_type` set to `FARGATE`. Defaults to `LATEST` | `string` | `null` | no |
| <a name="input_propagate_tags"></a> [propagate\_tags](#input\_propagate\_tags) | Specifies whether to propagate the tags from the task definition or the service to the tasks. The valid values are `SERVICE` and `TASK_DEFINITION` | `string` | `null` | no |
| <a name="input_proxy_configuration"></a> [proxy\_configuration](#input\_proxy\_configuration) | Configuration block for the App Mesh proxy | `any` | `{}` | no |
@@ -288,6 +288,7 @@ module "ecs_service" {
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | List of subnets to associate with the task or service | `list(string)` | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no |
| <a name="input_task_definition_arn"></a> [task\_definition\_arn](#input\_task\_definition\_arn) | Existing task definition ARN. Required when `create_task_definition` is `false` | `string` | `null` | no |
| <a name="input_task_definition_placement_constraints"></a> [task\_definition\_placement\_constraints](#input\_task\_definition\_placement\_constraints) | Configuration block for rules that are taken into consideration during task placement (up to max of 10). This is set at the task definition, see `placement_constraints` for setting at the service | `any` | `{}` | no |
| <a name="input_task_exec_iam_role_arn"></a> [task\_exec\_iam\_role\_arn](#input\_task\_exec\_iam\_role\_arn) | Existing IAM role ARN | `string` | `null` | no |
| <a name="input_task_exec_iam_role_description"></a> [task\_exec\_iam\_role\_description](#input\_task\_exec\_iam\_role\_description) | Description of the role | `string` | `null` | no |
| <a name="input_task_exec_iam_role_name"></a> [task\_exec\_iam\_role\_name](#input\_task\_exec\_iam\_role\_name) | Name to use on IAM role created | `string` | `null` | no |
2 changes: 1 addition & 1 deletion modules/service/main.tf
Original file line number Diff line number Diff line change
@@ -639,7 +639,7 @@ resource "aws_ecs_task_definition" "this" {
pid_mode = var.pid_mode

dynamic "placement_constraints" {
for_each = var.placement_constraints
for_each = var.task_definition_placement_constraints

content {
expression = try(placement_constraints.value.expression, null)
13 changes: 6 additions & 7 deletions modules/service/variables.tf
Original file line number Diff line number Diff line change
@@ -135,7 +135,7 @@ variable "ordered_placement_strategy" {
}

variable "placement_constraints" {
description = "Configuration block for rules that are taken into consideration during task placement (up to max of 10)"
description = "Configuration block for rules that are taken into consideration during task placement (up to max of 10). This is set at the service, see `task_definition_placement_constraints` for setting at the task definition"
type = any
default = {}
}
@@ -322,12 +322,11 @@ variable "pid_mode" {
default = null
}

# Shared between service and task definition
# variable "placement_constraints" {
# description = "Configuration block for rules that are taken into consideration during task placement (up to max of 10)"
# type = any
# default = {}
# }
variable "task_definition_placement_constraints" {
description = "Configuration block for rules that are taken into consideration during task placement (up to max of 10). This is set at the task definition, see `placement_constraints` for setting at the service"
type = any
default = {}
}

variable "proxy_configuration" {
description = "Configuration block for the App Mesh proxy"
109 changes: 55 additions & 54 deletions wrappers/service/main.tf
Original file line number Diff line number Diff line change
@@ -3,60 +3,61 @@ module "wrapper" {

for_each = var.items

create = try(each.value.create, var.defaults.create, true)
tags = try(each.value.tags, var.defaults.tags, {})
ignore_task_definition_changes = try(each.value.ignore_task_definition_changes, var.defaults.ignore_task_definition_changes, false)
alarms = try(each.value.alarms, var.defaults.alarms, {})
capacity_provider_strategy = try(each.value.capacity_provider_strategy, var.defaults.capacity_provider_strategy, {})
cluster_arn = try(each.value.cluster_arn, var.defaults.cluster_arn, "")
deployment_circuit_breaker = try(each.value.deployment_circuit_breaker, var.defaults.deployment_circuit_breaker, {})
deployment_controller = try(each.value.deployment_controller, var.defaults.deployment_controller, {})
deployment_maximum_percent = try(each.value.deployment_maximum_percent, var.defaults.deployment_maximum_percent, 200)
deployment_minimum_healthy_percent = try(each.value.deployment_minimum_healthy_percent, var.defaults.deployment_minimum_healthy_percent, 66)
desired_count = try(each.value.desired_count, var.defaults.desired_count, 1)
enable_ecs_managed_tags = try(each.value.enable_ecs_managed_tags, var.defaults.enable_ecs_managed_tags, true)
enable_execute_command = try(each.value.enable_execute_command, var.defaults.enable_execute_command, false)
force_new_deployment = try(each.value.force_new_deployment, var.defaults.force_new_deployment, true)
health_check_grace_period_seconds = try(each.value.health_check_grace_period_seconds, var.defaults.health_check_grace_period_seconds, null)
launch_type = try(each.value.launch_type, var.defaults.launch_type, "FARGATE")
load_balancer = try(each.value.load_balancer, var.defaults.load_balancer, {})
name = try(each.value.name, var.defaults.name, null)
assign_public_ip = try(each.value.assign_public_ip, var.defaults.assign_public_ip, false)
security_group_ids = try(each.value.security_group_ids, var.defaults.security_group_ids, [])
subnet_ids = try(each.value.subnet_ids, var.defaults.subnet_ids, [])
ordered_placement_strategy = try(each.value.ordered_placement_strategy, var.defaults.ordered_placement_strategy, {})
placement_constraints = try(each.value.placement_constraints, var.defaults.placement_constraints, {})
platform_version = try(each.value.platform_version, var.defaults.platform_version, null)
propagate_tags = try(each.value.propagate_tags, var.defaults.propagate_tags, null)
scheduling_strategy = try(each.value.scheduling_strategy, var.defaults.scheduling_strategy, null)
service_connect_configuration = try(each.value.service_connect_configuration, var.defaults.service_connect_configuration, {})
service_registries = try(each.value.service_registries, var.defaults.service_registries, {})
timeouts = try(each.value.timeouts, var.defaults.timeouts, {})
triggers = try(each.value.triggers, var.defaults.triggers, {})
wait_for_steady_state = try(each.value.wait_for_steady_state, var.defaults.wait_for_steady_state, null)
create_iam_role = try(each.value.create_iam_role, var.defaults.create_iam_role, true)
iam_role_arn = try(each.value.iam_role_arn, var.defaults.iam_role_arn, null)
iam_role_name = try(each.value.iam_role_name, var.defaults.iam_role_name, null)
iam_role_use_name_prefix = try(each.value.iam_role_use_name_prefix, var.defaults.iam_role_use_name_prefix, true)
iam_role_path = try(each.value.iam_role_path, var.defaults.iam_role_path, null)
iam_role_description = try(each.value.iam_role_description, var.defaults.iam_role_description, null)
iam_role_permissions_boundary = try(each.value.iam_role_permissions_boundary, var.defaults.iam_role_permissions_boundary, null)
iam_role_tags = try(each.value.iam_role_tags, var.defaults.iam_role_tags, {})
iam_role_statements = try(each.value.iam_role_statements, var.defaults.iam_role_statements, {})
create_task_definition = try(each.value.create_task_definition, var.defaults.create_task_definition, true)
task_definition_arn = try(each.value.task_definition_arn, var.defaults.task_definition_arn, null)
container_definitions = try(each.value.container_definitions, var.defaults.container_definitions, {})
container_definition_defaults = try(each.value.container_definition_defaults, var.defaults.container_definition_defaults, {})
cpu = try(each.value.cpu, var.defaults.cpu, 1024)
ephemeral_storage = try(each.value.ephemeral_storage, var.defaults.ephemeral_storage, {})
family = try(each.value.family, var.defaults.family, null)
inference_accelerator = try(each.value.inference_accelerator, var.defaults.inference_accelerator, {})
ipc_mode = try(each.value.ipc_mode, var.defaults.ipc_mode, null)
memory = try(each.value.memory, var.defaults.memory, 2048)
network_mode = try(each.value.network_mode, var.defaults.network_mode, "awsvpc")
pid_mode = try(each.value.pid_mode, var.defaults.pid_mode, null)
proxy_configuration = try(each.value.proxy_configuration, var.defaults.proxy_configuration, {})
requires_compatibilities = try(each.value.requires_compatibilities, var.defaults.requires_compatibilities, ["FARGATE"])
create = try(each.value.create, var.defaults.create, true)
tags = try(each.value.tags, var.defaults.tags, {})
ignore_task_definition_changes = try(each.value.ignore_task_definition_changes, var.defaults.ignore_task_definition_changes, false)
alarms = try(each.value.alarms, var.defaults.alarms, {})
capacity_provider_strategy = try(each.value.capacity_provider_strategy, var.defaults.capacity_provider_strategy, {})
cluster_arn = try(each.value.cluster_arn, var.defaults.cluster_arn, "")
deployment_circuit_breaker = try(each.value.deployment_circuit_breaker, var.defaults.deployment_circuit_breaker, {})
deployment_controller = try(each.value.deployment_controller, var.defaults.deployment_controller, {})
deployment_maximum_percent = try(each.value.deployment_maximum_percent, var.defaults.deployment_maximum_percent, 200)
deployment_minimum_healthy_percent = try(each.value.deployment_minimum_healthy_percent, var.defaults.deployment_minimum_healthy_percent, 66)
desired_count = try(each.value.desired_count, var.defaults.desired_count, 1)
enable_ecs_managed_tags = try(each.value.enable_ecs_managed_tags, var.defaults.enable_ecs_managed_tags, true)
enable_execute_command = try(each.value.enable_execute_command, var.defaults.enable_execute_command, false)
force_new_deployment = try(each.value.force_new_deployment, var.defaults.force_new_deployment, true)
health_check_grace_period_seconds = try(each.value.health_check_grace_period_seconds, var.defaults.health_check_grace_period_seconds, null)
launch_type = try(each.value.launch_type, var.defaults.launch_type, "FARGATE")
load_balancer = try(each.value.load_balancer, var.defaults.load_balancer, {})
name = try(each.value.name, var.defaults.name, null)
assign_public_ip = try(each.value.assign_public_ip, var.defaults.assign_public_ip, false)
security_group_ids = try(each.value.security_group_ids, var.defaults.security_group_ids, [])
subnet_ids = try(each.value.subnet_ids, var.defaults.subnet_ids, [])
ordered_placement_strategy = try(each.value.ordered_placement_strategy, var.defaults.ordered_placement_strategy, {})
placement_constraints = try(each.value.placement_constraints, var.defaults.placement_constraints, {})
platform_version = try(each.value.platform_version, var.defaults.platform_version, null)
propagate_tags = try(each.value.propagate_tags, var.defaults.propagate_tags, null)
scheduling_strategy = try(each.value.scheduling_strategy, var.defaults.scheduling_strategy, null)
service_connect_configuration = try(each.value.service_connect_configuration, var.defaults.service_connect_configuration, {})
service_registries = try(each.value.service_registries, var.defaults.service_registries, {})
timeouts = try(each.value.timeouts, var.defaults.timeouts, {})
triggers = try(each.value.triggers, var.defaults.triggers, {})
wait_for_steady_state = try(each.value.wait_for_steady_state, var.defaults.wait_for_steady_state, null)
create_iam_role = try(each.value.create_iam_role, var.defaults.create_iam_role, true)
iam_role_arn = try(each.value.iam_role_arn, var.defaults.iam_role_arn, null)
iam_role_name = try(each.value.iam_role_name, var.defaults.iam_role_name, null)
iam_role_use_name_prefix = try(each.value.iam_role_use_name_prefix, var.defaults.iam_role_use_name_prefix, true)
iam_role_path = try(each.value.iam_role_path, var.defaults.iam_role_path, null)
iam_role_description = try(each.value.iam_role_description, var.defaults.iam_role_description, null)
iam_role_permissions_boundary = try(each.value.iam_role_permissions_boundary, var.defaults.iam_role_permissions_boundary, null)
iam_role_tags = try(each.value.iam_role_tags, var.defaults.iam_role_tags, {})
iam_role_statements = try(each.value.iam_role_statements, var.defaults.iam_role_statements, {})
create_task_definition = try(each.value.create_task_definition, var.defaults.create_task_definition, true)
task_definition_arn = try(each.value.task_definition_arn, var.defaults.task_definition_arn, null)
container_definitions = try(each.value.container_definitions, var.defaults.container_definitions, {})
container_definition_defaults = try(each.value.container_definition_defaults, var.defaults.container_definition_defaults, {})
cpu = try(each.value.cpu, var.defaults.cpu, 1024)
ephemeral_storage = try(each.value.ephemeral_storage, var.defaults.ephemeral_storage, {})
family = try(each.value.family, var.defaults.family, null)
inference_accelerator = try(each.value.inference_accelerator, var.defaults.inference_accelerator, {})
ipc_mode = try(each.value.ipc_mode, var.defaults.ipc_mode, null)
memory = try(each.value.memory, var.defaults.memory, 2048)
network_mode = try(each.value.network_mode, var.defaults.network_mode, "awsvpc")
pid_mode = try(each.value.pid_mode, var.defaults.pid_mode, null)
task_definition_placement_constraints = try(each.value.task_definition_placement_constraints, var.defaults.task_definition_placement_constraints, {})
proxy_configuration = try(each.value.proxy_configuration, var.defaults.proxy_configuration, {})
requires_compatibilities = try(each.value.requires_compatibilities, var.defaults.requires_compatibilities, ["FARGATE"])
runtime_platform = try(each.value.runtime_platform, var.defaults.runtime_platform, {
operating_system_family = "LINUX"
cpu_architecture = "X86_64"