こんにちは。アプリケーションサービス部の河野です。
今回は、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 (執筆記事の一覧)