Skip to content
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

feat: Add support for aws_autoscaling_policy #175

22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Available features
- Autoscaling group with launch template - either created by the module or utilizing an existing launch template
- Autoscaling group utilizing mixed instances policy
- Ability to configure autoscaling groups to set instance refresh configuration and add lifecycle hooks
- Ability to configure autoscaling policies

## Usage

Expand Down Expand Up @@ -222,6 +223,23 @@ The following combinations are supported to conditionally create resources and/o
launch_template = aws_launch_template.my_launch_template.name
```

- Create the autoscaling policies:

```
scaling_policies = {
my-policy = {
policy_type = "TargetTrackingScaling"
target_tracking_configuration = {
predefined_metric_specification = {
predefined_metric_type = "ASGAverageCPUUtilization"
resource_label = "MyLabel"
}
target_value = 50.0
}
}
}
```

## Tags

There are two ways to specify tags for auto-scaling group in this module - `tags` and `tags_as_map`.
Expand Down Expand Up @@ -273,6 +291,7 @@ No modules.
| Name | Type |
|------|------|
| [aws_autoscaling_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group) | resource |
| [aws_autoscaling_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_policy) | resource |
| [aws_autoscaling_schedule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_schedule) | resource |
| [aws_launch_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_configuration) | resource |
| [aws_launch_template.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource |
Expand All @@ -291,6 +310,7 @@ No modules.
| <a name="input_create_asg"></a> [create\_asg](#input\_create\_asg) | Determines whether to create autoscaling group or not | `bool` | `true` | no |
| <a name="input_create_lc"></a> [create\_lc](#input\_create\_lc) | Determines whether to create launch configuration or not | `bool` | `false` | no |
| <a name="input_create_lt"></a> [create\_lt](#input\_create\_lt) | Determines whether to create launch template or not | `bool` | `false` | no |
| <a name="input_create_scaling_policy"></a> [create\_scaling\_policy](#input\_create\_scaling\_policy) | Determines whether to create target scaling policy schedule or not | `bool` | `true` | no |
| <a name="input_create_schedule"></a> [create\_schedule](#input\_create\_schedule) | Determines whether to create autoscaling group schedule or not | `bool` | `true` | no |
| <a name="input_credit_specification"></a> [credit\_specification](#input\_credit\_specification) | (LT) Customize the credit specification of the instance | `map(string)` | `null` | no |
| <a name="input_default_cooldown"></a> [default\_cooldown](#input\_default\_cooldown) | The amount of time, in seconds, after a scaling activity completes before another scaling activity can start | `number` | `null` | no |
Expand Down Expand Up @@ -347,6 +367,7 @@ No modules.
| <a name="input_protect_from_scale_in"></a> [protect\_from\_scale\_in](#input\_protect\_from\_scale\_in) | Allows setting instance protection. The autoscaling group will not select instances with this setting for termination during scale in events. | `bool` | `false` | no |
| <a name="input_ram_disk_id"></a> [ram\_disk\_id](#input\_ram\_disk\_id) | (LT) The ID of the ram disk | `string` | `null` | no |
| <a name="input_root_block_device"></a> [root\_block\_device](#input\_root\_block\_device) | (LC) Customize details about the root block device of the instance | `list(map(string))` | `[]` | no |
| <a name="input_scaling_policies"></a> [scaling\_policies](#input\_scaling\_policies) | Map of target scaling policy schedule to create | `map(any)` | `{}` | no |
| <a name="input_schedules"></a> [schedules](#input\_schedules) | Map of autoscaling group schedule to create | `map(any)` | `{}` | no |
| <a name="input_security_groups"></a> [security\_groups](#input\_security\_groups) | A list of security group IDs to associate | `list(string)` | `null` | no |
| <a name="input_service_linked_role_arn"></a> [service\_linked\_role\_arn](#input\_service\_linked\_role\_arn) | The ARN of the service-linked role that the ASG will use to call other AWS services | `string` | `null` | no |
Expand Down Expand Up @@ -386,6 +407,7 @@ No modules.
| <a name="output_autoscaling_group_name"></a> [autoscaling\_group\_name](#output\_autoscaling\_group\_name) | The autoscaling group name |
| <a name="output_autoscaling_group_target_group_arns"></a> [autoscaling\_group\_target\_group\_arns](#output\_autoscaling\_group\_target\_group\_arns) | List of Target Group ARNs that apply to this AutoScaling Group |
| <a name="output_autoscaling_group_vpc_zone_identifier"></a> [autoscaling\_group\_vpc\_zone\_identifier](#output\_autoscaling\_group\_vpc\_zone\_identifier) | The VPC zone identifier |
| <a name="output_autoscaling_policies"></a> [autoscaling\_policies](#output\_autoscaling\_policies) | ARNs of autoscaling policies |
| <a name="output_autoscaling_schedule_arns"></a> [autoscaling\_schedule\_arns](#output\_autoscaling\_schedule\_arns) | ARNs of autoscaling group schedules |
| <a name="output_launch_configuration_arn"></a> [launch\_configuration\_arn](#output\_launch\_configuration\_arn) | The ARN of the launch configuration |
| <a name="output_launch_configuration_id"></a> [launch\_configuration\_id](#output\_launch\_configuration\_id) | The ID of the launch configuration |
Expand Down
33 changes: 33 additions & 0 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,39 @@ module "complete_lt" {
end_time = "2032-01-01T16:00:00Z"
}
}
# Target scaling policy schedule based on average CPU load
scaling_policies = {
avg-cpu-policy-greater-than-50 = {
Sudokamikaze marked this conversation as resolved.
Show resolved Hide resolved
policy_type = "TargetTrackingScaling"
estimated_instance_warmup = 1200
target_tracking_configuration = {
predefined_metric_specification = {
predefined_metric_type = "ASGAverageCPUUtilization"
}
target_value = 50.0
}
},
predictive-scaling = {
policy_type = "PredictiveScaling"
predictive_scaling_config = {
metric_specification = {
target_value = 32
predefined_scaling_metric_specification = {
predefined_metric_type = "ASGAverageCPUUtilization"
resource_label = "testLabel"
}
predefined_load_metric_specification = {
predefined_metric_type = "ASGTotalCPUUtilization"
resource_label = "testLabel"
}
}
mode = "ForecastAndScale"
scheduling_buffer_time = 10
max_capacity_breach_behavior = "IncreaseMaxCapacity"
max_capacity_buffer = 10
}
}
}
}

# Launch configuration
Expand Down
102 changes: 102 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -473,3 +473,105 @@ resource "aws_autoscaling_schedule" "this" {
# Cron examples: https://crontab.guru/examples.html
recurrence = lookup(each.value, "recurrence", null)
}

################################################################################
# Autoscaling Policy
################################################################################
resource "aws_autoscaling_policy" "this" {
for_each = { for k, v in var.scaling_policies : k => v if var.create_asg && var.create_scaling_policy }

name = lookup(each.value, "name", each.key)
autoscaling_group_name = aws_autoscaling_group.this[0].name

adjustment_type = lookup(each.value, "adjustment_type", null)
policy_type = lookup(each.value, "policy_type", null)
estimated_instance_warmup = lookup(each.value, "estimated_instance_warmup", null)
cooldown = lookup(each.value, "cooldown", null)
min_adjustment_magnitude = lookup(each.value, "min_adjustment_magnitude", null)
metric_aggregation_type = lookup(each.value, "metric_aggregation_type", null)

dynamic "step_adjustment" {
for_each = lookup(each.value, "step_adjustment", null) != null ? [each.value.step_adjustment] : []
content {
scaling_adjustment = step_adjustment.value.scaling_adjustment
metric_interval_lower_bound = lookup(step_adjustment.value, "metric_interval_lower_bound", null)
metric_interval_upper_bound = lookup(step_adjustment.value, "metric_interval_upper_bound", null)
}
}

dynamic "target_tracking_configuration" {
for_each = lookup(each.value, "target_tracking_configuration", null) != null ? [each.value.target_tracking_configuration] : []
content {
target_value = target_tracking_configuration.value.target_value
disable_scale_in = lookup(target_tracking_configuration.value, "disable_scale_in", null)

dynamic "predefined_metric_specification" {
for_each = lookup(target_tracking_configuration.value, "predefined_metric_specification", null) != null ? [target_tracking_configuration.value.predefined_metric_specification] : []
content {
predefined_metric_type = predefined_metric_specification.value.predefined_metric_type
}
}

dynamic "customized_metric_specification" {
for_each = lookup(target_tracking_configuration.value, "customized_metric_specification", null) != null ? [target_tracking_configuration.value.customized_metric_specification] : []
content {

dynamic "metric_dimension" {
for_each = lookup(customized_metric_specification.value, "metric_dimension", null) != null ? [customized_metric_specification.value.metric_dimension] : []
content {
name = lookup(metric_dimension.value, "name", null)
value = lookup(metric_dimension.value, "value", null)
}
}

metric_name = customized_metric_specification.value.metric_name
namespace = customized_metric_specification.value.namespace
statistic = customized_metric_specification.value.statistic
unit = lookup(customized_metric_specification.value, "unit", null)
}
}
}
}

dynamic "predictive_scaling_configuration" {
for_each = lookup(each.value, "predictive_scaling_configuration", null) != null ? [each.value.predictive_scaling_configuration] : []
content {
max_capacity_breach_behavior = lookup(predictive_scaling_configuration.value, "max_capacity_breach_behavior", null)
max_capacity_buffer = lookup(predictive_scaling_configuration.value, "max_capacity_buffer", null)
mode = lookup(predictive_scaling_configuration.value, "mode", null)
scheduling_buffer_time = lookup(predictive_scaling_configuration.value, "scheduling_buffer_time", null)

dynamic "metric_specification" {
Sudokamikaze marked this conversation as resolved.
Show resolved Hide resolved
for_each = lookup(predictive_scaling_configuration.value, "metric_specification", [])
content {
target_value = metric_specification.value.target_value

dynamic "predefined_load_metric_specification" {
for_each = lookup(metric_specification.value, "predefined_load_metric_specification", null) != null ? [metric_specification.value.predefined_load_metric_specification] : []
content {
predefined_metric_type = predefined_load_metric_specification.value.predefined_metric_type
resource_label = predefined_load_metric_specification.value.resource_label
}
}

dynamic "predefined_metric_pair_specification" {
for_each = lookup(metric_specification.value, "predefined_metric_pair_specification", null) != null ? [metric_specification.value.predefined_metric_pair_specification] : []
content {
predefined_metric_type = predefined_metric_pair_specification.value.predefined_metric_type
resource_label = predefined_metric_pair_specification.value.resource_label
}
}

dynamic "predefined_scaling_metric_specification" {
for_each = lookup(metric_specification.value, "predefined_scaling_metric_specification", null) != null ? [metric_specification.value.predefined_scaling_metric_specification] : []
content {
predefined_metric_type = predefined_scaling_metric_specification.value.predefined_metric_type
resource_label = predefined_scaling_metric_specification.value.resource_label
}
}
}
}
}
}
}

9 changes: 9 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,12 @@ output "autoscaling_schedule_arns" {
description = "ARNs of autoscaling group schedules"
value = { for k, v in aws_autoscaling_schedule.this : k => v.arn }
}

################################################################################
# Autoscaling Policy
################################################################################

output "autoscaling_policies" {
Sudokamikaze marked this conversation as resolved.
Show resolved Hide resolved
Sudokamikaze marked this conversation as resolved.
Show resolved Hide resolved
description = "ARNs of autoscaling policies"
value = { for k, v in aws_autoscaling_policy.this : k => v.arn }
Sudokamikaze marked this conversation as resolved.
Show resolved Hide resolved
}
17 changes: 17 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -532,3 +532,20 @@ variable "schedules" {
type = map(any)
default = {}
}


################################################################################
# Target scaling policy schedule
Sudokamikaze marked this conversation as resolved.
Show resolved Hide resolved
################################################################################

variable "create_scaling_policy" {
description = "Determines whether to create target scaling policy schedule or not"
type = bool
default = true
}

variable "scaling_policies" {
description = "Map of target scaling policy schedule to create"
type = map(any)
Sudokamikaze marked this conversation as resolved.
Show resolved Hide resolved
default = {}
}