おーばーびゅー
こんな感じでどちゃくそAPI作っていたら、CloudFormationの制約に当たってしまいdeployできなくなりました...(1 stack内のresource数は最大200まで)
今回はこれを、Nested Stacksなるもので解決していきます。
deployには引き続きServerless Frameworkを用いているので、serverless-plugin-split-stacksというプラグインを導入してdeployするresourceを複数のstackに分けていきます。
環境
macOS Sierra v10.12.6
node.js v9.7.0
yarn v1.5.1
Serverless Framework v1.26.1
serverless-plugin-split-stacks v1.4.1
作業
install
yarn add -D serverless-plugin-split-stacks
すっごい不安定そうな指定...そのうち直します
edit files
serverless.yml内でpluginsの指定
serverless-webpackが入っていますがこれは必須ではなく、私が使っているだけです。
他のpluginはお使いの環境に合わせて適宜指定してください。
...
plugins:
- serverless-webpack
- serverless-plugin-split-stacks
...
splitの仕方をカスタマイズ
運用しているリソース数がやっと200に到達したぐらいであれば以下の作業は行わなくともdeploy出来るかと思います。
私のリソース力は53万400弱まで膨らんでおり、このままではsplitしたNested Stacksでさえ200リソースの制限に引っかかってしまうので、splitのルールを追加で指定していきます。
今回はserverless.ymlのfunctions以下に定義しているfunction名の頭の文字列を見てどのNested Stacksに振り分けるか判断していきます。
下記stacks-map.js
はprojectのトップレベル(serverless.yml
と同階層)に配置してください。
serverless-plugin-split-stacks
が自動で読み込みます。
const ServerlessPluginSplitStacks = require('serverless-plugin-split-stacks');
ServerlessPluginSplitStacks.resolveMigration = function(
resource,
logicalId,
serverless
) {
// logicalIdに関数名+リソース名が入ってきます
// ここにはServerlessがdeployするあらゆるリソースが入ってくるので、'LambdaFunction'や'LambdaPermissionApiGateway'などの多様なリソース名で飛んでくるので、そのprefixのみを見て格納先を判断します
if (logicalId.startsWith('Programs')) {
// 返却するobjectのdestinationに振り分け先のNested Stacksのprefixを渡します
// e.g.: { destination: 'Programs' }を返却するとProgramsNestedStackが作成され、その中にリソースが格納されます
return { destination: 'Programs' };
}
// 上は冗長に書きましたがこんな感じで並べていけば良いです
if (logicalId.startsWith('Tags')) return { destination: 'Tags' };
// Fallback to default:
return this.stacksMap[resource.Type];
};
こうなる
deployの途中でこういう出力が出ます
(若干消している行があるので、このログのリソース数などは合っていません)
> sls deploy --stage local
...
Serverless: [serverless-plugin-split-stacks]: Summary: 238 resources migrated in to 9 nested stacks
Serverless: [serverless-plugin-split-stacks]: Resources per stack:
Serverless: [serverless-plugin-split-stacks]: - (root): 127
Serverless: [serverless-plugin-split-stacks]: - APINestedStack: 44
Serverless: [serverless-plugin-split-stacks]: - ProgramsNestedStack: 12
Serverless: [serverless-plugin-split-stacks]: - TagsNestedStack: 18
Serverless: [serverless-plugin-split-stacks]: - VersionsNestedStack: 13
...
いぇーーい
注意点
splitのカスタマイズは計画的に
途中で
運用しているリソース数がやっと200に到達したぐらいであれば以下の作業は行わなくともdeploy出来るかと思います。
などと書きましたが、特定のresourceはstackを跨いだ移動が不可能です。
今回使用しているプラグインのREADME.mdからも引用します。(2018/03/14)
Many kind of resources (as e.g. DynamoDB tables) cannot be freely moved between CloudFormation stacks (that can only be achieved via full removal and recreation of the stage)
"今はこれで大丈夫だからとりあえずこれでdeploy..."とかせずに、しっかりご自身の計画でsplitの仕方をカスタマイズしていった方が懸命かと思います。
多分すぐobsolete
こんなQiita記事を書いておいてなんですが、 serverless-plugin-split-stacks
はversion 2からLambda function毎にNested Stacksを振り分ける方式になるようです。
その方式をPer Lambdaと呼んでおり、今回使用した方式はPer Typeというものです(実際には関数のprefixで大部分を分けているのでResource Typeによる分割は部分的なものですが)。
目下開発中なようなのでそちらも期待しましょう。
こちらからは以上です。
お疲れ様でした。