1
0

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 3 years have passed since last update.

serverless-plugin-split-stacksでAppSyncのResolverをデプロイする

Posted at

環境

"serverless-plugin-split-stacks": "^1.9.3",
"serverless-appsync-plugin": "^1.3.1",
"serverless": "^1.78.1",

appsyncをserverless fwでデプロイするのはつらい

serverless-appsync-plugin でappsyncをデプロイしてみると、以下のようなエラーによく遭遇する。

template may not exceed 460800 bytes in size

具体的には、Resolverをプロビジョンする部分のテンプレートが大きくなりがちという問題がある。

ResolverのCloudFormationを見てみる


    "GraphQlResolverQuerylistUsers": {
      "Type": "AWS::AppSync::Resolver",
      "DependsOn": [],
      "Properties": {
        "ApiId": {
          "Ref": "GraphQlApiApiIdParameter"
        },
        "TypeName": "Query",
        "FieldName": "listCards",
        "RequestMappingTemplate": "\n  #set( $limit = (中略) n$util.toJson($ctx.result)\n  ",
        "Kind": "UNIT",
        "DataSourceName": {
          "Ref": "GraphQlDsUserNameParameter"
        }
      }
    },

こんな感じのJSONがResolverの数だけ並んでいる。
例では略しているが、RequestMappingTemplate フィールドにvtlのソースがすべて入っているのがサイズの増大に寄与していることがわかる

serverless-plugin-split-stacks

素直に使う

serverless fwでデプロイされるcloudformationテンプレートを分割してくれるやつ。

serverless-appsync-plugin では、以下のように使うよう書いてある。

You can use serverless-plugin-split-stacks to migrate AppSync resources in nested stacks in order to work around the 200 resource limit.

Create stacks-map.js in the root folder
module.exports = {
'AWS::AppSync::ApiKey': { destination: 'AppSync', allowSuffix: true },
'AWS::AppSync::DataSource': { destination: 'AppSync', allowSuffix: true },
'AWS::AppSync::FunctionConfiguration': { destination: 'AppSync', allowSuffix: true },
'AWS::AppSync::GraphQLApi': { destination: 'AppSync', allowSuffix: true },
'AWS::AppSync::GraphQLSchema': { destination: 'AppSync', allowSuffix: true },
'AWS::AppSync::Resolver': { destination: 'AppSync', allowSuffix: true }
}

この設定の意味するところはAWS::AppSync::Resolver タイプのリソースをAppSyncNestedStackみたいな名前のテンプレートに移動させるというものになる。
ただ、見ての通り、この通りにしたところで、AWS::AppSync::Resolver タイプのリソースの分割先は一つのままなので、Resolverのリソースが十分に大きい場合、サイズ問題は解決できない。

工夫する

serverless-plugin-split-stacks のドキュメントをよく読むと、動的に移動先のテンプレートを決められるとある。
なのでこれをうまく利用してみる。
結果的に以下のようになった。

// stacks-map.js
const def = {
  'AWS::AppSync::ApiKey': { destination: 'AppSyncApi', allowSuffix: true },
  'AWS::AppSync::DataSource': { destination: 'AppSync', allowSuffix: true },
  'AWS::AppSync::FunctionConfiguration': { destination: 'AppSyncFunction', allowSuffix: true },
  'AWS::AppSync::GraphQLApi': { destination: 'AppSyncApi', allowSuffix: true },
  'AWS::AppSync::GraphQLSchema': { destination: 'AppSyncSchema', allowSuffix: true },
}

let count = 0
module.exports =
  (resource, logicalId) => {
    if (resource.Type in def) {
      return def[resource] // 何か設定したいとき向け
    }

    if (resource.Type === 'AWS::AppSync::Resolver') {
      count++
      return {
        destination: `AppSyncResolver${Math.floor(count / 100)}`, // 100個ずつにする
        force: true // 既存のリソースが別のテンプレートにあった場合も、強制的に異動させる(Resolverは永続層などではなく単なるソースコードなので、移動しても影響はない)
      }
    }

// return undefinedすると、デフォルトの分割先が自動的にあてがわれるので特に指定不要
  };

すると、デプロイすると以下のようになる。

Serverless: Packaging service...
Serverless: [serverless-plugin-split-stacks]: Summary: 204 resources migrated in to 6 nested stacks
Serverless: [serverless-plugin-split-stacks]:    Resources per stack:
Serverless: [serverless-plugin-split-stacks]:    - (root): 106
Serverless: [serverless-plugin-split-stacks]:    - AppSyncApiNestedStack: 1
Serverless: [serverless-plugin-split-stacks]:    - AppSyncFunctionNestedStack: 10
Serverless: [serverless-plugin-split-stacks]:    - AppSyncNestedStack: 36
Serverless: [serverless-plugin-split-stacks]:    - AppSyncResolver0NestedStack: 99
Serverless: [serverless-plugin-split-stacks]:    - AppSyncResolver1NestedStack: 57
Serverless: [serverless-plugin-split-stacks]:    - AppSyncSchemaNestedStack: 1

意図したとおり、AppSyncResolver0NestedStack AppSyncResolver1NestedStack のように、動的に採番されたテンプレートが生成されるようになった。

1
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?