Skip to content

Commit

Permalink
ECS Cluster time based autoscaling
Browse files Browse the repository at this point in the history
* Allows configuring time based autoscaling for the Infrastructure ECS
  Cluster's autoscaling group.
* Cron expressions can be provided to set the desired capacity to the
  min or max sizes. Custom scaling sizes can also be provided, to set
  the min/max sizes for a given cron expression (in which case the min
  size will be set as the desired capacity)
  • Loading branch information
Stretch96 committed Jan 2, 2024
1 parent 6f74e49 commit dec2006
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ This project creates and manages resources within an AWS account for infrastruct
| [aws_athena_workgroup.infrastructure_vpc_flow_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/athena_workgroup) | resource |
| [aws_autoscaling_group.infrastructure_ecs_cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group) | resource |
| [aws_autoscaling_lifecycle_hook.infrastructure_ecs_cluster_termination](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_lifecycle_hook) | resource |
| [aws_autoscaling_schedule.ecs_infrastructure_time_based_custom](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_schedule) | resource |
| [aws_autoscaling_schedule.ecs_infrastructure_time_based_max](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_schedule) | resource |
| [aws_autoscaling_schedule.ecs_infrastructure_time_based_min](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_schedule) | resource |
| [aws_cloudwatch_log_group.ecs_cluster_infrastructure_draining_lambda_log_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
| [aws_cloudwatch_log_group.infrastructure_vpc_flow_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
| [aws_default_network_acl.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_network_acl) | resource |
Expand Down Expand Up @@ -121,6 +124,9 @@ This project creates and manages resources within an AWS account for infrastruct
| <a name="input_infrastructure_dockerhub_email"></a> [infrastructure\_dockerhub\_email](#input\_infrastructure\_dockerhub\_email) | Dockerhub email | `string` | n/a | yes |
| <a name="input_infrastructure_dockerhub_token"></a> [infrastructure\_dockerhub\_token](#input\_infrastructure\_dockerhub\_token) | Dockerhub token which has permissions to pull images | `string` | n/a | yes |
| <a name="input_infrastructure_ecs_cluster_ami_version"></a> [infrastructure\_ecs\_cluster\_ami\_version](#input\_infrastructure\_ecs\_cluster\_ami\_version) | AMI version for ECS cluster instances (amzn2-ami-ecs-hvm-<version>) | `string` | n/a | yes |
| <a name="input_infrastructure_ecs_cluster_autoscaling_time_based_custom"></a> [infrastructure\_ecs\_cluster\_autoscaling\_time\_based\_custom](#input\_infrastructure\_ecs\_cluster\_autoscaling\_time\_based\_custom) | List of objects with min/max sizes and cron expressions to scale the ECS cluster. Min size will be used as desired. | <pre>list(<br> object({<br> cron = string<br> min = number<br> max = number<br> })<br> )</pre> | n/a | yes |
| <a name="input_infrastructure_ecs_cluster_autoscaling_time_based_max"></a> [infrastructure\_ecs\_cluster\_autoscaling\_time\_based\_max](#input\_infrastructure\_ecs\_cluster\_autoscaling\_time\_based\_max) | List of cron expressions to scale the ECS cluster to the configured max size | `list(string)` | n/a | yes |
| <a name="input_infrastructure_ecs_cluster_autoscaling_time_based_min"></a> [infrastructure\_ecs\_cluster\_autoscaling\_time\_based\_min](#input\_infrastructure\_ecs\_cluster\_autoscaling\_time\_based\_min) | List of cron expressions to scale the ECS cluster to the configured min size | `list(string)` | n/a | yes |
| <a name="input_infrastructure_ecs_cluster_draining_lambda_enabled"></a> [infrastructure\_ecs\_cluster\_draining\_lambda\_enabled](#input\_infrastructure\_ecs\_cluster\_draining\_lambda\_enabled) | Enable the Lambda which ensures all containers have drained before terminating ECS cluster instances | `bool` | n/a | yes |
| <a name="input_infrastructure_ecs_cluster_draining_lambda_log_retention"></a> [infrastructure\_ecs\_cluster\_draining\_lambda\_log\_retention](#input\_infrastructure\_ecs\_cluster\_draining\_lambda\_log\_retention) | Log retention for the ECS cluster draining Lambda | `number` | n/a | yes |
| <a name="input_infrastructure_ecs_cluster_ebs_docker_storage_volume_size"></a> [infrastructure\_ecs\_cluster\_ebs\_docker\_storage\_volume\_size](#input\_infrastructure\_ecs\_cluster\_ebs\_docker\_storage\_volume\_size) | Size of EBS volume for Docker storage on the infrastructure ECS instances | `number` | n/a | yes |
Expand Down
32 changes: 32 additions & 0 deletions ecs-cluster-infrastructure-autoscaling-time-based.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
resource "aws_autoscaling_schedule" "ecs_infrastructure_time_based_max" {
for_each = local.enable_infrastructure_ecs_cluster ? local.infrastructure_ecs_cluster_autoscaling_time_based_max : []

autoscaling_group_name = aws_autoscaling_group.infrastructure_ecs_cluster[0].name
scheduled_action_name = "${local.resource_prefix}-time-based-max ${each.value}"
desired_capacity = local.infrastructure_ecs_cluster_max_size
min_size = -1
max_size = -1
recurrence = each.value
}

resource "aws_autoscaling_schedule" "ecs_infrastructure_time_based_min" {
for_each = local.enable_infrastructure_ecs_cluster ? local.infrastructure_ecs_cluster_autoscaling_time_based_min : []

autoscaling_group_name = aws_autoscaling_group.infrastructure_ecs_cluster[0].name
scheduled_action_name = "${local.resource_prefix}-time-based-min ${each.value}"
desired_capacity = local.infrastructure_ecs_cluster_min_size
min_size = -1
max_size = -1
recurrence = each.value
}

resource "aws_autoscaling_schedule" "ecs_infrastructure_time_based_custom" {
for_each = local.enable_infrastructure_ecs_cluster ? local.infrastructure_ecs_cluster_autoscaling_time_based_custom : {}

autoscaling_group_name = aws_autoscaling_group.infrastructure_ecs_cluster[0].name
scheduled_action_name = "${local.resource_prefix}-time-based-custom ${each.value["cron"]} ${each.value["min"]}-${each.value["max"]}"
desired_capacity = each.value["min"]
min_size = each.value["min"]
max_size = each.value["max"]
recurrence = each.value["cron"]
}
5 changes: 5 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ locals {
infrastructure_ecs_cluster_min_size = var.infrastructure_ecs_cluster_min_size
infrastructure_ecs_cluster_max_size = var.infrastructure_ecs_cluster_max_size
infrastructure_ecs_cluster_max_instance_lifetime = var.infrastructure_ecs_cluster_max_instance_lifetime
infrastructure_ecs_cluster_autoscaling_time_based_max = toset(var.infrastructure_ecs_cluster_autoscaling_time_based_max)
infrastructure_ecs_cluster_autoscaling_time_based_min = toset(var.infrastructure_ecs_cluster_autoscaling_time_based_min)
infrastructure_ecs_cluster_autoscaling_time_based_custom = {
for custom in toset(var.infrastructure_ecs_cluster_autoscaling_time_based_custom) : "${custom["min"]}-${custom["max"]} ${custom["cron"]}" => custom
}
infrastructure_ecs_cluster_user_data = base64encode(
templatefile("ec2-userdata/ecs-instance.tpl", {
docker_storage_volume_device_name = local.infrastructure_ecs_cluster_ebs_docker_storage_volume_device_name,
Expand Down
21 changes: 21 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,24 @@ variable "infrastructure_ecs_cluster_max_instance_lifetime" {
description = "Maximum lifetime in seconds of an instance within the ECS cluster"
type = number
}

variable "infrastructure_ecs_cluster_autoscaling_time_based_max" {
description = "List of cron expressions to scale the ECS cluster to the configured max size"
type = list(string)
}

variable "infrastructure_ecs_cluster_autoscaling_time_based_min" {
description = "List of cron expressions to scale the ECS cluster to the configured min size"
type = list(string)
}

variable "infrastructure_ecs_cluster_autoscaling_time_based_custom" {
description = "List of objects with min/max sizes and cron expressions to scale the ECS cluster. Min size will be used as desired."
type = list(
object({
cron = string
min = number
max = number
})
)
}

0 comments on commit dec2006

Please sign in to comment.