AppSync と Aurora Serverless を連携する方法

記事タイトルとURLをコピーする

こんにちは。アプリケーションサービス部の河野です。

今回は、Amplify で作成した GraphQL API のデータソースを Amazon Aurora Serverless にする方法をご紹介します。

先にまとめ

以下のポイントを考慮して設定する必要があります。

  • Aurora Serverless V1 で構築する必要がある
  • AppSync と Aurora Serverless の連携は、 Amplify CLI が提供する GraphQL Transformer v1 を使用する必要がある(最新は v2)
  • Amplify Studio で AppSync をプロビジョニングしている場合は、権限を追加する必要がある

Aurora Serverless V2 が使用できないという大きな制約があるため、どうしても RDB として扱いたい場合の選択肢の一つとして頭の片隅に置いておくぐらいが丁度良さそうです。

概要

AppSync は Aurora Serverless V1 をデータソースとして設定することができます。

設定方法については、以下のドキュメントにて紹介されています。

API (GraphQL) - Relational Databases - AWS Amplify Docs

本記事では、ドキュメントで紹介されている設定方法をもとに、解説を交えながら設定していきます。

本記事で構築する構成図

実践

1. Aurora Serveless の構築

まずは、Aurora Serverless を構築します。
Aurora Serverless との連携は、Data API が前提となるため、Serveless V1 を使用する必要があります。(※)

※ 2023/08 時点では V2 は Data API はサポートされていません。 https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/aurora-serverless-v2.upgrade.html#aurora-serverless-v2.move-from-serverless-v1

今回は、以下の Cloudformation テンプレートを使用しました。
VPC とサブネットとセキュリティグループは別途作成してください。

Parameters:
  VPCId:
    Description: VPC to deploy the Aurora Serverless DB cluster
    Type: String
  SubnetId1:
    Description: The first subnet to deploy the Aurora Serverless DB cluster
    Type: String
  SubnetId2:
    Description: The second subnet to deploy the Aurora Serverless DB cluster
    Type: String
  SecurityGroupId:
    Description: Security Group to deploy the Aurora Serverless DB cluster
    Type: String

Resources:
  MyDBSubnetGroup:
    Type: 'AWS::RDS::DBSubnetGroup'
    Properties:
      DBSubnetGroupDescription: Subnet group for Aurora Serverless Cluster
      SubnetIds:
        - !Ref SubnetId1
        - !Ref SubnetId2

  AuroraServerlessCluster:
    Type: 'AWS::RDS::DBCluster'
    Properties:
      Engine: aurora-mysql
      EngineMode: serverless
      MasterUsername: !Sub '{{resolve:secretsmanager:${AuroraMasterSecret}:SecretString:username}}'
      MasterUserPassword: !Sub '{{resolve:secretsmanager:${AuroraMasterSecret}:SecretString:password}}'
      VpcSecurityGroupIds:
        - !Ref SecurityGroupId
      DBSubnetGroupName:
        Ref: MyDBSubnetGroup
      EnableHttpEndpoint: true

  AuroraMasterSecret:
    Type: 'AWS::SecretsManager::Secret'
    Properties:
      GenerateSecretString:
        SecretStringTemplate: '{"username": "admin"}'
        GenerateStringKey: "password"
        PasswordLength: 16
        ExcludeCharacters: '"@/\'

Outputs:
  SecretArn:
    Description: The secret ARN
    Value: !Ref AuroraMasterSecret

2. クエリエディタから接続情報を登録する

RDS のマネジメントコンソールからクエリエディタを開きます。

先ほど作成した Aurora を選択し、「新しいデータベース認証情報を追加します」を選択します。
ユーザー名とパスワードは、連携している Secretes Manager から参照して設定してください。(1. のテンプレート使用した場合、AuroraMasterSecret-xxxx 名で作成されています)

データベースに接続しますをクリックすると、以下のエラーが表示されますが、そのままもう一度クリックすると、問題なく接続されます。

3. テーブルの作成

クエリエディタからテーブルを作成します。

以下のクエリを実行します。

CREATE database MarketPlace;
USE MarketPlace;
CREATE TABLE Customers (
  id int(11) NOT NULL PRIMARY KEY,
  name varchar(50) NOT NULL,
  phone varchar(50) NOT NULL,
  email varchar(50) NOT NULL
);
CREATE TABLE Orders (
  id int(11) NOT NULL PRIMARY KEY,
  customerId int(11) NOT NULL,
  orderDate datetime DEFAULT CURRENT_TIMESTAMP,
  KEY `customerId` (`customerId`),
  CONSTRAINT `customer_orders_ibfk_1` FOREIGN KEY (`customerId`) REFERENCES `Customers` (`id`)
);

4. Amplify の設定

Amplify CLI を使用して GraphQL の API のデータソースを Aurora Serverelss に設定します。

4-1. Amplify 初期化

amplify init でプロジェクトを初期化します。(既にある場合はスキップしてOK)

amplify init

Project information
| Name: blogAppSyncAurora
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: react
| Source Directory Path: src
| Distribution Directory Path: build
| Build Command: npm run-script build
| Start Command: npm run-script start

...

✅ Initialized your environment successfully.

Your project has been successfully initialized and connected to the cloud!

4-2. GraphQL API を追加

ここも既にある場合はスキップしてOK

amplify add api

? Select from one of the below mentioned services: GraphQL
? Here is the GraphQL API that we will create. Select a setting to edit or continue Continue
? Choose a schema template: Blank Schema

