AWS AppSync プライベート API の使用 - AWS AppSync

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

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 を利用しています。VPC のインスタンスは、パブリック IP アドレスがなくても AWS AppSync API と通信できます。VPC と AWS AppSync との間のトラフィックは、AWS ネットワークを離れません。

プライベート 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 プリンシパルを制限するポリシーを作成または使用するときは、メソッドの authorizationTypeAWS_IAM または NONE に設定する必要があります。

AWS AppSync プライベート API の作成

次の手順で、AWS AppSync サービスでプライベート API を作成する方法を示します。

警告

プライベート API 機能は API の作成中にのみ有効にできます。この設定は、AWS AppSync API または AWS AppSync プライベート API の作成後に変更することはできません。

  1. AWS Management Console にサインインして、AppSync コンソールを開きます。

    1. ダッシュボードで、[API の作成] を選択します。

  2. [API を最初から設計する] を選択し、[次へ] を選択します。

  3. [プライベート API] セクションで、[プライベート API 機能を使用する] を選択します。

  4. 残りのオプションを設定し、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 ユーザーガイドインターフェイスエンドポイントの作成を参照してください。

Console
  1. AWS Management Console にサインインし、Amazon VPC コンソールの [エンドポイント] ページを開きます。

  2. [Create endpoint] (エンドポイントの作成) を選択します。

    1. [サービスカテゴリ] フィールドで、[AWS サービス] が選択されていることを確認します。

    2. [サービス] テーブルで、[com.amazonaws.{region}.appsync-api] を選択します。Type 列の値が Interface であることを確認します。

    3. VPC フィールドで、VPC とそのサブネットを選択します。

    4. インターフェイスエンドポイントのプライベート DNS を有効にするには、[DNS 名を有効にする] チェックボックスをオンにします。

    5. [セキュリティグループ] フィールドで、1 つ以上のセキュリティグループを選択します。

  3. [Create endpoint] (エンドポイントの作成) を選択します。

CLI

create-vpc-endpoint コマンドを使用し、VPC ID、VPC エンドポイントタイプ (インターフェイス)、サービス名、エンドポイントを使用するサブネット、およびエンドポイントネットワークインターフェイスに関連付けるセキュリティグループを指定します。例:

$ aws ec2 create-vpc-endpoint —vpc-id vpc-ec43eb89 \ —vpc-endpoint-type Interface \ —service-name com.amazonaws.{region}.appsync-api \ —subnet-id subnet-abababab —security-group-id sg-1a2b3c4d

プライベート 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 を使用してクエリとミューテーションを送信し、wscat を使用してサブスクリプションを設定します。この例をエミュレートするには、以下のコマンドの括弧 { } 内の値を、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 を使用して AWS AppSync プライベート API サブスクリプションエンドポイントをテストできます。以下の例では、認証に 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" } } }