--- title: Amazon ECS Capacity Providers for EC2 instances description: >- How to automatically scale the EC2 capacity for your ECS cluster by using an ECS Capacity Provider filterDimensions: - key: tool value: cloudformation - key: type value: pattern - key: capacity value: ec2 - key: feature value: capacity-provider authors: - peckn date: April 5 2023 --- #### About This pattern shows how to setup an ECS cluster that automatically launches its own EC2 instances using an ECS Capacity Provider. This approach allows the ECS cluster to start out completely empty, add capacity as needed, and then "scale to zero" when you stop all tasks in the cluster. #### Install SAM CLI This pattern uses AWS SAM CLI for deploying CloudFormation stacks on your account. You should follow the appropriate [steps for installing SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html). #### Cluster with EC2 Capacity Provider This CloudFormation template deploys an ECS cluster that has a capacity provider linked to an EC2 Autoscaling Group. The Autoscaling Group starts out completely empty. <<< @/pattern/ecs-ec2-capacity-provider-scaling/files/cluster-capacity-provider.yml This stack accepts the following parameters that can used to adjust its behavior: - `InstanceType` - An ECS instance type. By default the stack deploys `c5.large` - `DesiredCapacity` - Number of EC2 instances to start with. Default `0` - `MaxSize` - An upper limit on number of EC2 instances to scale up to. Default `100` - `ECSAMI` - The Amazon Machine Image to use for each EC2 instance. Don't change this unless you really know what you are doing. - `VpcId` - The VPC to launch EC2 instances in. Can be the default account VPC. - `SubnetIds` - A comma separated list of subnets from that VPC. #### Service with a Capacity Provider Strategy This CloudFormation template deploys an ECS service in a cluster, with a capacity provider strategy setup. The service will signal the capacity provider to request capacity, and the capacity provider will scale up the EC2 Autoscaling Group automatically. <<< @/pattern/ecs-ec2-capacity-provider-scaling/files/service-capacity-provider.yml Most parameters in this stack will be supplied by a parent stack that passes in resources from the capacity provider stack. However you may be interested in overriding the following parameters: - `ServiceName` - A human name for the service. - `ImageUrl` - URL of a container image to run. By default this stack deploys `public.ecr.aws/docker/library/busybox:latest` - `ContainerCpu` - CPU shares, where 1024 CPU is 1 vCPU. Default: `256` (1/4th vCPU) - `ContainerMemory` - Megabytes of memory to give the conatiner. Default `512` - `Command` - Command to run in the container. Default: `sleep 3600` - `DesiredCount` - Number of copies of the container to run. Default: `0` (So you can test scaling up from zero) #### Parent Stack This stack deploys both stacks as nested stacks, for ease of grouping and passing parameters from one stack to the next. <<< @/pattern/ecs-ec2-capacity-provider-scaling/files/parent.yml This parent stack requires the following parameters: - `VpcId` - The ID of a VPC on your AWS account. This can be the default VPC - `SubnetIds` - A comma separated list of subnet ID's within that VPC #### Deploying the stacks with SAM Use SAM CLI to deploy the stacks with a command like this: ```sh sam deploy \ --template-file parent.yml \ --stack-name capacity-provider-environment \ --resolve-s3 \ --capabilities CAPABILITY_IAM \ --parameter-overrides VpcId=vpc-79508710 SubnetIds=subnet-b4676dfe,subnet-c71ebfae ``` ::: warning Depending on what you choose to call your stack in the `stack-name` parameter, you may get an error in CloudFormation that looks like this: ``` CreateCapacityProvider error: The specified capacity provider name is invalid. Up to 255 characters are allowed, including letters (upper and lowercase), numbers, underscores, and hyphens. The name cannot be prefixed with "aws", "ecs", or "fargate". Specify a valid name and try again. ``` If this happens ensure that your parent CloudFormation stack's name does not start with "aws", "ecs", "fargate". The capacity provider in the stack gets an autogenerated name that is derived from the stack name, so if the stack starts with a prohibited word it will cause the capacity provider's name to also start with that prohibited word. ::: #### Test out by scaling up Initially the ECS cluster will be empty, with no EC2 instances. Additionally the deployed service has a `DesiredCount` of zero, so there are initially no containers being launched either. Use the Amazon ECS web console to update the service and set the desired count to a higher number of tasks. You will observe the ECS cluster launch the requested tasks into an initial status of `PROVISIONING`. At this point the task is just a virtual placeholder. The capacity provider notices the task waiting for capacity and responds by scaling up the autoscaling group to provide some EC2 capacity in the cluster. Finally, ECS places tasks onto this brand new capacity as it comes online. #### Test out scaling down Last but not least update the service in the ECS console to adjust its desired count back down to zero. Once all instances are empty you will see ECS begin to shutdown EC2 instances until the cluster has been scaled back down to zero. #### See Also - If your workload is interruptible you may prefer to save money on your infrastructure costs by using an [EC2 Spot Capacity provider](/ecs-spot-capacity-cluster) instead.