ENGINEER BLOG ENGINEER BLOG
  • 公開日
  • 最終更新日

【AWS SAM】LambdaのCodeUriでエラーが起きた際の対処法

この記事を共有する

目次

はじめに

こんにちは!パーソル&サーバーワークスの野間です。

AWS Serverless Application Model (以下、SAM) を使って AWS Lambda (以下、Lambda) のテンプレートを作成していたときに、以下のエラーが発生しました。

changeset_error.png

'CodeUri' requires Bucket and Key properties to be specified. 

この記事ではその原因と対処法を紹介します!

いきなり結論

✅結論:CodeUriでは組み込み関数(!Ref や !Sub)が使えません。

エラーの原因は、Lambda の CodeUri に !Ref を使っていたことでした。つまり、CodeUri には組み込み関数を使わず、静的なパスを記載する必要があります。

AWS のドキュメントにも以下のように書かれています。

CodeUri プロパティで組み込み関数を使用する場合、 AWS SAM は値を正しく解析できません。代わりに AWS::LanguageExtensions 変換の使用を検討してください。

参考:https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-function-codeuri

CodeUriについて

ここであらためて、CodeUri について簡単に説明します。 CodeUri は、Lambda 関数で使うコードの場所を示すプロパティで、以下の2種類の指定方法があります。

1. S3 のパスを指定する場合

 CodeUri: s3://bucket-name/key-name 

2. ローカルパスを指定する場合

 CodeUri: lambda/src 

このローカルパスを指定した場合は、aws cloudformation package コマンドで自動的にそのディレクトリの内容が Amazon S3 (以下、S3) にアップロードされ、テンプレート内の CodeUri が S3 パスに置き換えられます。

codeuri.png 参考:https://d1.awsstatic.com/webinars/jp/pdf/services/20190814AWS-BlackbeltSAM_rev.pdf

ただし、テンプレートファイルのあるディレクトリをそのまま指定すると、Lambda に不要なファイルまで含まれてしまう可能性があるので注意が必要です。

lambda_file.png

そのため、Lambda に必要なファイルだけをまとめたディレクトリを作成し、そのローカルパスを CodeUri に記載するのがおすすめです。

今回の構成と対処法

今回のケースでは、AWS CodePipeline を利用して Lambda をデプロイする構成で開発していました。

codepipeline-lambdafunction.png

Source

GitLabリポジトリに SAM テンプレートファイルと Lambda で利用する Python ファイルを格納しています。

.
├── CodePipeline.yml
├── build
│   └── buildspec.yml
└── lambda
    ├── hello-world-lambda.yml
    ├── lambda_function.py
    └── param.json

Build

Build ステージでは aws cloudformation package コマンドを実行して、GitLab に格納した SAM テンプレートファイルを S3 に格納しています。

build:
    commands:
      - |
        aws cloudformation package \
          --template-file $LAMBDA_TEMPLATE_FILE_PATH \
          --s3-bucket $S3_BUCKET \
          --s3-prefix $LAMBDA_FUNCTION_NAME \
          --output-template-file $PACKAGED_TEMPLATE_FILE_NAME

Deploy

Deploy ステージでは SAM テンプレートファイルを使って Lambda を作成しています。 CodeUri はエラーが起きたため以下のように静的なパスに変更しました。

  LambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Ref LambdaFunctionName
      CodeUri: lambda/lambda_function.py
      Runtime: !Ref Runtine
      Handler: !Ref Handler
      MemorySize: !Ref MemorySize
      Timeout: !Ref Timeout
      Role: !GetAtt LambdaExecutionRole.Arn

または、以下のように S3 バケット名と S3キー名を指定することも可能です。

CodeUri:
      Bucket: !Ref BucketName
      Key: lambda_function.zip

おわりに

普段テンプレートを書くときは、なるべくハードコーディングを避けて !Ref や !Sub を使うのが当たり前になっていたので、 組み込み関数が使えない場面があるのはとても驚きました。 同じようなエラーに遭遇した方の参考になればうれしいです!

この記事は私が書きました

野間 太一

記事一覧

猫とCloudFormationが好きです。

野間 太一

この記事を共有する

クラウドのご相談

CONTACT

クラウド導入や運用でお悩みの方は、お気軽にご相談ください。
専門家がサポートします。

サービス資料ダウンロード

DOWNLOAD

ビジネスをクラウドで加速させる準備はできていますか?
今すぐサービス資料をダウンロードして、詳細をご確認ください。