SAMを触ってみてはまったことなどをメモします。
template.yamlのRoleでエラー 1
sam init
でHello Worldプロジェクトを作成し、
sam build
と sam deploy
がうまくいくところまで確認できた後、
template.yamlにRoleを追加したらエラーになりました。
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
Role: "arn:aws:iam::xxxxxxxxxx:role/xxxxxxxxxx" # ここを追加
CodeUri: hello-world/
Handler: app.lambdaHandler
Runtime: nodejs16.x
Timeout: 120
Architectures:
buildはできましたがdeployでエラーです。
Waiting for changeset to be created..
Error: Failed to create changeset for the stack: sam-app, ex: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state: For expression "Status" we matched expected path: "FAILED" Status: FAILED. Reason: Template error: instance of Fn::GetAtt references undefined resource HelloWorldFunctionRole
わかりにくいですが、Roleを設定しているのにOutput
で暗黙的なRoleを作ろうとしているのがだめみたいです。
なので、Outputの以下をコメントアウトします。
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
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
無事にSuccessしました。
template.yamlのRoleでエラー 2
次に、RoleをGlobalに定義しようと思い実行しましたが、deployでまたもやエラーが出ます。
Globals:
Function:
Timeout: 3
Role: "arn:aws:iam::xxxxxxxxxx:role/xxxxxxxxxx" # ここを追加
エラー
"'Role' is not a supported property of 'Function'. Must be one of the following values - ['Handler', 'Runtime', 'CodeUri', 'DeadLetterQueue', 'Description', 'MemorySize', 'Timeout', 'VpcConfig', 'Environment', 'Tags', 'Tracing', 'KmsKeyArn', 'AutoPublishAlias', 'Layers', 'DeploymentPreference', 'PermissionsBoundary', 'ReservedConcurrentExecutions', 'ProvisionedConcurrencyConfig', 'AssumeRolePolicyDocument', 'EventInvokeConfig', 'FileSystemConfigs', 'CodeSigningConfigArn', 'Architectures', 'EphemeralStorage', 'FunctionUrlConfig']")]
こちらはエラーメッセージに書いてある通りで、GlobalにRoleは定義できないみたいです。
公式ドキュメントに定義できるプロパティ一覧が書いてあります
layerビルドでエラー Cannot find module
こんな構成でLayerを作り、レイヤーのLogical IDを指定してビルドしたらエラーになりました
.
├── README.md
├── events
│ └── event.json
├── lambdas
│ ├── func1
│ │ ├── app.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── tests
├── layers
│ └── layer1
│ └── nodejs
│ └── node_modules
│ ├── mylayer.js
│ ├── package.json
│ └── package.lock.json
├── package-lock.json
├── package.json
├── samconfig.toml
└── template.yaml
...
Resources:
Func1:
Type: AWS::Serverless::Function
Properties:
Role: "arn:aws:iam::xxxxxxxxxx:role/xxxxxxxxxx"
CodeUri: lambdas/func1/
Handler: app.lambdaHandler
Runtime: nodejs16.x
Timeout: 120
Architectures:
Layers: # ここを追加
- !Ref MyLayer
MyLayer: # ここを追加
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: mylayer
Description: layer for me
ContentUri: layers/layer1/
CompatibleRuntimes:
- nodejs16.x
Metadata:
BuildMethod: nodejs16.x
・・・
実行コマンド
sam build MyLayer
エラー
{
"errorType": "Runtime.ImportModuleError",
"errorMessage": "Error: Cannot find module 'MyLayer'\nRequire stack:\n- /var/task/app.js\n- /var/runtime/index.mjs"
}
これ、ちょっとよくわかっていないのですが、そもそもLayerはBuildしなくていいのかもしれないです。
zipファイルをs3に保存しそれをレイヤーに反映するという仕組みを自動でやってくれているように見えます。
buildせずにdeployしたところ、エラーは起きずに正常に更新されていました。
参考にさせていただきました
- AWS SAMによるLambda Layers & Layers利用Functionの作成手順と運用観点での注意点(2021年3月, SAM 1.19版)
- Lambda Layers をnode.js(SAM)で試してみる
layerのデプロイで Error: No changes to deploy.
layerを修正してsam deploy
した時に以下のエラーになりました
Error: No changes to deploy. Stack aws-sam-layers-template is up to date
差分がないのでdeployできないとのこと。sam build
した後でもダメです。
layerだけだと変更を検知してくれない?ようなので、lambda関数の方に何かコメントを入れるなどの修正を加えてsam build
、sam deploy
したところデプロイできて動くようになりました。
ログファイル出力でError: Got unexpected extra argument
ルートディレクトリに logfile.txt
というログ出力ファイルを作成し sam local invokeする際に--log-file logfile.txt
というオプションをつけて実行したところエラーになりました。
コマンド
sam local invoke Func1 --event events/event.json --debug --log-file logfile.txt
エラー
Error: Got unexpected extra argument (logfile.txt)
原因はよくわかってませんがオプションの順番を変えたらうまく動きました
sam local invoke Func1 --log-file logfile.txt --event events/event.json --debug
--event
の後に--log-file
を持ってきてもエラーになりませんでした。
以上