Aurora と連携する際に、スキーマは自動生成してくれるので、ここでは Blank Schema を選択しています。

4-3. Aurora Serverless を追加

Aurora Serverless との連携は、Amplify CLI が提供する GraphQL Transformer v1 と呼ばれる機能によって実現されています。

CLI の Feature Flags を設定して、Transformer v1 が使えるように設定します。

Reference - Feature Flags - AWS Amplify Docs

amplify/cli.json の "transformerversion" の値を "1" に変更します。

  "features": {
    "graphqltransformer": {
     ...{省略}
      "transformerversion": 1,
     ...{省略}
     

amplify status を実行して、GraphQL transformer version: 1 が表示されていることを確認します。

    Current Environment: dev
    
┌──────────┬───────────────────┬───────────┬───────────────────┐
│ Category │ Resource name     │ Operation │ Provider plugin   │
├──────────┼───────────────────┼───────────┼───────────────────┤
│ Api      │ blogappsyncaurora │ Create    │ awscloudformation │
└──────────┴───────────────────┴───────────┴───────────────────┘

GraphQL transformer version: 1

Aurora Serverless を設定します。

amplify api add-graphql-datasource

Using datasource: Aurora Serverless, provided by: awscloudformation
✔ Provide the region in which your cluster is located: · ap-northeast-1
✔ Only one Cluster was found: 'blog-aurora-auroraserverlesscluster-xxxxxxx' was automatically selected.
✔ Only one Secret was found for the cluster: 'arn:aws:secretsmanager:ap-northeast-1:XXXXXXXXXXX:secret:rds-db-credentials/cluster-/admin/' was automatically selected.
✔ Fetched Aurora Serverless cluster.
✔ Only one Database was found: 'MarketPlace' was automatically selected.
✅ Successfully added the Aurora Serverless datasource locally

✅ Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud

GraphQL schema compiled successfully.

schema.graphql が、Aurora で作成したテーブルスキーマ情報をもとに自動生成されていることがわかります。

input AMPLIFY {
  globalAuthRule: AuthRule = {allow: public}
}

input CreateCustomersInput {
  id: Int!
  name: String!
  phone: String!
  email: String!
}

type Customers {
  id: Int!
  name: String!
  phone: String!
  email: String!
}

input UpdateCustomersInput {
  id: Int!
  name: String
  phone: String
  email: String
}

input CreateOrdersInput {
  id: Int!
  customerId: Int!
  orderDate: AWSDateTime
}

type Orders {
  id: Int!
  customerId: Int!
  orderDate: AWSDateTime
}

input UpdateOrdersInput {
  id: Int!
  customerId: Int
  orderDate: AWSDateTime
}

type Mutation {
  deleteCustomers(id: Int!): Customers
  createCustomers(createCustomersInput: CreateCustomersInput!): Customers
  updateCustomers(updateCustomersInput: UpdateCustomersInput!): Customers
  deleteOrders(id: Int!): Orders
  createOrders(createOrdersInput: CreateOrdersInput!): Orders
  updateOrders(updateOrdersInput: UpdateOrdersInput!): Orders
}

type Query {
  getCustomers(id: Int!): Customers
  listCustomerss: [Customers]
  getOrders(id: Int!): Orders
  listOrderss: [Orders]
}

type Subscription {
  onCreateCustomers: Customers @aws_subscribe(mutations: ["createCustomers"])
  onCreateOrders: Orders @aws_subscribe(mutations: ["createOrders"])
}

schema {
  query: Query
  mutation: Mutation
  subscription: Subscription
}

ここまで、確認できたら、amplify push で API をデプロイします。

amplify push

デプロイが失敗する場合は、以下のスキーマを削除して再実行してみてください。

input AMPLIFY {
  globalAuthRule: AuthRule = {allow: public}
}

5. AppSync からデータを登録する

正しく連携されているか確認するために、AppSync から Mutation を実行して、Aurora Serverless にデータを登録します。

Aurora Serverless のクエリエディタからデータが登録されているか確認します。

登録されていますね!

Troubleshooting

Amplify Studio で AppSync をプロビショにングしている場合

Amplify Studio の Data Modeling で既に AppSync をプロビジョニングしている状態で、api add-graphql-datasource を実行すると、以下のエラーが表示されることがありました。

🛑 There was an error adding the datasource  
🛑 User: arn:aws:sts::xxxxxxx:assumed-role/ap-northeast-1_h77M6P2JA_Full-access/amplifyadmin is not authorized to perform: rds:DescribeDBClusters on resource: arn:aws:rds:ap-northeast-1:xxxxxxxxxxx:cluster:* because no identity-based policy allows the rds:DescribeDBClusters action

Amplify Studio セットアップ時に作成されるロールに権限が不足しているというエラーです。
ロールに以下権限を付与して再実行してください。

  • rds:DescribeDBClusters
  • secretsmanager:ListSecrets
  • rds-data:ExecuteStatement
  • secretsmanager:GetSecretValue

No database found in the selected cluster が表示される場合

DB cluster が停止していないかを確認しましょう。
クラスター停止している場合に上記のエラーが表示されることがありました。

api add-graphql-datasource コマンドで、クラスターが起動するので、上記エラーが表示された場合は、再度コマンドを実行してみてください。

おわりに

冒頭にも記載しましたが、Arurora Serverless V2 が使用できない大きな制約があるため、注意が必要ですが、どなたかのお役に立てれば幸いです。

swx-go-kawano (執筆記事の一覧)