AWS AppSync プライベート API の使用
Amazon Virtual Private Cloud (Amazon VPC) を使用すると、VPC からのみアクセスできるプライベート API である AWS AppSync プライベート API を作成できます。プライベート API を使用すると、データを公開することなく、内部アプリケーションへの API アクセスを制限し、GraphQL および Realtime エンドポイントに接続できます。
VPC と AWS AppSync サービスの間でとのプライベート接続を確立するには、インターフェイス VPC エンドポイントを作成します。インターフェイスエンドポイントは、インターネットゲートウェイ、NAT デバイス、VPN 接続、AWS Direct Connect 接続のいずれも必要とせずに AWS AppSync API にプライベートにアクセスできる AWS PrivateLink
プライベート API 機能を有効にする前に考慮すべき要素は他にもいくつかあります。
-
プライベート DNS 機能を有効にした状態で AWS AppSyncに対して VPC インターフェイスエンドポイントを設定すると、VPC 内のリソースは、AWS AppSync 生成された API URL を使用して他の AWS AppSync パブリック API を呼び出すことができなくなります。これは、パブリック API へのリクエストがインターフェイスエンドポイント経由でルーティングされるためで、パブリック API では許可されていません。このシナリオでパブリック API を呼び出すには、パブリック API にカスタムドメイン名を設定し、VPC 内のリソースがそのドメイン名を使用してパブリック API を呼び出すことをお勧めします。
-
AWS AppSync プライベート API は VPC からのみ利用できます。AWS AppSync コンソールのクエリエディタは、ブラウザのネットワーク設定が VPC にトラフィックをルーティングできる場合 (VPN 経由または AWS Direct Connect での接続など) にのみ API にアクセスできます。
-
AWS AppSync の VPC インターフェイスエンドポイントを使用すると、同じ AWS アカウントとリージョンのすべてのプライベート API にアクセスできます。プライベート API へのアクセスをさらに制限するには、以下のオプションを検討してください。
-
必要な管理者だけが AWS AppSync の VPC エンドポイントインターフェイスを作成できるようにします。
-
VPC エンドポイントのカスタムポリシーを使用して、VPC 内のリソースから呼び出せる API を制限します。
-
VPC 内のリソースについては、IAM 認可を使用して AWS AppSync API を呼び出すことをお勧めします。そのためには、リソースに API に対してスコープダウンされたロールが割り当てられていることを確認する必要があります。
-
-
IAM プリンシパルを制限するポリシーを作成または使用するときは、メソッドの
authorizationType
をAWS_IAM
またはNONE
に設定する必要があります。
AWS AppSync プライベート API の作成
次の手順で、AWS AppSync サービスでプライベート API を作成する方法を示します。
警告
プライベート API 機能は API の作成中にのみ有効にできます。この設定は、AWS AppSync API または AWS AppSync プライベート API の作成後に変更することはできません。
-
AWS Management Console にサインインして、AppSync コンソール
を開きます。 -
ダッシュボードで、[API の作成] を選択します。
-
-
[API を最初から設計する] を選択し、[次へ] を選択します。
-
[プライベート API] セクションで、[プライベート API 機能を使用する] を選択します。
-
残りのオプションを設定し、API のデータを確認して、[作成] を選択します。
AWS AppSync プライベート API を使用する前に、VPC で AWS AppSync のインターフェイスエンドポイントを設定する必要があります。プライベート API と VPC は同じ AWS アカウントとリージョンに存在する必要があることに注意してください。
AWS AppSync のインターフェイスエンドポイントの作成
Amazon VPC コンソールまたは AWS Command Line Interface (AWS CLI) を使用して、AWS AppSync API のインターフェイスエンドポイントを作成できます。詳細については、 Amazon VPC ユーザーガイド のインターフェイスエンドポイントの作成を参照してください。
プライベート DNS オプションを使用するには、VPC の enableDnsHostnames
および enableDnsSupportattributes
を設定する必要があります。詳細については、「Amazon VPC ユーザーガイド」の「VPC の DNS 属性の表示と更新」を参照してください。インターフェイスエンドポイントのプライベート DNS 機能を有効にすると、以下の形式を使用してデフォルトのパブリック DNS エンドポイントを使用して AWS AppSync API GraphQL と Real-Time エンドポイントにリクエストを行うことができます。
https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql
詳細については、アマゾン ウェブ サービス全般のリファレンスの「サービスエンドポイントとクォータ」を参照してください。
詳細については、Amazon VPC ユーザーガイドの「インターフェイスエンドポイントを介したサービスへのアクセス」を参照してください。
AWS CloudFormation を使用してエンドポイントを作成および設定する方法については、「AWS CloudFormation ユーザーガイド」の「AWS::EC2::VPCEndpoint」リソースを参照してください。
高度な の例
インターフェイスエンドポイントのプライベート DNS 機能を有効にすると、以下の形式を使用してデフォルトのパブリック DNS エンドポイントを使用して AWS AppSync API GraphQL と Real-Time エンドポイントにリクエストを行うことができます。
https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql
インターフェイスの VPC エンドポイントのパブリック DNS ホスト名を使用すると、API を呼び出すためのベース URL は次の形式になります。
https://{vpc_endpoint_id}-{endpoint_dns_identifier}.appsync-api.{region}.vpce.amazonaws.com/graphql
AZ にエンドポイントをデプロイしている場合は、AZ 固有の DNS ホスト名を使用することもできます。
https://{vpc_endpoint_id}-{endpoint_dns_identifier}-{az_id}.appsync-api.{region}.vpce.amazonaws.com/graphql.
VPC エンドポイントのパブリック DNS 名を使用するには、AWS AppSync API エンドポイントのホスト名をヘッダーとして、Host
x-appsync-domain
またはヘッダーとしてリクエストに渡す必要があります。以下の例では、サンプルスキーマの起動TodoAPI
ガイドで作成されたものを使用しています。
curl https://{vpc_endpoint_id}-{endpoint_dns_identifier}.appsync-api.{region}.vpce.amazonaws.com/graphql \ -H "Content-Type:application/graphql" \ -H "x-api-key:da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}" \ -H "Host:{api_url_identifier}.appsync-api.{region}.amazonaws.com" \ -d '{"query":"mutation add($createtodoinput: CreateTodoInput!) {\n createTodo(input: $createtodoinput) {\n id\n name\n where\n when\n description\n }\n}","variables":{"createtodoinput":{"name":"My first GraphQL task","when":"Friday Night","where":"Day 1","description":"Learn more about GraphQL"}}}'
以下の例では、サンプルスキーマの起動ガイドで生成された Todo アプリを使用します。サンプル Todo API をテストするために、プライベート DNS を使用して API を呼び出します。任意のコマンドラインツールを使用できます。この例では curl{ }
内の値を、AWS アカウントの対応する値に置き換えます。
ミューテーション操作のテスト — createTodo
リクエスト
curl https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql \ -H "Content-Type:application/graphql" \ -H "x-api-key:da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}" \ -d '{"query":"mutation add($createtodoinput: CreateTodoInput!) {\n createTodo(input: $createtodoinput) {\n id\n name\n where\n when\n description\n }\n}","variables":{"createtodoinput":{"name":"My first GraphQL task","when":"Friday Night","where":"Day 1","description":"Learn more about GraphQL"}}}'
ミューテーション操作のテスト — createTodo
応答
{ "data": { "createTodo": { "id": "<todo-id>", "name": "My first GraphQL task", "where": "Day 1", "when": "Friday Night", "description": "Learn more about GraphQL" } } }
クエリ操作のテスト — listTodos
リクエスト
curl https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql \ -H "Content-Type:application/graphql" \ -H "x-api-key:da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}" \ -d '{"query":"query ListTodos {\n listTodos {\n items {\n description\n id\n name\n when\n where\n }\n }\n}\n","variables":{"createtodoinput":{"name":"My first GraphQL task","when":"Friday Night","where":"Day 1","description":"Learn more about GraphQL"}}}'
クエリ操作のテスト — listTodos
リクエスト
{ "data": { "listTodos": { "items": [ { "description": "Learn more about GraphQL", "id": "<todo-id>", "name": "My first GraphQL task", "when": "Friday night", "where": "Day 1" } ] } } }
サブスクリプション操作のテスト — createTodo
ミューテーションへのサブスクライブ
AWS AppSyncで GraphQL サブスクリプションをセットアップするには、「リアルタイム WebSocket クライアントの構築」を参照してください。VPC の Amazon EC2 インスタンスから、wscat API
KEY
を使用しています。
$ header=`echo '{"host":"{api_url_identifier}.appsync-api.{region}.amazonaws.com","x-api-key":"da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}"}' | base64 | tr -d '\n'` $ wscat -p 13 -s graphql-ws -c "wss://{api_url_identifier}.appsync-realtime-api.us-west-2.amazonaws.com/graphql?header=$header&payload=e30=" Connected (press CTRL+C to quit) > {"type": "connection_init"} < {"type":"connection_ack","payload":{"connectionTimeoutMs":300000}} < {"type":"ka"} > {"id":"f7a49717","payload":{"data":"{\"query\":\"subscription onCreateTodo {onCreateTodo {description id name where when}}\",\"variables\":{}}","extensions":{"authorization":{"x-api-key":"da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}","host":"{api_url_identifier}.appsync-api.{region}.amazonaws.com"}}},"type":"start"} < {"id":"f7a49717","type":"start_ack"}
または、VPC エンドポイントのドメイン名を使用し、wscat
ウェブソケットを確立するコマンドで必ず Host ヘッダーを指定してください。
$ header=`echo '{"host":"{api_url_identifier}.appsync-api.{region}.amazonaws.com","x-api-key":"da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}"}' | base64 | tr -d '\n'` $ wscat -p 13 -s graphql-ws -c "wss://{vpc_endpoint_id}-{endpoint_dns_identifier}.appsync-api.{region}.vpce.amazonaws.com/graphql?header=$header&payload=e30=" --header Host:{api_url_identifier}.appsync-realtime-api.us-west-2.amazonaws.com Connected (press CTRL+C to quit) > {"type": "connection_init"} < {"type":"connection_ack","payload":{"connectionTimeoutMs":300000}} < {"type":"ka"} > {"id":"f7a49717","payload":{"data":"{\"query\":\"subscription onCreateTodo {onCreateTodo {description id priority title}}\",\"variables\":{}}","extensions":{"authorization":{"x-api-key":"da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}","host":"{api_url_identifier}.appsync-api.{region}.amazonaws.com"}}},"type":"start"} < {"id":"f7a49717","type":"start_ack"}
以下のミューテーションコードを実行します。
curl https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql \ -H "Content-Type:application/graphql" \ -H "x-api-key:da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}" \ -d '{"query":"mutation add($createtodoinput: CreateTodoInput!) {\n createTodo(input: $createtodoinput) {\n id\n name\n where\n when\n description\n }\n}","variables":{"createtodoinput":{"name":"My first GraphQL task","when":"Friday Night","where":"Day 1","description":"Learn more about GraphQL"}}}'
その後、サブスクリプションがトリガーされ、次のようなメッセージ通知が表示されます。
< {"id":"f7a49717","type":"data","payload":{"data":{"onCreateTodo":{"description":"Go to the shops","id":"169ce516-b7e8-4a6a-88c1-ab840184359f","priority":5,"title":"Go to the shops"}}}}
IAM ポリシーを使用してパブリック API の作成を制限する
AWS AppSync プライベート API で使用する IAM Condition
ステートメントをサポートします。visibility
フィールドを appsync:CreateGraphqlApi
オペレーションの IAM ポリシーステートメントに含めて、どの IAM ロールとユーザーがプライベート API とパブリック API を作成できるかを制御できます。これにより、IAM 管理者は、ユーザーにプライベート GraphQL API の作成のみを許可する IAM ポリシーを定義できます。ユーザーがパブリック API を作成しようとすると、許可されていないメッセージが届きます。
たとえば、IAM 管理者はプライベート API の作成を許可する次の IAM ポリシーステートメントを作成できます。
{ "Sid": "AllowPrivateAppSyncApis", "Effect": "Allow", "Action": "appsync:CreateGraphqlApi", "Resource": "*", "Condition": { "ForAnyValue:StringEquals": { "appsync:Visibility": "PRIVATE" } } }
IAM 管理者は以下のサービスコントロールポリシーを追加して、AWS 組織内のすべてのユーザーがプライベート AWS AppSync API 以外の API を作成できないようにすることもできます。
{ "Sid": "BlockNonPrivateAppSyncApis", "Effect": "Deny", "Action": "appsync:CreateGraphqlApi", "Resource": "*", "Condition": { "ForAnyValue:StringNotEquals": { "appsync:Visibility": "PRIVATE" } } }