Help with configuring the ECS Application Autoscaling needed

2,627 views
Skip to first unread message

Michael Leikind

unread,
Mar 13, 2017, 7:39:30 PM3/13/17
to Terraform
Hi,

I am trying to create a template for configuring the ECS Application Autoscaling.

Here is what I did so far... Everything works besides "APP AUTO-SCALLING" part which was added recently.

When running the terraform apply command the get this error:

===========
aws_appautoscaling_target.tgt: Creating...
  max_capacity:       "" => "4"
  min_capacity:       "" => "1"
  resource_id:        "" => "service/webhooks/app-cluster"
  role_arn:           "" => "arn:aws:iam::XXXXXXXXX:role/ecsAutoscaleRole"
  scalable_dimension: "" => "ecs:service:DesiredCount"
  service_namespace:  "" => "ecs"
aws_appautoscaling_target.tgt: Still creating... (10s elapsed)
aws_appautoscaling_target.tgt: Still creating... (20s elapsed)
aws_appautoscaling_target.tgt: Still creating... (30s elapsed)
aws_appautoscaling_target.tgt: Still creating... (40s elapsed)
aws_appautoscaling_target.tgt: Still creating... (50s elapsed)
Error applying plan:

1 error(s) occurred:

* aws_appautoscaling_target.tgt: Error creating application autoscaling target: ValidationException: Unable to assume IAM role: arn:aws:iam::969968648862:role/ecsAutoscaleRole
        status code: 400, request id: XXX-XXX-XXX-XXX
===========


Appreciate any help! 

Mudasir Mirza

unread,
Mar 14, 2017, 5:55:53 AM3/14/17
to Terraform
Hi,

I will share my working example. I got it to working on a very long time and after almost 40+ iterations and hope this helps you out

### ECS AutoScaling Alarm
resource "aws_cloudwatch_metric_alarm" "nginx_service_high" {
  alarm_name          = "nginx-service-CPU-Utilization-High-30"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = "1"
  metric_name         = "CPUUtilization"
  namespace           = "AWS/ECS"
  period              = "60"
  statistic           = "Average"
  threshold           = "30"

  dimensions {
    ClusterName = "${aws_ecs_cluster.main.name}"
    ServiceName = "${aws_ecs_service.nginx.name}"
  }

  alarm_actions = ["${aws_appautoscaling_policy.nginx_up.arn}"]
}

resource "aws_cloudwatch_metric_alarm" "nginx_service_low" {
  alarm_name          = "nginx-service-CPU-Utilization-Low-5"
  comparison_operator = "LessThanThreshold"
  evaluation_periods  = "1"
  metric_name         = "CPUUtilization"
  namespace           = "AWS/ECS"
  period              = "60"
  statistic           = "Average"
  threshold           = "5"

  dimensions {
    ClusterName = "${aws_ecs_cluster.main.name}"
    ServiceName = "${aws_ecs_service.nginx.name}"
  }

  alarm_actions = ["${aws_appautoscaling_policy.nginx_down.arn}"]
}

resource "aws_appautoscaling_target" "nginx_scale_target" {
  service_namespace = "ecs"
  resource_id = "service/${aws_ecs_cluster.main.name}/${aws_ecs_service.nginx.name}"
  scalable_dimension = "ecs:service:DesiredCount"
  role_arn = "${aws_iam_role.ecs_autoscale_role.arn}"
  min_capacity = 1
  max_capacity = 4

  depends_on = [
    "aws_ecs_cluster.main",
    "aws_ecs_service.nginx"
  ]

}

resource "aws_appautoscaling_policy" "nginx_up" {
  name                      = "nginx-scale-up"
  service_namespace         = "ecs"
  resource_id               = "service/${var.ecs_cluster_name}/${aws_ecs_service.nginx.name}"
  scalable_dimension        = "ecs:service:DesiredCount"

  adjustment_type           = "ChangeInCapacity"
  cooldown                  = 300
  metric_aggregation_type   = "Average"

  step_adjustment {
    metric_interval_lower_bound = 0
    scaling_adjustment = 1
  }
  depends_on = [
    "aws_appautoscaling_target.nginx_scale_target"
  ]
}

resource "aws_appautoscaling_policy" "nginx_down" {
  name                      = "nginx-scale-down"
  service_namespace         = "ecs"
  resource_id               = "service/${var.ecs_cluster_name}/${aws_ecs_service.nginx.name}"
  scalable_dimension        = "ecs:service:DesiredCount"

  adjustment_type           = "ChangeInCapacity"
  cooldown                  = 300
  metric_aggregation_type   = "Average"

  step_adjustment {
    metric_interval_lower_bound = 0
    scaling_adjustment = -1
  }
  depends_on = [
    "aws_appautoscaling_target.nginx_scale_target"
  ]
}

resource "aws_iam_role" "ecs_autoscale_role" {
  name               = "ecsAutoscaleRole"
  assume_role_policy = "${file("${path.module}/autoscale-assume-role.json")}"
}

resource "aws_iam_policy_attachment" "ecs_autoscale_role_attach" {
  name       = "ecs-autoscale-role-attach"
  roles      = ["${aws_iam_role.ecs_autoscale_role.name}"]
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole"
}

The policy document JSON is

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "application-autoscaling.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

This is an example of Nginx service.

Michael Leikind

unread,
Mar 14, 2017, 12:16:35 PM3/14/17
to Terraform
You just made my day,
thanks so much!

Michael Leikind

unread,
Mar 14, 2017, 2:17:41 PM3/14/17
to Terraform
If its not too much to ask, 
would you mind sharing the service creation code with an exposed CloudWatch alerts?

Mudasir Mirza

unread,
Mar 14, 2017, 5:06:38 PM3/14/17
to Terraform
Hi,

This might help you out


This has been taken out from a big module, so allot of dependencies are missing related to VPC, that you will have to figure out.

Mic L

unread,
Mar 15, 2017, 12:23:36 AM3/15/17
to Terraform
Thank you again!
Reply all
Reply to author
Forward
0 new messages