CI環境でnpm i -g serverlessからsls deployを実行したら、ある時急にエラーが出るようになったので対処方法などをまとめておく。
- [Serverless Framework v1.65.0の仕様変更]
- [対処方法1:スタック名を変更する]
- [対処方法2:旧バージョンのServerless Frameworkを利用する]
- [まとめ]
[Serverless Framework v1.65.0の仕様変更]
2020年3月上旬現在最新であるServerless Framework v1.65.0から、AWS Lambda関数に付与されるIAMロール名の生成ロジックが変更になった。
こちらのプルリクエストがその変更に該当する。
IAMロールの命名規則は次のように変化した。
- v1.64.1:${service}-${stage}-${region}-lambdaRole
- v1.65.0:${stackName}-${region}-lambdaRole
プルリクエストの中でレビュアのmedikoo氏が述べている通り、独自のスタック名(stackName)を定義していなければ、${stackName} = ${service}-${stage}なので問題がない。反対に言えば、独自のスタック名を定義している場合には、問題が発生する。
例として、次のような比較的シンプルなserverless.yml
を考える*1。
シンプルだが、providerのところで無駄に長いstackNameを独自に定義しているところが今回のポイントである。
service: sls1-65-0-roletest provider: region: ap-northeast-1 name: aws runtime: python3.8 stackName: serverless-framework-version-1-65-0-test-stack iamRoleStatements: - Effect: Allow Action: - 's3:ListBucket' Resource: '*' functions: hello: handler: handler.hello events: [] name: sls1-65-0-roletest-dev-hello
この場合、先にあげた命名規則の変更により、Lambda関数hello
に適用されるIAMロールの命名は次のようになる。
- v1.64.1:sls1-65-0-roletest-dev-ap-northeast-1-lambdaRole(48文字)
- v1.65.0:serverless-framework-version-1-65-0-test-stack-ap-northeast-1-lambdaRole(72文字)
sls packageコマンドで生成されたserverless-state.jsonを比較すると一目瞭然である。
ここで重要になるのが、AWS IAMの文字数制限である。
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_iam-limits.html
AWSのドキュメントによると、IAMロール名の制限は64文字であるらしい(エラーが出るまで知らなかった)。
従って、Serverless Framework v1.64.1では上記のserverless.ymlをデプロイすることができるが、Serverless Framework v1.65.0を利用するとIAMロール名が8文字分上限を超えてしまうため、次のようにエラーとなってしまう。
$ sls --version Framework Core: 1.65.0 Plugin: 3.4.1 SDK: 2.3.0 Components: 2.22.3 $ sls deploy Serverless: Packaging service... Serverless: Excluding development dependencies... Serverless: Uploading CloudFormation file to S3... Serverless: Uploading artifacts... Serverless: Uploading service sls1-65-0-roletest.zip file to S3 (410 B)... Serverless: Validating template... Serverless: Updating Stack... Serverless: Checking Stack update progress... .... Serverless: Operation failed! Serverless: View the full error output: https://ap-northeast-1.console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stack/detail?stackId=arn%3Aaws%3Acloudformation%3Aap-northeast-1%3AXXXXXXXXXXXX%3Astack%2Fserverless-framework-version-1-65-0-test-stack%2FXXXXX Serverless Error --------------------------------------- An error occurred: IamRoleLambdaExecution - 1 validation error detected: Value 'serverless-framework-version-1-65-0-test-stack-ap-northeast-1-lambdaRole' at 'roleName' failed to satisfy constraint: Member must have length less than or equal to 64 (Service: AmazonIdentityManagement; Status Code: 400; Error Code: ValidationError; Request ID: XXXXX). Get Support -------------------------------------------- Docs: docs.serverless.com Bugs: github.com/serverless/serverless/issues Issues: forum.serverless.com Your Environment Information --------------------------- Operating System: darwin Node Version: 10.15.0 Framework Version: 1.65.0 Plugin Version: 3.4.1 SDK Version: 2.3.0 Components Version: 2.22.3
[対処方法1:スタック名を変更する]
上記のエラーに対応するには、以下のいずれかの方法でスタック名を変更すれば良い。
- stackNameで定義している名称を短くする
- stackNameを定義せず、短いservice名とstage名の組み合わせをstackNameとする
しかし、いずれの場合でも、CloudFormationとしてのスタック名が変更となってしまう。このため、v1.64.1以前のバージョンで既にServerless Applicationをデプロイしている場合には以前のCloudFormationスタックを名前で特定することができず、古いスタックが削除されないので注意したい。
古いスタックはたいていの場合不要なので、手動で削除する必要がある。
[対処方法2:旧バージョンのServerless Frameworkを利用する]
今回は、CIのジョブが以下のように定義されていた。
- npm i -g serverless - sls deploy
単にnpm i -g serverless
と実行すると、利用可能な最新バージョンがインストールされる。このため、今回のように意図しない修正が含まれている場合、デプロイができずにエラーとなる可能性がある。
これを回避するには、以下のように利用するServerless Frameworkのバージョンを固定すれば良い。
- npm i -g serverless@1.64.1 - sls deploy
ただしこの場合、いつか新機能が実装され、その機能を利用しようとServerless Frameworkをバージョンアップした際に今回の問題に該当する可能性があるため、注意が必要である。
[まとめ]
- Serverless Frameworkをv1.65.0にバージョンアップしてデプロイしたらIAMロール名の長さ制限エラーが出た
- 独自に定義している長いスタック名を短縮するか、スタック名を定義するのをやめることで回避できる
- あるいは、v1.64.1以前のServerless Frameworkを使い続けることでも回避できる
- 検証に利用したコードは以下のリポジトリにコミットしてある
*1:この例ではAWS Lambdaで利用するメモリサイズは考慮していない。Serverless Frameworkのデフォルトが1024MBなので用途に応じて変更した方が良いだろう。https://kdnakt.hatenablog.com/entry/2018/08/22/080000