iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🏃‍♂️

AWS CDK adds hotswap deployments for faster ECS deployments

に公開

Introduction

Good morning, I'm Kato. As I mentioned in this article, AWS CDK normally generates CloudFormation templates to perform deployments. However, a feature called hotswap deployment has emerged, which enables high-speed deployment by using the AWS SDK instead of CloudFormation when deploying Lambda functions.

Yesterday, v1.128.0 was released, and ECS services are now supported for hotswap deployment. Also, I hadn't realized it, but Step Functions are now supported as well.

Deployment Speed

To see exactly how much faster it becomes, I tried a configuration using ApplicationLoadBalancedFargateService from ecs-patterns. The Dockerfile and application used are as follows:

# app/Dockerfile
FROM node:16.11.1-alpine3.14

WORKDIR /usr/src/app

# Install tini
ENV TINI_VERSION v0.19.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static /tini
RUN chmod +x /tini
ENTRYPOINT ["/tini", "--"]

# Install my app
COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run compile

CMD ["npm", "start"]
// app/src/index.ts
import {createServer} from 'http';

const port = process.env.PORT ?? 3000;

const server = createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World!');
});

server.listen(port);

If you want to check all the files, please see intercept6/cdk-ecs-hotswap-demo.

When measured with the time command, while a normal deployment took over 8 minutes, the hotswap deployment took about 1 minute and 20 seconds.

- Normal hotswap deployment
1st time 8:47.84 1:14.31
2nd time 8:46.36 1:13.78
3rd time 9:23.97 1:35.16
Average 8:59.39 1:21.08

How it is implemented

Let's take a look at the pull request below to see how ECS hotswap deployment is implemented.

The logic is implemented by the apply method required by the HotswapOperation interface.
https://github.com/skinny85/aws-cdk/blob/92e317219596a1a50f51c1302cd5e594ad42c8c4/packages/aws-cdk/lib/api/hotswap/ecs-services.ts#L84

The apply method executes the processing in the following order. (The comments were extremely helpful!)

  1. Update the modified task definition and create a new task definition revision.
  2. Update the ECS service to point to the new task definition revision.
  3. Wait for the deployment of the ECS service started in step 2 to complete.

Note that these processes are performed by the AWS SDK (likely v2), and the options are as follows:

      clusterPromises.push({
        promise: sdk.ecs().updateService({
          service: ecsService.serviceArn,
          taskDefinition: taskDefRevArn,
          cluster: clusterName,
          forceNewDeployment: true,
          deploymentConfiguration: {
            minimumHealthyPercent: 0,
          },
        }).promise(),

One thing I felt should be particularly kept in mind is that minimumHealthyPercent is 0. In EC2 mode, if there is no spare capacity for instances, service disruption may occur. Not just for ECS, avoid using hotswap deployment anywhere except for development environments.

Afterword

AWS CDK is becoming increasingly convenient! However, as unique features like this continue to grow, I've started to think it might be quite challenging for those who begin learning CDK from now on. That said, AWS services have many areas where granularity can be finely configured, which makes me really want to rely on CDK for serverless development.
I would be happy to see more updates on the CloudFormation side so that we don't have to work so hard within CDK.
That's all.

Discussion