/ #cdk #Lambda 

【CDK/Python】罠だらけのLambda Provisioned Concurrency (+ Alias)

もくじ

何がしたいか?というとCDKでエイリアスを作って、そこに最新のLambdaをプロビジョニングさせたい。ということです。

が、、、これがやたら罠だらけだったので記事にしました。

これからCDKでProvisioned Concurrencyしようと思っている方は、躓きを減らせるかもです。

とりあえず完成形を出して、途中途中でこんなトラップがありましたというのに触れていきます!

⚠今回のスタックをデプロイしたら、必ず削除してください!放置すると料金が発生します!

前提

  • 自由にできるAWSのアカウントがある
  • Python3
  • CDK 1.128.0

では 作っていきましょう👻

まず雛形になるプロジェクトを用意します

$ mkdir cdk-lambda-provisioned-concurrency && cd $_
$ cdk init --language python

次に依存関係を書きます。

#...略
setuptools.setup(
	#...略
    install_requires=["aws-cdk.core==1.128.0", "aws-cdk.aws-lambda==1.128.0",],
	#...略
#...略

インストール

$ pip install -r requirements.txt

スタックを実装する

トラップの多いのはここです

from aws_cdk import core as cdk, aws_lambda
from datetime import datetime


class CdkLambdaProvisionedConcurrencyStack(cdk.Stack):
    def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Lambdaを作る
        hoge_lambda = aws_lambda.Function(
            self,
            "HogeLambda",
            code=aws_lambda.Code.from_asset("src"),
            handler="index.handler",
            runtime=aws_lambda.Runtime.PYTHON_3_9,
            architecture=aws_lambda.Architecture.ARM_64,  # プロビジョニングするのでARMできるだけ安くする
        )

        # 新しいバージョンを発番する
        hoge_version = aws_lambda.Version(
            self,
            f"HogeVersion{datetime.today().timestamp()}",  # デプロイ毎にバージョンを作るためにIDを変化させる必要がある
            lambda_=hoge_lambda,
            removal_policy=cdk.RemovalPolicy.RETAIN,  # 過去バージョンを削除しないようにする
        )

        # 新しいバージョンからエイリアスを作る
        aws_lambda.Alias(
            self, "HogeAlias", alias_name="hoge-alias", version=hoge_version, provisioned_concurrent_executions=1
        )  # versionに`hoge_lambda.latest_version`を指定した場合はプロビジョニングできない

大体コメントしてますが、詳細を説明します。


# プロビジョニングするのでARMできるだけ安くする

これはオプションです!公式によると20%お安くなって19%パフォーマンスが向上するとのこと

使えるなら使わないほうが損ですね〜


# デプロイ毎にバージョンを作るためにIDを変化させる必要がある

罠その1です。

デプロイ時に常にIDが変わるようにします。

なぜならID固定だと最初にデプロイしたときにだけバージョンが作られて、以降何度デプロイしても新しいバージョンが作られなくなります。


# 過去バージョンを削除しないようにする

罠その2です。

Lambdaのバージョン管理しているのですが、これを設定しないとデプロイ時に新しいバージョンが作られますが古いバージョンがどんどん削除されるという現象が発生します。

私はコンソール上のバージョンニングとか不要なので、古いのどんどん削除して大丈夫だ!問題ない! という方、

それが罠その3です。

それをやると下記のエラーがでてデプロイできません

Alias with weights can not be used with Provisioned Concurrency

直訳すると重さ付きのエイリアスはプロビジョンド・コンカレンシーでは使えないよ!とのことですが、

たぶんこれニュアンス違ってでプロビジョニング中の過去バージョン削除しようとしたけど、まだ使ってるから削除でき無いってことだと思います。

なのでこの設定は必須です。


versionに`hoge_lambda.latest_version`を指定した場合はプロビジョニングできない

罠その4です。

これはLambdaのコンソールを叩いているとすぐわかるのですが、$LATESTで作ったエイリアスにはプロビジョニングできません。


とのことでした。。。

ほぼほぼこの記事は以上で、後はLambdaを適当に作ってデプロイされたものをふむふむ確認するだけです(笑)

適当なLambda

def handler(event, context):
    return "hogehoge"

デプロイ!

$ cdk deploy
# これ削除を忘れずに!!放置した時間だけお金が発生します!!

# 削除
$ cdk destroy

デプロイした内容を確認してみる

# 関数名を取得する
$ aws lambda list-functions --query 'Functions[?contains(FunctionName,`HogeLambda`)].[FunctionName]' --output text
> hogehoge

# バージョンを確認する。※下記のhogehogeに関数名を貼り付けて叩く
$ aws lambda list-versions-by-function --function-name hogehoge --output table  --query 'Versions[*].Version'
------------------------
|ListVersionsByFunction|
+----------------------+
|  $LATEST             |
|  1                   |
|  2                   |
.. 省略
|  8                   |
|  9                   |
+----------------------+
# 動作確認で何度かデプロイしてたので、私の環境にはバージョンがたくさんありました(笑)

# エイリアスを確認する。※下記のhogehogeに関数名を貼り付けて叩く
$ aws lambda list-aliases --function-name hogehoge
{
    "Aliases": [
        {
            "AliasArn": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:xxxx:hoge-alias",
            "Name": "hoge-alias",
            "FunctionVersion": "9",
            "Description": "",
            "RevisionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
        }
    ]
}

# provisioned-concurrencyを確認する。※下記のhogehogeに関数名を貼り付けて叩く
$ aws lambda get-provisioned-concurrency-config --function-name hogehoge --qualifier hoge-alias
{
    "RequestedProvisionedConcurrentExecutions": 1,
    "AvailableProvisionedConcurrentExecutions": 1,
    "AllocatedProvisionedConcurrentExecutions": 1,
    "Status": "READY",
    "LastModified": "2021-10-20T13:48:56+0000"
}

以上確認終了!

後片付け

$ cdk destroy

まとめ

CDKでProvisioned Concurrencyをする場合は罠がたくさんあるのでお気をつけください!

またProvisioned Concurrencyは時間で課金されるのでしっかり削除しましょう!

以上です!

今回のリポジトリはこちら

https://github.com/sisi100/cdk-lambda-provisioned-concurrency/tree/rm-scaling

Author

Sisii

インフラが好きなエンジニアぶってるなにか