🏃‍♂️

AWS CDKにECSを高速でデプロイするhotswap deployments機能が追加されました

2021/10/16に公開

はじめに

おはようございます、加藤です。先日、こちらの記事で紹介しましたが、AWS CDKは本来Cloud Formationテンプレートを生成してデプロイを行いますが、Lambda関数をデプロイする際にCloud Formationを使用せずにAWS SDKを使うことで高速にデプロイする機能が登場しました。この機能はhotswap deploymentと呼ばれます。

昨日、v1.128.0がリリースされ、hotswap deploymentにECSサービスが対応しました。また、気づいていませんでしたがStep Functionsも対応していました。

デプロイ速度

具体的にどれぐらい早くなるのか、ecs-patternsApplicationLoadBalancedFargateServiceを使った構成で試してみました。使用したDockerfileとアプリケーションは下記のとおりです。

# 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);

全てのファイルを確認したい場合は、intercept6/cdk-ecs-hotswap-demoを確認してください。

timeコマンドで測定したところ、通常が8分強かかるのに対してhotswap deploymentを使った場合は1分20秒程度になりました。

- 通常 hotswap deployment
1回目 8:47.84 1:14.31
2回目 8:46.36 1:13.78
3回目 9:23.97 1:35.16
平均 8:59.39 1:21.08

どのように実現されているか

どのようにECSのhotswap deploymentが実現されているか、下記のプルリクエストを覗いてみます。

HotswapOperationインターフェイスによって要求されるapplyメソッドによって処理が実装されています。
https://github.com/skinny85/aws-cdk/blob/92e317219596a1a50f51c1302cd5e594ad42c8c4/packages/aws-cdk/lib/api/hotswap/ecs-services.ts#L84

applyメソッドでは下記の順序で処理が実行されます。(コメントがあってメッチャ助かった)

  1. 変更されたタスク定義を更新し新しいタスク定義 リビジョンを作成する
  2. 新しいタスク定義 リビジョンを指すようにECSサービスを更新します
  3. ステップ2で起動したECSサービスのデプロイが官僚するのを待つ

なお、これらの処理はAWS SDK(おそらくv2)によって行われており、オプションは下記の通りです。

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

特に意識すべきと感じたのが、minimumHealthyPercent0であることです。EC2モードにおいてインスタンスのキャパシティの空きがない場合などで、サービス断が発生する可能性があります。ECSに限らず、hotswap deploymentは開発環境を以外では使わないようにしましょう。

あとがき

AWS CDKがどんどん便利に!なって来てはいるんですが、ここまで独自機能が増えてくると今後CDKを学び始める人には結構しんどいんじゃないかなと思うようになりました。かといってAWSのサービスは昨日の粒度が細かく設定できる箇所が多いので、サーバーレス開発だとCDKにめっちゃ頼りたくなります。
あまりCDKで頑張り過ぎなくて良いようにCloud Formation側でもっと色々なアップデートがあるとうれしいなーと思います。
以上です。

Discussion