AmplifyとAWS CDKを共存させる方法

Amplify を触っていて、GraphQL の API サーバを作るのに便利なことは実感できました。一方で、SQS を使うとか少し逸れたことをしようとすると、自分で CFn テンプレートを書かないといけません。ここは、CDK を使った方が楽だなあと感じるところです。あと、Amplify で CLI の質問に答えながら AWS サービスを設定するのって簡単ですがちょっと面倒になったりして、もっと Infrastructure as Code に寄せたい気もします。

そこで、Amplify を使った方が便利なところは Amplify に任せつつ、自分でゴリゴリ書きたいところは AWS CDK で書く、というように Amplify と AWS CDK を共存させることにしました。

Amplify と AWS CDK の役割分担

役割分担を以下のようにしました。Amplify はお得意の API(GraphQL)と hosting(React) のみとし、それ以外を AWS CDK に寄せました。

Amplify の役割

  • api (GraphQL API で裏側は DynamoDB)
  • hosting (React アプリを載せる)

AWS CDK の役割

  • SQS
  • Lambda (SQS のコンシューマ)
  • ChatBot (CloudWatch カスタムメトリクスで Lambda エラーのアラームを Slack に通知)

連携方法

Amplify と AWS CDK のインタフェースは Amplify API のみとしました。Lambda が API を叩きます。なので、Amplify が自動生成してくれる aws-exports.js や API.ts などのソースファイルを AWS CDK 側から参照できれば連携が可能になります。

なお、AWS CDK が Amplify を参照するだけではなく、逆方向・双方向に参照する場合には、自動生成されるソースや設定ファイルをどうやって参照するか個別に整理する必要があります。本記事では AWS CDK が Amplify を参照するケースのみに絞ります。

ディレクトリ構成

Amplify を動かして生成されるディレクトリ/ファイルはそのままルート直下に置いています。cdk ディレクトリを掘って、cdk init で生成されるディレクトリ/ファイルを放り込んでいます。

.
├── amplify
├── build
├── cdk
│   ├── bin
│   ├── build
│   ├── cdk.out
│   ├── lib
│   ├── node_modules
│   ├── src (Lambda)
│   │   ├── graphql
│   │   └── lambda
│   │   │   ├── a
│   │   │   ├── b
│   │   │   └── c
│   │   └── lib
│   └── test
├── node_modules
├── public
├── src (React + Amplify API)
│   ├── component
│   ├── graphql
│   ├── lib
│   └── screens
└── vendor

cdk/src/graphql に以下のファイルのシンボリックリンクを張って、src/graphql にあるソースを cdk/src/lambda から参照できるようにしました。これで、amplify pushすると API の修正が AWS CDK 側の Lambda にも反映されるようになります。

  • aws-exports.js
  • API.ts
  • mutations.ts
  • queries.ts
  • subscription.ts

付録 1 Amplify の AWS CDK 対応状況

Amplify が AWS CDK をサポートしていれば。。。なのですが、github のチケットを調べてみたところ、Amplify は CDK に対応していないようです。現状開発の見通しも立っていません。

AWS CDK provider #171 https://github.com/aws-amplify/amplify-cli/issues/171

付録 2 Amplify に CFn カスタムリソースを追加する方法

公式ドキュメントにも方法が記載されていますし、実際に手を動かしてみた方もいます。AWS CDK を使わずに CFn でイケる方はその方が話が早いかもしれません。

Custom CloudFormation stacks AWS Amplify で、カスタムカテゴリを作って、カスタムリソースを追加してみた 俺、この AWS Amplify Console でコンテナの自動デプロイ環境が出来たら結婚するんだ

付録 3 CDK synth の出力を Amplify に食わせてみたときのエラー

cdk synth で出力した CFn テンプレートをカスタムリソースとして Amplify に追加してみましたが、エラーを解消できず断念。AWS CLI からaws cloudformationで cdk synth の出力した CFn テンプレートを投げたら成功しました。ここら辺は深掘りせず諦めています。

以下、発生したエラーです。

AWS::CloudFormation::Stack Parameters: [AssetParametersA, AssetParametersB, AssetParametersC] must have values

template.json にパラメータが含まれているので、parameters.json を template.json と同じディレクトリに配置します。

{
  "AssetParametersA": "AAA",
  "AssetParametersB": "BBB",
  "AssetParametersC": "CCC"
}

AWS::CloudFormation::Stack Parameters: [env] do not exist in the template

Amplify から template.json に env 名がパラメータとして渡されてきます。CDK の生成した template.json にはこれが含まれていないので parameters に追加します。

AWS::SQS::Queue The name of a FIFO queue can only include alphanumeric characters, hyphens, or underscores, must end with .fifo suffix and be 1 to 80 in length. (Service: AmazonSQS; Status Code: 400; Error Code: InvalidParameterValue; Request ID: 95e7a36e-0706-5a06-a794-fb7c630a5d99; Proxy: null)

SQS の FIFO キューの名前にはサフィックスとして”.fifo”をつけるべしというエラーです。cdk deployでは問題なくデプロイできたのですが、Amplify に食わせる場合は修正が必要みたいです。ここまでで対応を中断しました。