ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

PipeCD で AWS Lambda function を Canary Release する

する。

この example を使う。

github.com

Lambda と Canary Release

AWS Lambda では alias と version という概念によって Canary Release が実現できる。

docs.aws.amazon.com

複数の version の lambda application を deploy しておき、alias の weight を操作することで canary release を実現できる。

PipeCD はこの機能を操作し、PipeCD の持つ Pipeline 設定で実現している。

Cloud Run の例はこちら。

blog.chaspy.me

Container Image を ECR へ Push する

PipeCD の lambda の deploy には3種類の方法がある。

pipecd.dev

  1. container image
  2. zip file archives
  3. source code directly

nodejs や python などの場合、2 や 3 の方法が取れるが、Go の場合、通常ビルド済みバイナリはソースコードに含まないため、実質 1 のみ、あるいはビルドバイナリを zip にして S3 に置く方法で 2 を取ることができるが、面倒である。

一応 Go の Binary は GitHub Release などにアップロードされることがほとんどなので、url 指定で使う方式はどうか、と issue だけは書いた。が、他にそういう需要が増えない限りは実装されないだろう。

github.com

というわけで、Go でやりたかったので container image を ECR に push する。

github.com

hello するだけの function である。

github.com

それをこの辺で build して login して push している。

github.com

ここまでが CI (lambda application) 側の責務。

無事 Push される。

f:id:take_she12:20220215134156p:plain

PipeCD Application の登録

登録する。

f:id:take_she12:20220215134504p:plain

PipeCD Configuration の追加

指定した repository の path に以下のファイルを push

function.yaml

apiVersion: pipecd.dev/v1beta1
kind: LambdaFunction
spec:
  name: SimpleFunction
  role: arn:aws:iam::655123516369:role/service-role/lambda
  image: 655123516369.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-api-gateway:v1
  memory: 512
  timeout: 30
  tags:
    app: simple

app.pipecd.yaml

# Deployment pipeline with canary strategy.
# Using version, alias, additional version to do canary, bluegreen.
# https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html
apiVersion: pipecd.dev/v1beta1
kind: LambdaApp
spec:
  pipeline:
    stages:
      # Deploy workloads of the new version.
      # But this is still receiving no traffic.
      - name: LAMBDA_CANARY_ROLLOUT
      # Promote new version to receive amount of traffic.
      - name: LAMBDA_PROMOTE
        with:
          percent: 10
      - name: LAMBDA_PROMOTE
        with:
          percent: 50
      # Promote new version to receive all traffic.
      - name: LAMBDA_PROMOTE
        with:
          percent: 100

push すると最初の quick sync が走ります。quick sync では現在指定している lambda function を単に deploy します。

f:id:take_she12:20220215134810p:plain

完了すると v1 が deploy されています。

f:id:take_she12:20220215134903p:plain

f:id:take_she12:20220215135028p:plain

f:id:take_she12:20220215135033p:plain

f:id:take_she12:20220215135036p:plain

f:id:take_she12:20220215135039p:plain

v2 を canary release する

PipeCD Configuration がある repository で image を更新します。

commit fd3fac104294eebbfa82beeed705296567b12a61
Author: kondo takeshi <chaspy@users.noreply.github.com>
Date:   Tue Feb 15 13:52:34 2022 +0900

    Deploy v2

diff --git a/lambda/canary/function.yaml b/lambda/canary/function.yaml
index 58b1924..a565222 100644
--- a/lambda/canary/function.yaml
+++ b/lambda/canary/function.yaml
@@ -3,7 +3,7 @@ kind: LambdaFunction
 spec:
   name: SimpleFunction
   role: arn:aws:iam::655123516369:role/service-role/lambda
-  image: 655123516369.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-api-gateway:v1
+  image: 655123516369.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-api-gateway:v2
   memory: 512
   timeout: 30
   tags:

merge すると deployment が作成され、

pipeline が plan されます。

f:id:take_she12:20220215135637p:plain

まずは v2 の function が deploy されます。

f:id:take_she12:20220215135713p:plain

待ちがなかったのであっという間に 100% promotion されてしまいましたw

f:id:take_she12:20220215140031p:plain f:id:take_she12:20220215140034p:plain f:id:take_she12:20220215140037p:plain f:id:take_she12:20220215140039p:plain

WAIT STAGE を追加してみる

これだとあんまりなので、30秒ずつ待ち時間を追加する。

v3 を deploy する。

f:id:take_she12:20220215140844p:plain

ちゃんと WAIT が動作しました。

f:id:take_she12:20220215141319p:plain f:id:take_she12:20220215141322p:plain

というわけで本家 example に PR 出しました。(すぐマージされました、Thank you!)

github.com

他の Deploy tool との比較

他のツールは動かしていませんが、調べた範囲でいくつか紹介しています。

素の aws cli

canary を利用しないのであればこれで十分かもしれません。

github.com

build して zip にして aws lambda update-function-code で upload するシンプルなパターン。

AWS SAM

aws.amazon.com

AWS 製のツールで、CLI が提供される。

yaml を input にして、内部では cloudformation が動くようだ。

段階的デプロイについてのドキュメントは以下。

docs.aws.amazon.com

Deployment Preference Type が 10percent ずつしかないのか、というところが自由度が低い気がしますね。

lambroll

github.com

init で初期化できたり、設定ファイルをコード管理して deploy コマンドで扱えるなど、cli よりわかりやすく、かつシンプルなツールなようです。

すでに lambda が存在している場合に init で設定をダウンロードするのもユーザビリティがあって良いですね。

ただ、canary release には対応していないようです。

fujiwara さんのブログを置いておく。

sfujiwara.hatenablog.com

比較

(他にツールがあれば教えてください)

シンプルと、できる機能の大きさでこういう順番になりそうなので、用途に応じて使いわけるといいでしょう。

aws cli < lambroll < PipeCD < SAM

lambda の deploy だけしたいのであれば lambroll, Canary Release をしたいなら PipeCD か SAM になりますが、PipeCD は Control Plane と Piped が必要なので環境構築が他に比べて少し大変な一方、柔軟な Canary, Analysis, Approval の設定が可能なので、すでに PipeCD を使っている環境については強力な選択肢になると思います。

SAM は Lambda 以外の API Gateway など他のサーバレスサービスをまとめてデプロイする、リッチなツールという位置付けになるかと思います。