Skip to content

feat: Add support for availability zone rebalancing (#262) #269

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
merged 2 commits into from
Mar 21, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 2 additions & 1 deletion examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ module "ecs" {
}
]

subnet_ids = module.vpc.private_subnets
subnet_ids = module.vpc.private_subnets
availability_zone_rebalancing = "ENABLED"
security_group_rules = {
alb_ingress_3000 = {
type = "ingress"
Expand Down
1 change: 1 addition & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ module "service" {
# Service
ignore_task_definition_changes = try(each.value.ignore_task_definition_changes, false)
alarms = try(each.value.alarms, {})
availability_zone_rebalancing = try(each.value.availability_zone_rebalancing, "DISABLED")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
availability_zone_rebalancing = try(each.value.availability_zone_rebalancing, "DISABLED")
availability_zone_rebalancing = try(each.value.availability_zone_rebalancing, null)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll fix.

capacity_provider_strategy = try(each.value.capacity_provider_strategy, {})
cluster_arn = module.cluster.arn
deployment_circuit_breaker = try(each.value.deployment_circuit_breaker, {})
Expand Down
4 changes: 2 additions & 2 deletions modules/service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ module "ecs_service" {
| <a name="input_autoscaling_min_capacity"></a> [autoscaling\_min\_capacity](#input\_autoscaling\_min\_capacity) | Minimum number of tasks to run in your service | `number` | `1` | no |
| <a name="input_autoscaling_policies"></a> [autoscaling\_policies](#input\_autoscaling\_policies) | Map of autoscaling policies to create for the service | `any` | <pre>{<br/> "cpu": {<br/> "policy_type": "TargetTrackingScaling",<br/> "target_tracking_scaling_policy_configuration": {<br/> "predefined_metric_specification": {<br/> "predefined_metric_type": "ECSServiceAverageCPUUtilization"<br/> }<br/> }<br/> },<br/> "memory": {<br/> "policy_type": "TargetTrackingScaling",<br/> "target_tracking_scaling_policy_configuration": {<br/> "predefined_metric_specification": {<br/> "predefined_metric_type": "ECSServiceAverageMemoryUtilization"<br/> }<br/> }<br/> }<br/>}</pre> | no |
| <a name="input_autoscaling_scheduled_actions"></a> [autoscaling\_scheduled\_actions](#input\_autoscaling\_scheduled\_actions) | Map of autoscaling scheduled actions to create for the service | <pre>map(object({<br/> name = optional(string)<br/> min_capacity = number<br/> max_capacity = number<br/> schedule = string<br/> start_time = optional(string)<br/> end_time = optional(string)<br/> timezone = optional(string)<br/> }))</pre> | `null` | no |
| <a name="input_availability_zone_rebalancing"></a> [availability\_zone\_rebalancing](#input\_availability\_zone\_rebalancing) | ECS automatically redistributes tasks within a service across Availability Zones (AZs) to mitigate the risk of impaired application availability due to underlying infrastructure failures and task lifecycle activities. The valid values are `ENABLED` and `DISABLED`. Defaults to `DISABLED` | `string` | `null` | no |
| <a name="input_availability_zone_rebalancing"></a> [availability\_zone\_rebalancing](#input\_availability\_zone\_rebalancing) | ECS automatically redistributes tasks within a service across Availability Zones (AZs) to mitigate the risk of impaired application availability due to underlying infrastructure failures and task lifecycle activities. The valid values are `ENABLED` and `DISABLED`. Defaults to `DISABLED` | `string` | `"DISABLED"` | no |
| <a name="input_capacity_provider_strategy"></a> [capacity\_provider\_strategy](#input\_capacity\_provider\_strategy) | Capacity provider strategies to use for the service. Can be one or more | <pre>map(object({<br/> base = optional(number)<br/> capacity_provider = string<br/> weight = optional(number)<br/> }))</pre> | `null` | no |
| <a name="input_cluster_arn"></a> [cluster\_arn](#input\_cluster\_arn) | ARN of the ECS cluster where the resources will be provisioned | `string` | `""` | no |
| <a name="input_container_definition_defaults"></a> [container\_definition\_defaults](#input\_container\_definition\_defaults) | A map of default values for [container definitions](http://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerDefinition.html) created by `container_definitions` | `any` | `{}` | no |
Expand Down Expand Up @@ -340,7 +340,7 @@ module "ecs_service" {
| <a name="input_track_latest"></a> [track\_latest](#input\_track\_latest) | Whether should track latest `ACTIVE` task definition on AWS or the one created with the resource stored in state. Default is `false`. Useful in the event the task definition is modified outside of this resource | `bool` | `true` | no |
| <a name="input_triggers"></a> [triggers](#input\_triggers) | Map of arbitrary keys and values that, when changed, will trigger an in-place update (redeployment). Useful with `timestamp()` | `map(string)` | `null` | no |
| <a name="input_volume"></a> [volume](#input\_volume) | Configuration block for volumes that containers in your task may use | <pre>map(object({<br/> configure_at_launch = optional(bool)<br/> docker_volume_configuration = optional(object({<br/> autoprovision = optional(bool)<br/> driver = optional(string)<br/> driver_opts = optional(map(string))<br/> labels = optional(map(string))<br/> scope = optional(string)<br/> }))<br/> efs_volume_configuration = optional(object({<br/> authorization_config = optional(object({<br/> access_point_id = optional(string)<br/> iam = optional(string)<br/> }))<br/> file_system_id = string<br/> root_directory = optional(string)<br/> transit_encryption = optional(string)<br/> transit_encryption_port = optional(number)<br/> }))<br/> fsx_windows_file_server_volume_configuration = optional(object({<br/> authorization_config = optional(object({<br/> credentials_parameter = string<br/> domain = string<br/> }))<br/> file_system_id = string<br/> root_directory = string<br/> }))<br/> host_path = optional(string)<br/> name = optional(string)<br/> }))</pre> | `null` | no |
| <a name="input_volume_configuration"></a> [volume\_configuration](#input\_volume\_configuration) | Configuration for a volume specified in the task definition as a volume that is configured at launch time | <pre>object({<br/> name = string<br/> managed_ebs_volume = list(object({<br/> encrypted = optional(bool)<br/> file_system_type = optional(string)<br/> iops = optional(number)<br/> kms_key_id = optional(string)<br/> size_in_gb = optional(number)<br/> snapshot_id = optional(string)<br/> throughput = optional(number)<br/> volume_type = optional(string)<br/> tag_specification = optional(list(object({<br/> resource_type = string<br/> propagate_tags = optional(string, "TASK_DEFINITION")<br/> tags = optional(map(string))<br/> })))<br/> }))<br/> })</pre> | `null` | no |
| <a name="input_volume_configuration"></a> [volume\_configuration](#input\_volume\_configuration) | Configuration for a volume specified in the task definition as a volume that is configured at launch time | <pre>object({<br/> name = string<br/> managed_ebs_volume = list(object({<br/> encrypted = optional(bool)<br/> file_system_type = optional(string)<br/> iops = optional(number)<br/> kms_key_id = optional(string)<br/> size_in_gb = optional(number)<br/> snapshot_id = optional(string)<br/> throughput = optional(number)<br/> volume_type = optional(string)<br/> tag_specifications = optional(list(object({<br/> resource_type = string<br/> propagate_tags = optional(string, "TASK_DEFINITION")<br/> tags = optional(map(string))<br/> })))<br/> }))<br/> })</pre> | `null` | no |
| <a name="input_vpc_lattice_configurations"></a> [vpc\_lattice\_configurations](#input\_vpc\_lattice\_configurations) | The VPC Lattice configuration for your service that allows Lattice to connect, secure, and monitor your service across multiple accounts and VPCs | <pre>object({<br/> role_arn = string<br/> target_group_arn = string<br/> port_name = string<br/> })</pre> | `null` | no |
| <a name="input_wait_for_steady_state"></a> [wait\_for\_steady\_state](#input\_wait\_for\_steady\_state) | If true, Terraform will wait for the service to reach a steady state before continuing. Default is `false` | `bool` | `null` | no |
| <a name="input_wait_until_stable"></a> [wait\_until\_stable](#input\_wait\_until\_stable) | Whether terraform should wait until the task set has reached `STEADY_STATE` | `bool` | `null` | no |
Expand Down
2 changes: 1 addition & 1 deletion modules/service/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ variable "alarms" {
variable "availability_zone_rebalancing" {
description = " ECS automatically redistributes tasks within a service across Availability Zones (AZs) to mitigate the risk of impaired application availability due to underlying infrastructure failures and task lifecycle activities. The valid values are `ENABLED` and `DISABLED`. Defaults to `DISABLED`"
type = string
default = null
default = "DISABLED"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert, should be null

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

}

variable "capacity_provider_strategy" {
Expand Down
4 changes: 2 additions & 2 deletions wrappers/service/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module "wrapper" {
}
})
autoscaling_scheduled_actions = try(each.value.autoscaling_scheduled_actions, var.defaults.autoscaling_scheduled_actions, null)
availability_zone_rebalancing = try(each.value.availability_zone_rebalancing, var.defaults.availability_zone_rebalancing, null)
availability_zone_rebalancing = try(each.value.availability_zone_rebalancing, var.defaults.availability_zone_rebalancing, "DISABLED")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

capacity_provider_strategy = try(each.value.capacity_provider_strategy, var.defaults.capacity_provider_strategy, null)
cluster_arn = try(each.value.cluster_arn, var.defaults.cluster_arn, "")
container_definition_defaults = try(each.value.container_definition_defaults, var.defaults.container_definition_defaults, {})
Expand Down Expand Up @@ -120,6 +120,7 @@ module "wrapper" {
task_exec_iam_statements = try(each.value.task_exec_iam_statements, var.defaults.task_exec_iam_statements, null)
task_exec_secret_arns = try(each.value.task_exec_secret_arns, var.defaults.task_exec_secret_arns, ["arn:aws:secretsmanager:*:*:secret:*"])
task_exec_ssm_param_arns = try(each.value.task_exec_ssm_param_arns, var.defaults.task_exec_ssm_param_arns, ["arn:aws:ssm:*:*:parameter/*"])
task_tags = try(each.value.task_tags, var.defaults.task_tags, {})
tasks_iam_role_arn = try(each.value.tasks_iam_role_arn, var.defaults.tasks_iam_role_arn, null)
tasks_iam_role_description = try(each.value.tasks_iam_role_description, var.defaults.tasks_iam_role_description, null)
tasks_iam_role_name = try(each.value.tasks_iam_role_name, var.defaults.tasks_iam_role_name, null)
Expand All @@ -129,7 +130,6 @@ module "wrapper" {
tasks_iam_role_statements = try(each.value.tasks_iam_role_statements, var.defaults.tasks_iam_role_statements, null)
tasks_iam_role_tags = try(each.value.tasks_iam_role_tags, var.defaults.tasks_iam_role_tags, {})
tasks_iam_role_use_name_prefix = try(each.value.tasks_iam_role_use_name_prefix, var.defaults.tasks_iam_role_use_name_prefix, true)
task_tags = try(each.value.task_tags, var.defaults.task_tags, {})
timeouts = try(each.value.timeouts, var.defaults.timeouts, null)
track_latest = try(each.value.track_latest, var.defaults.track_latest, true)
triggers = try(each.value.triggers, var.defaults.triggers, null)
Expand Down