Skip to content

Commit f731feb

Browse files
feat: Add support for predictive autoscaling policies (#361)
* wip * add predefined metrics * add customized metrics support * fix pre-commit * apply suggestions sorting: - variables.tf, modules/service/{main,variables}.tf - all fields sorted to match fields on the AWS provider changes: - removed `try` blocks for `predictive_scaling_policy_configuration` arguments - metric_specification: object -> list(object) - metric_data_query.metric_stat: object -> list(object) - metric_data_query.metric_stat.metric: object -> list(object) - metric_data_query.metric_stat.metric and .namespace: became optional * fix arguments sorting for `modules/service/main.tf` * fix: Update variable defintions to match API, correct ordering --------- Co-authored-by: Bryant Biggs <[email protected]>
1 parent 284ed00 commit f731feb

File tree

11 files changed

+398
-8
lines changed

11 files changed

+398
-8
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

examples/complete/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Note that this example may create resources which will incur monetary charges on
3939

4040
| Name | Source | Version |
4141
|------|--------|---------|
42-
| <a name="module_alb"></a> [alb](#module\_alb) | terraform-aws-modules/alb/aws | ~> 9.0 |
42+
| <a name="module_alb"></a> [alb](#module\_alb) | terraform-aws-modules/alb/aws | ~> 10.0 |
4343
| <a name="module_autoscaling"></a> [autoscaling](#module\_autoscaling) | terraform-aws-modules/autoscaling/aws | ~> 9.0 |
4444
| <a name="module_autoscaling_sg"></a> [autoscaling\_sg](#module\_autoscaling\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 |
4545
| <a name="module_ecs"></a> [ecs](#module\_ecs) | ../../ | n/a |

examples/complete/main.tf

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,52 @@ module "ecs" {
6161
cpu = 1024
6262
memory = 4096
6363

64+
autoscaling_policies = {
65+
predictive = {
66+
policy_type = "PredictiveScaling"
67+
predictive_scaling_policy_configuration = {
68+
mode = "ForecastOnly"
69+
metric_specification = [{
70+
target_value = 60
71+
customized_scaling_metric_specification = {
72+
metric_data_query = [
73+
{
74+
id = "cpu_util"
75+
metric_stat = {
76+
stat = "Average"
77+
metric = {
78+
metric_name = "CPUUtilization"
79+
namespace = "AWS/ECS"
80+
dimension = [
81+
{
82+
name = "ServiceName"
83+
value = "ecsdemo-frontend"
84+
},
85+
{
86+
name = "ClusterName"
87+
value = "ex-complete"
88+
}
89+
]
90+
}
91+
}
92+
return_data = true
93+
}
94+
]
95+
}
96+
predefined_load_metric_specification = {
97+
predefined_metric_type = "ECSServiceTotalCPUUtilization"
98+
}
99+
# predefined_scaling_metric_specification = {
100+
# predefined_metric_type = "ECSServiceAverageMemoryUtilization"
101+
# }
102+
# predefined_metric_pair_specification = {
103+
# predefined_metric_type = "ECSServiceMemoryUtilization"
104+
# }
105+
}]
106+
}
107+
}
108+
}
109+
64110
# Container definition(s)
65111
container_definitions = {
66112

@@ -237,7 +283,7 @@ resource "aws_service_discovery_http_namespace" "this" {
237283

238284
module "alb" {
239285
source = "terraform-aws-modules/alb/aws"
240-
version = "~> 9.0"
286+
version = "~> 10.0"
241287

242288
name = local.name
243289

examples/ec2-autoscaling/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Note that this example may create resources which will incur monetary charges on
3939

4040
| Name | Source | Version |
4141
|------|--------|---------|
42-
| <a name="module_alb"></a> [alb](#module\_alb) | terraform-aws-modules/alb/aws | ~> 9.0 |
42+
| <a name="module_alb"></a> [alb](#module\_alb) | terraform-aws-modules/alb/aws | ~> 10.0 |
4343
| <a name="module_autoscaling"></a> [autoscaling](#module\_autoscaling) | terraform-aws-modules/autoscaling/aws | ~> 9.0 |
4444
| <a name="module_autoscaling_sg"></a> [autoscaling\_sg](#module\_autoscaling\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 |
4545
| <a name="module_ecs_cluster"></a> [ecs\_cluster](#module\_ecs\_cluster) | ../../modules/cluster | n/a |

examples/ec2-autoscaling/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ data "aws_ssm_parameter" "ecs_optimized_ami" {
184184

185185
module "alb" {
186186
source = "terraform-aws-modules/alb/aws"
187-
version = "~> 9.0"
187+
version = "~> 10.0"
188188

189189
name = local.name
190190

examples/fargate/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Note that this example may create resources which will incur monetary charges on
3939

4040
| Name | Source | Version |
4141
|------|--------|---------|
42-
| <a name="module_alb"></a> [alb](#module\_alb) | terraform-aws-modules/alb/aws | ~> 9.0 |
42+
| <a name="module_alb"></a> [alb](#module\_alb) | terraform-aws-modules/alb/aws | ~> 10.0 |
4343
| <a name="module_ecs_cluster"></a> [ecs\_cluster](#module\_ecs\_cluster) | ../../modules/cluster | n/a |
4444
| <a name="module_ecs_service"></a> [ecs\_service](#module\_ecs\_service) | ../../modules/service | n/a |
4545
| <a name="module_ecs_task_definition"></a> [ecs\_task\_definition](#module\_ecs\_task\_definition) | ../../modules/service | n/a |

examples/fargate/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ resource "aws_service_discovery_http_namespace" "this" {
280280

281281
module "alb" {
282282
source = "terraform-aws-modules/alb/aws"
283-
version = "~> 9.0"
283+
version = "~> 10.0"
284284

285285
name = local.name
286286

modules/service/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ module "ecs_service" {
233233
| <a name="input_assign_public_ip"></a> [assign\_public\_ip](#input\_assign\_public\_ip) | Assign a public IP address to the ENI (Fargate launch type only) | `bool` | `false` | no |
234234
| <a name="input_autoscaling_max_capacity"></a> [autoscaling\_max\_capacity](#input\_autoscaling\_max\_capacity) | Maximum number of tasks to run in your service | `number` | `10` | no |
235235
| <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 |
236-
| <a name="input_autoscaling_policies"></a> [autoscaling\_policies](#input\_autoscaling\_policies) | Map of autoscaling policies to create for the service | <pre>map(object({<br/> name = optional(string) # Will fall back to the key name if not provided<br/> policy_type = optional(string, "TargetTrackingScaling")<br/> step_scaling_policy_configuration = optional(object({<br/> adjustment_type = optional(string)<br/> cooldown = optional(number)<br/> metric_aggregation_type = optional(string)<br/> min_adjustment_magnitude = optional(number)<br/> step_adjustment = optional(list(object({<br/> metric_interval_lower_bound = optional(string)<br/> metric_interval_upper_bound = optional(string)<br/> scaling_adjustment = number<br/> })))<br/> }))<br/> target_tracking_scaling_policy_configuration = optional(object({<br/> customized_metric_specification = optional(object({<br/> dimensions = optional(list(object({<br/> name = string<br/> value = string<br/> })))<br/> metric_name = optional(string)<br/> metrics = optional(list(object({<br/> expression = optional(string)<br/> id = string<br/> label = optional(string)<br/> metric_stat = optional(object({<br/> metric = object({<br/> dimensions = optional(list(object({<br/> name = string<br/> value = string<br/> })))<br/> metric_name = string<br/> namespace = string<br/> })<br/> stat = string<br/> unit = optional(string)<br/> }))<br/> return_data = optional(bool)<br/> })))<br/> namespace = optional(string)<br/> statistic = optional(string)<br/> unit = optional(string)<br/> }))<br/> disable_scale_in = optional(bool)<br/> predefined_metric_specification = optional(object({<br/> predefined_metric_type = string<br/> resource_label = optional(string)<br/> }))<br/> scale_in_cooldown = optional(number, 300)<br/> scale_out_cooldown = optional(number, 60)<br/> target_value = optional(number, 75)<br/> }))<br/> }))</pre> | <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 |
236+
| <a name="input_autoscaling_policies"></a> [autoscaling\_policies](#input\_autoscaling\_policies) | Map of autoscaling policies to create for the service | <pre>map(object({<br/> name = optional(string) # Will fall back to the key name if not provided<br/> policy_type = optional(string, "TargetTrackingScaling")<br/> predictive_scaling_policy_configuration = optional(object({<br/> max_capacity_breach_behavior = optional(string)<br/> max_capacity_buffer = optional(number)<br/> metric_specification = list(object({<br/> customized_capacity_metric_specification = optional(object({<br/> metric_data_query = list(object({<br/> expression = optional(string)<br/> id = string<br/> label = optional(string)<br/> metric_stat = optional(object({<br/> metric = object({<br/> dimension = optional(list(object({<br/> name = string<br/> value = string<br/> })))<br/> metric_name = optional(string)<br/> namespace = optional(string)<br/> })<br/> stat = string<br/> unit = optional(string)<br/> }))<br/> return_data = optional(bool)<br/> }))<br/> }))<br/> customized_load_metric_specification = optional(object({<br/> metric_data_query = list(object({<br/> expression = optional(string)<br/> id = string<br/> label = optional(string)<br/> metric_stat = optional(object({<br/> metric = object({<br/> dimension = optional(list(object({<br/> name = string<br/> value = string<br/> })))<br/> metric_name = optional(string)<br/> namespace = optional(string)<br/> })<br/> stat = string<br/> unit = optional(string)<br/> }))<br/> return_data = optional(bool)<br/> }))<br/> }))<br/> customized_scaling_metric_specification = optional(object({<br/> metric_data_query = list(object({<br/> expression = optional(string)<br/> id = string<br/> label = optional(string)<br/> metric_stat = optional(object({<br/> metric = object({<br/> dimension = optional(list(object({<br/> name = string<br/> value = string<br/> })))<br/> metric_name = optional(string)<br/> namespace = optional(string)<br/> })<br/> stat = string<br/> unit = optional(string)<br/> }))<br/> return_data = optional(bool)<br/> }))<br/> }))<br/> predefined_load_metric_specification = optional(object({<br/> predefined_metric_type = string<br/> resource_label = optional(string)<br/> }))<br/> predefined_metric_pair_specification = optional(object({<br/> predefined_metric_type = string<br/> resource_label = optional(string)<br/> }))<br/> predefined_scaling_metric_specification = optional(object({<br/> predefined_metric_type = string<br/> resource_label = optional(string)<br/> }))<br/> target_value = number<br/> }))<br/> mode = optional(string)<br/> scheduling_buffer_time = optional(number)<br/> }))<br/> step_scaling_policy_configuration = optional(object({<br/> adjustment_type = optional(string)<br/> cooldown = optional(number)<br/> metric_aggregation_type = optional(string)<br/> min_adjustment_magnitude = optional(number)<br/> step_adjustment = optional(list(object({<br/> metric_interval_lower_bound = optional(string)<br/> metric_interval_upper_bound = optional(string)<br/> scaling_adjustment = number<br/> })))<br/> }))<br/> target_tracking_scaling_policy_configuration = optional(object({<br/> customized_metric_specification = optional(object({<br/> dimensions = optional(list(object({<br/> name = string<br/> value = string<br/> })))<br/> metric_name = optional(string)<br/> metrics = optional(list(object({<br/> expression = optional(string)<br/> id = string<br/> label = optional(string)<br/> metric_stat = optional(object({<br/> metric = object({<br/> dimensions = optional(list(object({<br/> name = string<br/> value = string<br/> })))<br/> metric_name = string<br/> namespace = string<br/> })<br/> stat = string<br/> unit = optional(string)<br/> }))<br/> return_data = optional(bool)<br/> })))<br/> namespace = optional(string)<br/> statistic = optional(string)<br/> unit = optional(string)<br/> }))<br/> disable_scale_in = optional(bool)<br/> predefined_metric_specification = optional(object({<br/> predefined_metric_type = string<br/> resource_label = optional(string)<br/> }))<br/> scale_in_cooldown = optional(number, 300)<br/> scale_out_cooldown = optional(number, 60)<br/> target_value = optional(number, 75)<br/> }))<br/> }))</pre> | <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 |
237237
| <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 |
238238
| <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 |
239239
| <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 |

0 commit comments

Comments
 (0)