Should ECS/EC2 ASGProvider Capacity Provider be able to scale-up from zero, 0->1

0

Following from earlier thread https://repost.aws/questions/QU6QlY_u2VQGW658S8wVb0Cw/should-ecs-service-task-start-be-triggered-by-asg-capacity-0-1 , I've now attached a proper Capacity Provider, an Auto Scale Group provider to my ECS Cluster.

Question TL;DR: should scaling an ECS Service 0->1 desired tasks be able to wake-up a previously scaled-to-zero ASG and have it scale 0->1 desired/running?

So I've started with an ECS Service with a single task definition and Desired=1, backed by the ASG with Capacity Provider scaling - also starting with 1 Desired/InService ASG instance.

I can then set the ECS Service Desired tasks to 0, and it stops the single running task, then CapacityProviderReservation goes from 100 to 0, and 15 minutes/sample later the Alarm is triggered, and the ASG shuts-down it's only instance, 1->0 Desired/running.

If I later change the ECS Service Desired back to 1 - nothing happens, other than ECS noting that it has no capacity to place the task.

Should this work? I have previously seen something similar working - CapacityProviderReservation jumps to 200 and an instance gets created, but this is not working for me now - that metric is stuck at 100, and no scale-up-from-zero (to one) occurs in the ASG, and the task cannot be started.

Should this be expected to work? Reference blog https://aws.amazon.com/blogs/containers/deep-dive-on-amazon-ecs-cluster-auto-scaling/ suggests that CapacityProviderReservation should move to 200 if M > 0 and N = 0, but this seems to rely on a task in "Provisioning" state - will that even happen here, or is the ECS Service/Cluster giving-up and not getting that far, due to zero capacity?

asked 2 years ago1679 views
2 Answers
1
Accepted Answer

In order to use EC2 Capacity Provider with a Task or Service, you must specify a Capacity Provider Strategy when creating the service or running the task. This strategy is used instead of a Launch Type. The Capacity Provider Strategy must include the EC2 Capacity Provider along with a weight of at least 1.

For example:

{
  "weight": 1,
  "capacityProvider": "myEC2CapacityProvider",
  "base": 0
}

You can also configure this in the ECS Console when launching a Service.

AWS
EXPERT
answered 2 years ago
  • Great answer @Michael_F - I did get this to work via a CloudFormation and I can guess at the root cause when it wasn't working, so I will add an answer with those details.

0

Per answer from @Michael_F, for this to work, you must ensure that the Capacity Provider Strategy is attached to the ECS Service. In my case, building this with a CloudFormation stack, it was not, which is interesting so posting the solution here.

TL;DR: to go from not working to working, here's the CF template diff:

   EcsService:
     Type: AWS::ECS::Service
     Properties: 
       Cluster: !Ref EcsCluster
       DesiredCount: !FindInMap [ ServerState, !Ref ServerState, DesiredCapacity ]
       ServiceName: !Sub "${AWS::StackName}-ecs-service"
       TaskDefinition: !Ref EcsTask  
+      CapacityProviderStrategy:
+        - CapacityProvider: !Ref ECSCapacityProvider
+          Weight: 1
+          Base: 0
       DeploymentConfiguration:
         MaximumPercent: 100
         MinimumHealthyPercent: 0

Worth noting that ECSCapacityProvider referenced here is already defined - it is also already associated with the ECS Cluster with an association as the default strategy provider:

  EcsCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: !Sub "${AWS::StackName}-cluster"

  ECSCapacityProvider:
    Type: AWS::ECS::CapacityProvider
    Properties:
      AutoScalingGroupProvider:
        AutoScalingGroupArn: !Ref AutoScalingGroup
        ManagedScaling:
          MaximumScalingStepSize: 1
          MinimumScalingStepSize: 1
          Status: ENABLED
          TargetCapacity: 100
        ManagedTerminationProtection: ENABLED

  EcsClusterCapacityProviderAssociation:
    Type: AWS::ECS::ClusterCapacityProviderAssociations
    Properties:
      Cluster: !Ref EcsCluster
      CapacityProviders:
        - !Ref ECSCapacityProvider
      DefaultCapacityProviderStrategy:
        - CapacityProvider: !Ref ECSCapacityProvider
          Weight: 1

Now I thought this should be enough - the Capacity Provider and Strategy are registered with the same ECS Cluster where my ECS Service is defined, and according to https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cluster-capacity-providers.html and other docs, if you attach a default capacity provider strategy to a cluster, then create an ECS Service without one, it should adopt the default.

This did not happen for me in my CloudFormation template. The only thing I can image happened is that without an explicit DependsOn, my ECS Service is being defined asynchronously, or in-parallel to the capacity provider strategy on the cluster, so the ECS Service is being created before the capacity provider strategy is built and assigned to the cluster. The ECS Service therefore picks up a launch strategy. Can't really prove this yet.

So the solution would be to either add a DependsOn, or what I did above and explicitly assign the (already cluster default) capacity assignment strategy to the ECS Service.

With this, I can now use a Desired Task Count 1 -> 0 -> 1 to drive the ASG instance count to 1 -> (15 minutes) 0 -> (minute or two) 1.

answered 2 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions