Skip to content
Open
Show file tree
Hide file tree
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
16 changes: 16 additions & 0 deletions examples/complete/fixtures.us-east-2.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,19 @@ container_port_mappings = [

force_new_deployment = true
redeploy_on_apply = true

service_autoscaling_enabled = true
service_autoscaling_minimum_capacity = 1
service_autoscaling_maximum_capacity = 3
service_autoscaling_target_tracking_policies = {
cpu = {
predefined_metric_type = "ECSServiceAverageCPUUtilization"
target_value = 50
scale_out_cooldown = 60
scale_in_cooldown = 60
},
memory = {
predefined_metric_type = "ECSServiceAverageMemoryUtilization"
target_value = 80
}
}
52 changes: 28 additions & 24 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module "vpc" {

module "subnets" {
source = "cloudposse/dynamic-subnets/aws"
version = "2.1.0"
version = "2.4.2"

availability_zones = var.availability_zones
vpc_id = module.vpc.vpc_id
Expand Down Expand Up @@ -77,29 +77,33 @@ module "test_policy" {
}

module "ecs_alb_service_task" {
source = "../.."
alb_security_group = module.vpc.vpc_default_security_group_id
container_definition_json = one(module.container_definition.*.json_map_encoded_list)
ecs_cluster_arn = one(aws_ecs_cluster.default.*.id)
launch_type = var.ecs_launch_type
vpc_id = module.vpc.vpc_id
security_group_ids = [module.vpc.vpc_default_security_group_id]
subnet_ids = module.subnets.public_subnet_ids
ignore_changes_task_definition = var.ignore_changes_task_definition
network_mode = var.network_mode
assign_public_ip = var.assign_public_ip
propagate_tags = var.propagate_tags
deployment_minimum_healthy_percent = var.deployment_minimum_healthy_percent
deployment_maximum_percent = var.deployment_maximum_percent
deployment_controller_type = var.deployment_controller_type
desired_count = var.desired_count
task_memory = var.task_memory
task_cpu = var.task_cpu
ecs_service_enabled = var.ecs_service_enabled
force_new_deployment = var.force_new_deployment
redeploy_on_apply = var.redeploy_on_apply
task_policy_arns = [module.test_policy.policy_arn]
task_exec_policy_arns_map = { test = module.test_policy.policy_arn }
source = "../.."
alb_security_group = module.vpc.vpc_default_security_group_id
container_definition_json = one(module.container_definition.*.json_map_encoded_list)
ecs_cluster_arn = one(aws_ecs_cluster.default.*.id)
launch_type = var.ecs_launch_type
vpc_id = module.vpc.vpc_id
security_group_ids = [module.vpc.vpc_default_security_group_id]
subnet_ids = module.subnets.public_subnet_ids
ignore_changes_task_definition = var.ignore_changes_task_definition
network_mode = var.network_mode
assign_public_ip = var.assign_public_ip
propagate_tags = var.propagate_tags
deployment_minimum_healthy_percent = var.deployment_minimum_healthy_percent
deployment_maximum_percent = var.deployment_maximum_percent
deployment_controller_type = var.deployment_controller_type
desired_count = var.desired_count
task_memory = var.task_memory
task_cpu = var.task_cpu
ecs_service_enabled = var.ecs_service_enabled
force_new_deployment = var.force_new_deployment
redeploy_on_apply = var.redeploy_on_apply
task_policy_arns = [module.test_policy.policy_arn]
task_exec_policy_arns_map = { test = module.test_policy.policy_arn }
service_autoscaling_enabled = var.service_autoscaling_enabled
service_autoscaling_minimum_capacity = var.service_autoscaling_minimum_capacity
service_autoscaling_maximum_capacity = var.service_autoscaling_maximum_capacity
service_autoscaling_target_tracking_policies = var.service_autoscaling_target_tracking_policies

context = module.this.context
}
38 changes: 37 additions & 1 deletion examples/complete/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,40 @@ variable "redeploy_on_apply" {
type = bool
description = "Updates the service to the latest task definition on each apply"
default = false
}
}

variable "service_autoscaling_enabled" {
type = bool
description = "Whether to enable autoscaling for the ECS service. This will cause the number of tasks to be adjusted based on the autoscaling policies defined."
default = false
}

variable "service_autoscaling_minimum_capacity" {
type = number
description = "The minimum number of tasks to keep running in the service. This is used for service autoscaling policies."
nullable = true
default = null
}

variable "service_autoscaling_maximum_capacity" {
type = number
description = "The maximum number of tasks to keep running in the service. This is used for service autoscaling policies."
nullable = true
default = null
}

variable "service_autoscaling_target_tracking_policies" {
type = map(object({
predefined_metric_type = string
resource_label = optional(string)
target_value = number
scale_out_cooldown = optional(number)
scale_in_cooldown = optional(number)
}))
description = <<-EOT
A map of target tracking policies to use for ECS service autoscaling. Valid metrics types are `ECSServiceAverageCPUUtilization`, `ECSServiceAverageMemoryUtilization`, and `ALBRequestCountPerTarget`.
Note: `resource_label` is required for `ALBRequestCountPerTarget` metric type. This will be the last part of the target group ARN: `targetgroup/<target_group_name>/<target_group_id>`.
See the [documentation](https://docs.aws.amazon.com/autoscaling/application/APIReference/API_PredefinedMetricSpecification.html) for more details on predefined metrics.
EOT
default = {}
}
40 changes: 40 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
locals {
enabled = module.this.enabled
ecs_service_enabled = local.enabled && var.ecs_service_enabled
ecs_cluster_name = split("/", var.ecs_cluster_arn)[length(split("/", var.ecs_cluster_arn)) - 1]
autoscaling_enabled = local.enabled && var.ecs_service_enabled && var.service_autoscaling_enabled
task_role_arn = try(var.task_role_arn[0], tostring(var.task_role_arn), "")
create_task_role = local.enabled && length(var.task_role_arn) == 0
task_exec_role_arn = try(var.task_exec_role_arn[0], tostring(var.task_exec_role_arn), "")
Expand Down Expand Up @@ -56,6 +58,15 @@ module "service_connect_label" {
context = module.this.context
}

module "service_autoscaling_label" {
source = "cloudposse/label/null"
version = "0.25.0"
enabled = local.autoscaling_enabled
attributes = ["service", "autoscaling"]

context = module.this.context
}

resource "aws_ecs_task_definition" "default" {
count = local.create_task_definition ? 1 : 0
family = module.this.id
Expand Down Expand Up @@ -1012,3 +1023,32 @@ resource "aws_ecs_service" "default" {
depends_on = [aws_iam_role.ecs_service, aws_iam_role_policy.ecs_service]

}

# Autoscaling
resource "aws_appautoscaling_target" "service" {
count = local.autoscaling_enabled ? 1 : 0
min_capacity = var.service_autoscaling_minimum_capacity
max_capacity = var.service_autoscaling_maximum_capacity
resource_id = "service/${local.ecs_cluster_name}/${module.this.id}"
scalable_dimension = "ecs:service:DesiredCount"
service_namespace = "ecs"
tags = module.service_autoscaling_label.tags
}

resource "aws_appautoscaling_policy" "target" {
for_each = local.autoscaling_enabled ? var.service_autoscaling_target_tracking_policies : map()
name = "${module.service_autoscaling_label.id}-target-${each.key}"
policy_type = "TargetTrackingScaling"
resource_id = aws_appautoscaling_target.service[0].resource_id
scalable_dimension = aws_appautoscaling_target.service[0].scalable_dimension
service_namespace = aws_appautoscaling_target.service[0].service_namespace
target_tracking_scaling_policy_configuration {
predefined_metric_specification {
predefined_metric_type = each.value.predefined_metric_type
resource_label = each.value.resource_label
}
target_value = each.value.target_value
scale_out_cooldown = each.value.scale_out_cooldown
scale_in_cooldown = each.value.scale_in_cooldown
}
}
37 changes: 37 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,43 @@ variable "desired_count" {
default = 1
}

variable "service_autoscaling_enabled" {
type = bool
description = "Whether to enable autoscaling for the ECS service. This will cause the number of tasks to be adjusted based on the autoscaling policies defined."
default = false
}

variable "service_autoscaling_minimum_capacity" {
type = number
description = "The minimum number of tasks to keep running in the service. This is used for service autoscaling policies."
nullable = true
default = null
}

variable "service_autoscaling_maximum_capacity" {
type = number
description = "The maximum number of tasks to keep running in the service. This is used for service autoscaling policies."
nullable = true
default = null
}

variable "service_autoscaling_target_tracking_policies" {
type = map(object({
predefined_metric_type = string
resource_label = optional(string)
target_value = number
scale_out_cooldown = optional(number)
scale_in_cooldown = optional(number)
}))
description = <<-EOT
A map of target tracking policies to use for ECS service autoscaling. Valid metrics types are `ECSServiceAverageCPUUtilization`, `ECSServiceAverageMemoryUtilization`, and `ALBRequestCountPerTarget`.
Note: `resource_label` is required for `ALBRequestCountPerTarget` metric type. This will be the last part of the target group ARN: `targetgroup/<target_group_name>/<target_group_id>`.
See the [documentation](https://docs.aws.amazon.com/autoscaling/application/APIReference/API_PredefinedMetricSpecification.html) for more details on predefined metrics.
EOT
default = {}
}


variable "deployment_controller_type" {
type = string
description = "Type of deployment controller. Valid values are `CODE_DEPLOY` and `ECS`"
Expand Down