terraform-aws-ecs-cloudwatch-autoscaling icon indicating copy to clipboard operation
terraform-aws-ecs-cloudwatch-autoscaling copied to clipboard

No reference of how to specify cloudwatch metrics for autoscaling

Open mamccorm opened this issue 4 years ago • 7 comments

Found a bug? Maybe our Slack Community can help.

Slack Community

Describe the Bug

Hi there, I have a query regarding this terraform module, for reference: The following terraform module:

  • https://github.com/cloudposse/terraform-aws-ecs-cloudwatch-autoscaling

The description is as follows:

Terraform module to autoscale ECS Service based on CloudWatch metrics

The module itself seems to define the criteria for the auto-scaling, such as minimum and maximum amount of tasks, however I don't see any info or arguments to specify the Cloudwatch metric(s) to associate with. i.e how do we use this module to setup autoScaling with a Cloudwatch metric, such as CPU or memory utilisation, whenever there are no arguments to support this.

As an example, if I were to do this utilising the built-in terraform modules, i'd first look at leveraging the following to create a target:

  • https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_target

Then i'd attach a policy to it, with the targeted CloudWatch metric utilising:

  • https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_policy

Expected Behavior

Given the description of this module states that it is for creating ECS auto-scaling based on Cloudwatch metrics, id expect that it would allow me to specify the Cloudwatch metric to associate with it.

Steps to Reproduce

N/A - but details above

Screenshots

N/A - detail above.

Environment (please complete the following information):

N/A - details above

mamccorm avatar Jun 02 '21 15:06 mamccorm

@mamccormick isn't that what the following does ?

https://github.com/cloudposse/terraform-aws-ecs-cloudwatch-autoscaling/blob/7a9c37e90f5b5a16efc4a3d18434fe49c1190747/main.tf#L15

https://github.com/cloudposse/terraform-aws-ecs-cloudwatch-autoscaling/blob/7a9c37e90f5b5a16efc4a3d18434fe49c1190747/main.tf#L24-L29

https://github.com/cloudposse/terraform-aws-ecs-cloudwatch-autoscaling/blob/7a9c37e90f5b5a16efc4a3d18434fe49c1190747/main.tf#L43-L48

nitrocode avatar Aug 23 '21 15:08 nitrocode

If this module is consumed without using the outputs incomplete monitors will be created:

Screen Shot 2021-08-24 at 10 54 51 AM

If you click through the AWS console wizard it instructs you to create or target a CloudWatch alarm. The Terraform within this module doesn't provide any context on what to scale on, just how to scale. Looks like the outputs should be wired into alerts to create functional monitors.

gausnes avatar Aug 24 '21 16:08 gausnes

Ah then you probably need to use this module with the ecs sns module

https://github.com/cloudposse/terraform-aws-ecs-cloudwatch-sns-alarms

nitrocode avatar Aug 25 '21 01:08 nitrocode

As @gausnes already mentioned. This module won't create the autoscaling action by itself. What we need to do is combine the outputs (up and down) with a CloudWatch alarm.

One example that works for me:

module "cs_autoscaling_label" {
	source     = "../modules/null-label"
	name       = "cs-autoscaling"

	context = module.this.context
}

module "ecs_cloudwatch_autoscaling" {
	source                = "cloudposse/ecs-cloudwatch-autoscaling/aws"
	context               = module.cs_autoscaling_label.context
	cluster_name          = aws_ecs_cluster.ecs_cluster.name
	service_name          = module.content_service_fargate.service_name
	min_capacity          = var.min_capacity
	max_capacity          = var.max_capacity
	scale_up_adjustment   = var.scale_up_adjustment
	scale_up_cooldown     = var.scale_up_cooldown
	scale_down_adjustment = var.scale_down_adjustment
	scale_down_cooldown   = var.scale_down_cooldown
}

module "alarms_label" {
	source  = "../modules/null-label"
	name = "alarms"
	context = var.context
}

resource "aws_sns_topic" "sns_topic" {
	name              = module.alarms_label.id
	display_name      = "Foo bar"
	tags              = module.alarms_label.tags
}

module "ecs_cloudwatch_sns_alarms" {
	source  = "cloudposse/ecs-cloudwatch-sns-alarms/aws"
	.....
	cpu_utilization_high_alarm_actions = [
	                aws_sns_topic.cs_sns_topic.arn, 
	                module.ecs_cloudwatch_autoscaling.scale_up_policy_arn
	]
	.....
	cpu_utilization_low_alarm_actions = [
	        aws_sns_topic.cs_sns_topic.arn, 
	        module.ecs_cloudwatch_autoscaling.scale_down_policy_arn
	]
	.......
	memory_utilization_high_alarm_actions = [
	            aws_sns_topic.cs_sns_topic.arn, 
	            module.ecs_cloudwatch_autoscaling.scale_up_policy_arn
	]
	........
	memory_utilization_low_alarm_actions = [
	              aws_sns_topic.cs_sns_topic.arn, 
	              module.ecs_cloudwatch_autoscaling.scale_down_policy_arn
        ]
	....
	context = module.this.context
}

The differences in this above sample and the default example are the cpu_utilization_high_alarm_actions, cpu_utilization_low_alarm_actions, memory_utilization_high_alarm_actions, memory_utilization_low_alarm_actions we need to pass the outputs from autoscaling module (scale_up_policy_arn and scale_down_policy_arn) to the alarm actions we want. This configuration will produce the expected behaviour, something like this:

Screen Shot 2021-08-25 at 12 34 07

daltonsena avatar Aug 25 '21 15:08 daltonsena

Awesome. Thanks for figuring it out @daltonsena !

Perhaps one of you could put in a PR to update our README.yaml file to include the cloudposse/ecs-cloudwatch-sns-alarms/aws module reference in the usage? Then others will not hit the same issue.

nitrocode avatar Aug 25 '21 18:08 nitrocode

When I do this, the ECS UI shows that I only get scaling on CPU. Shouldn't there be a module.ecs_cloudwatch_autoscaling-mem to be the target of memory_utilization_*_alarm_actions?

razorsedge avatar Oct 07 '21 14:10 razorsedge

AWS will not allow you to use 2 alerts/metrics to control 1 aws_appautoscaling_policy that means we need 1 aws_appautoscaling_policy for each CPU and Memory alert/metric.

That means that we required 4 aws_appautoscaling_policy to have CPU Up, CPU Down, MEM Up, MEM Down.

This Module however only gives us 2 and since it try to create the aws_appautoscaling_target each time we call the module we can't use this module to create the 4 aws_appautoscaling_policy.

Maybe we should update the module and make the creation of aws_appautoscaling_target optional, athough this module is outdated in the metrics as well so maybe requieres additional changes like the metric_aggregation_type.

MrZablah avatar May 11 '24 09:05 MrZablah