この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Lambda のコールドスタート対策で利用する Provisioned Concurrency の設定をパラメータの値によって有効、無効にするSAMテンプレートを紹介します。SAMテンプレートベースですがCloudFormationテンプレートのConditions
とIf
の組み合わせ例の参考にもなるかと思います。
実現したいこと
お題はシンプルです。
- 同時実行数の数をCloudFormationのパラメータで指定します。
- パラメータの数値が
0
の場合は Provisioned Concurrency を無効化(未設定状態にしたい) - パラメータの雛妓は
1
以上の場合は Provisioned Concurrency を設定し有効化
ですが、CloudFormationは愚直な書き方になりがちなので意外とややこしいことになります。
それではConditions
、If
とAWS::NoValue
を駆使して処理してみましょう。
SAMテンプレート
sam init
コマンドで生成した Hello World テンプレートをベースに設定を追加しました。
コードは以下のリンクに置いてあります。
解説
解説はテンプレート内にコメントで記しました。ポイントはIf
とAWS::NoValue
の組み合わせにより設定する予定のプロパティを削除するところです。
本文中にコメントで書いた方が見やすいと思ってたのですが横幅の関係でみづらいかもしれません。コピペして画面いっぱい広げられるエディタで見てい頂いた方が見やすいかと思います。
template.yaml
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
# ----- Parameter設定 -----
Parameters:
ProvisionedConcurrentCount: # パラメータで同時実行数を指定します
Type: Number
Default: 0 # デフォルト値は0にしていますが、デプロイ時にパラメータの指定で上書きできます
Conditions: # 0かそれ以外かの判定をします
ProvisionedConcurrency: # 1つ下の行の判定結果が格納されます
!Not [!Equals [!Ref ProvisionedConcurrentCount, 0]] # True: 0以外のとき / False: 0のときという意味の判定文です
# ----- ここまで -----
Globals:
Function:
Timeout: 5
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
# ---- 同時実行数設定 -----
AutoPublishAlias: live # Provisioned Concurrency の設定には Alias が必須
ProvisionedConcurrencyConfig: !If # 第1引数を条件式として True / False を判定し、True であれば第2引数が False であれば第3引数が採用されます
- ProvisionedConcurrency # 0以外のときは True であり、0のときは False が格納されています(Conditions句のところ)
- ProvisionedConcurrentExecutions: !Ref ProvisionedConcurrentCount # True のときは第2引数が採用されます。指定された数値分の Provisioned Concurrency 設定をしています
- !Ref "AWS::NoValue" # False のときは第3引数が採用されます。AWS::NoValue の効果により ProvisionedConcurrencyConfig プロパティを削除します。(Provisioned Concurrencyの無効化 = デフォルトの状態)
# ---- ここまで -----
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
Outputs:
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
AWS::NoValue
については以下のリンクが参考になります。
実行結果確認
解説したSAMテンプレートをsam build
, sam deploy
コマンドでAWS上にリソースを作成します。
0指定で設定を無効にしたとき
samconfig.toml
内でパラメータの値を指定します。
samconfig.toml
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "lambdaConncurrencyConfigSample"
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1lcx29wiwvv2b"
s3_prefix = "lambdaConncurrencyConfigSample"
region = "ap-northeast-1"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
image_repositories = []
parameter_overrides = "ProvisionedConcurrentCount=\"0\""
パラメータProvisionedConcurrentCount
が0
でデプロイした Lambda 関数の設定状況です。プロビジョニングされた同時実行設定は未設定となっています。普通に Lambda 関数を作成すると設定されていないことがデフォルトの状態です。
1以上を指定し有効にしたとき
samconfig.toml
内でパラメータの値を変更します。
samconfig.toml
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "lambdaConncurrencyConfigSample"
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1lcx29wiwvv2b"
s3_prefix = "lambdaConncurrencyConfigSample"
region = "ap-northeast-1"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
image_repositories = []
parameter_overrides = "ProvisionedConcurrentCount=\"1\""
パラメータProvisionedConcurrentCount
が1
でデプロイした Lambda 関数の設定状況です。プロビジョニングされた同時実行設定が作られています。
以上、Conditions
、If
とAWS::NoValue
の組み合わせによるプロパティ作成ありなしの判定方法でした。
終わりに
お題のようなお問い合わせを頂いた際にサンプルで提示したテンプレートに解説をつけて紹介しました。同様のケースであればググって解決できるようにブログに残しました。Conditions
、If
とAWS::NoValue
の組み合わせ参考例としても役に立つような気がしています。どなたかのお役にたてれば光栄です。