LoginSignup
0
0

More than 1 year has passed since last update.

【Lambda】SAMではまったこと【Node.js】

Last updated at Posted at 2022-10-28

SAMを触ってみてはまったことなどをメモします。

template.yamlのRoleでエラー 1

sam initでHello Worldプロジェクトを作成し、
sam buildsam 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を指定してビルドしたらエラーになりました

sam-app
.
├── 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
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したところ、エラーは起きずに正常に更新されていました。

参考にさせていただきました

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 buildsam 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を持ってきてもエラーになりませんでした。

以上

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0