この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
好物はインフラとフロントエンドのかじわらゆたかです。
件名の通りなのですが、Serverless Framework とそのプラグインであるserverless-step-functionsを用いた環境でStatemachineを60個以上つくろうとするとエラーとなります。 プラグインにプルリクエストを出すことも考えたのですが、実際に開発中の案件で使っているのもあったのでPatchファイルで暫定対応をしたので、その内容を記載したいと思います。
再現と原因
今回の検証は以下の環境で行いました。
$ node --version
v13.12.0
$ sls --version
Framework Core: 1.67.0
Plugin: 3.6.4
SDK: 2.3.0
Components: 2.28.0
serverless-step-functions : 2.17.4
以下のようなServerless Frameworkのyamlファイルを用意しデプロイすると再現ができます。
service: serverless-many-statemachine
provider:
name: aws
runtime: nodejs12.x
region: ap-northeast-1
plugins:
- serverless-step-functions
stepFunctions:
stateMachines:
StateMachine1:
name: TestStateMachine1
definition:
StartAt: HelloWorld
States:
HelloWorld:
Type: Succeed
StateMachine2:
name: TestStateMachine2
definition:
StartAt: HelloWorld
States:
HelloWorld:
Type: Succeed
中略
StateMachine59:
name: TestStateMachine59
definition:
StartAt: HelloWorld
States:
HelloWorld:
Type: Succeed
StateMachine60:
name: TestStateMachine60
definition:
StartAt: HelloWorld
States:
HelloWorld:
Type: Succeed
上記をデプロイしようとすると以下ようなエラーが発生します。
$ sls deploy --aws-profile cm-di-div
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Validating template...
Error --------------------------------------------------
Error: The CloudFormation template is invalid: Template format error: Outputs count 61 is greater than max allowed 60
以下省略
書いてあるエラーメッセージのとおりなのですが、Serverless Frameworkが作ったCloudFormationのテンプレートがCloudFormationのOutputs の上限に達してしまったため発生したエラーのようです。
こちらはドキュメントにも以下のように記載がされています。
制限 | 説明 | 値 |
---|---|---|
出力 | AWS CloudFormation テンプレートで宣言できる出力の最大数。 | 60 個の出力 |
AWS CloudFormation の制限 - AWS CloudFormation
ワークアラウンドとしての対応
Serverless Step Functions プラグインでStateMachineの情報をCloudformationのOutputに記載している箇所は以下になります。
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Outputs,
newStateMachineOutPutObject);
Deployすることを目的とするならばハイライトされている行を削除することでデプロイは行えるようになります。 ですが、そのような対応ですと削除した箇所を忘れたり、別の人がデプロイするといった際にその対応を忘れてデプロイが失敗してしまうと言った事になってしまうかもしれません。 そのためこのOutputの抑制を行うPatchを書いて暫定措置とします。
NoOutputStatemachineARN.patch
--- ./compileStateMachines.js 2020-04-04 15:44:30.000000000 +0900
+++ ./compileStateMachines_noOutputs.js 2020-04-04 15:44:22.000000000 +0900
@@ -243,9 +243,6 @@ module.exports = {
[stateMachineOutputLogicalId]: stateMachineOutPutObject,
};
- _.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Outputs,
- newStateMachineOutPutObject);
-
return BbPromise.resolve();
});
}
あとは上記のパッチを以下な感じで適用することで、デプロイが行えるようになります。
patch -u node_modules/serverless-step-functions/lib/deploy/stepFunctions/compileStateMachines.js < NoOutputStatemachineARN.patch
またPatchを戻す場合は以下のような形になります。
patch -R node_modules/serverless-step-functions/lib/deploy/stepFunctions/compileStateMachines.js < NoOutputStatemachineARN.patch
結論
serverless-step-functions を使って大量のステートマシンを書いている際にデプロイできないってケースに遭遇した際に、 ワークアラウンドではありますがこの方法をとることでデプロイが行えるようになります。