11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Serverless管理下のリソース達が200制限に達したのでNested Stacksに放り込む(by serverless-plugin-split-stacks)

Last updated at Posted at 2018-03-14

おーばーびゅー

こんな感じでどちゃくそ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はお使いの環境に合わせて適宜指定してください。

serverless.yml
...
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 が自動で読み込みます。

stacks-map.js
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による分割は部分的なものですが)。
目下開発中なようなのでそちらも期待しましょう。

こちらからは以上です。
お疲れ様でした。

11
6
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
11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?