Amazon Web Services ブログ

AWS AppSync Private API の紹介

AWS AppSync は、開発者が 1 つまたは複数のデータソースからデータに安全にアクセス、操作、結合できる GraphQL API を作成できるようにするフルマネージドサービスです。AppSync で GraphQL API を作成すると、API に Query、Mutations、Subscription のリクエストを送信するために使用できるパブリックエンドポイントが生成されます。ただし、Amazon Virtual Private Cloud(VPC)やオンプレミスネットワークなどのプライベートネットワーク内のクライアントは、AppSync のパブリックエンドポイントに到達するために、インターネットを介したネットワークルートが必要になります。これは、AppSync API へのリクエストを送信するためにセキュリティポリシーやファイアウォールルールを変更する必要があるお客様にとっては課題となっていました。

AppSync の Private API の一般提供を発表します。Private API を使用すると、VPC やオンプレミスのデータセンターなどのプライベートネットワーク内のクライアントのみに、お客様の GraphQL API へのアクセスを制限できます。Private API へのリクエストは、インターネットを介さずに AWS のプライベートネットワークを経由して行われます。開始するには、AppSync で GraphQL API を作成する際に API を Private に設定し、API を呼び出す同じ AWS アカウント内の各 VPC にインターフェース VPC エンドポイントを作成します。また、AWS Direct Connect または AWS Site to Site VPN を使用して、オンプレミスネットワークからインターフェイスエンドポイントをホストする VPC へのプライベート接続を確立することができます。この接続により、オンプレミスデータセンターのクライアントは Private API を呼び出すことができます。

下図は、VPC で動作するアプリケーションから AWS AppSync 上の Private API に接続する方法を示しています。この例では、API を呼び出すコンピュートプラットフォームとして Amazon Elastic Compute Cloud (EC2)を使用していますが、AWS LambdaAWS Fargate などの他のコンピュートプラットフォームを使用して API を呼び出す場合も同様の構成となります。アプリケーションからの GraphQL リクエストは、インターフェイスエンドポイントを経由して AWS AppSync にルーティングされます。インターフェースエンドポイントは、AWS AppSync のようなサービス(およびその他の AWS やサードパーティーのサービス)に、あたかも自分の VPC にあるかのようにプライベート接続できる、可用性と拡張性を持った AWS PrivateLink を使用しています。VPC 内のどの Subnet にも導入可能で、高可用性を確保するために各アベイラビリティゾーン(AZ)に少なくとも 1 つのエンドポイントを導入することが推奨されています。

図 1:Amazon VPC から AppSync プライベート API に接続するアーキテクチャ

AppSync Private API を作成しの接続

AWS AppSync の Private API を作成し、VPC 内で動作する EC2 インスタンスから API を呼び出します。以下のような流れで進めていきます。

  • API を Private に設定し、シンプルな Todo API を作成します。
  • 2 つのアベイラビリティゾーン(AZ)にまたがる VPC を作成し、それぞれの AZ に Public Subnet と Private Subnet を設置します。
  • Private Subnet に AWS AppSync 用のインターフェースエンドポイントをアタッチします。
  • Private Subnet に配置された EC2 インスタンスから API を呼び出します。

AppSync Private API の作成

  • AppSync Console に移動し、「API を作成」をクリックします。
  • API 作成ウィザードの Step1 で「Design from scratch」を選択し、「次へ」をクリックします。
    注)既存の DynamoDB テーブルから新しい API を作成する際や、リアルタイム API を作成する際に、Private API を作成することも可能です。

  • Step 2 で、API の名前を指定し、Private API セクションで「Use private API features」のチェックボックスを選択し、「次へ」をクリックします。このチェックボックスを選択すると、API が Private になります。

  • Step 3 の 「Create a GraphQL type」 で「Create type backed by DynamoDB table now」を選択し、 「Model information 」で GraphQL Type の名前(モデル名)を指定し、フィールドと各フィールドのデータ型を指定します。次に、DynamoDB テーブルの名前、プライマリーキー、ソートキーを指定し、完了したら、「次へ」をクリックします。

  • Step 4 で、API の詳細を確認し、「API を作成」をクリックします。API と DynamoDB テーブルの作成が開始され、完了後、API 設定ページに移動すると、API が Private であることを示す新しいステータス「Private API On」が表示されます。また、リージョンに作成した AppSync API のリストには、Private API に付けられた鍵のサインが表示されます。

Public Subnet と Private Subnet を持つ VPC の作成

VPC Console の VPC ウィザードを使用して、VPC を作成することができます。VPC の設定を行うことで、以下のようにパブリックとプライベートの 2 つの Subnet 、ルートテーブル、インターネットゲートウェイ、NAT ゲートウェイを持つ VPC を作成できます。プレビューセクションには、作成されるリソースが表示されます。オプションの「DNS 解決を有効化」と「DNS ホスト名を有効化」が選択されていることを確認します。(これら 2 つの値の詳細については、VPC のドキュメントを参照してください)。

AWS AppSync 用のインターフェースエンドポイントの作成

  • Amazon VPC Console に移動し、左のナビゲーションペインで「エンドポイント」を選択し、「エンドポイントの作成」を選択します。
  • エンドポイントには、appsync-private-api-endpoint のようなネームタグを指定することができます。
  • サービスカテゴリは、AWS のサービス に設定してください

  • サービス名には 「com.amazonaws.{region}.appsync-api」を設定し、リージョンは現在作業しているリージョンに置き換えてください。
  • VPC は、前のステップで作成した VPC を選択します。
  • 「追加設定」セクションを展開し、「DNS 名を有効化」チェックボックスが選択されていることを確認します。これにより、プライベートホストゾーンがレコードセットを含む VPC に関連付けられます。そして、AppSync API URL(例:https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql)を使用してリクエストを行う際に、Amazon の AppSync サービスへのプライベートネットワーク接続を活用できるようになります。

  • エンドポイントを配置する 2 つの AZ と各 AZ の 1 つの Subnet を選択します。今回は Private Subnet にエンドポイントを作成します。
  • セキュリティグループについては、ポート 443(HTTPS)の VPC 内部トラフィックのみを許可するセキュリティグループ appsync-private-api-endpoint-sg を新規作成しました。セキュリティグループは、 Subnet の IP アドレス範囲や API を呼び出すリソースの IP アドレスに絞り込むように設定できます。
  • VPC エンドポイントポリシーでは、「フルアクセス」を選択し、どの AWS プリンシパルでも Private API を呼び出すことができるようにしました。AppSync API に Identity and Access Management(IAM)認可モードを使用している場合、必要な IAM ユーザーとロールにのみ必要な権限を付与するためにカスタムポリシーをスコープを絞るすることをお勧めします。
  • 他のオプションはデフォルトのままにして、「エンドポイントを作成」をクリックします。

EC2 インスタンスから Private API を呼び出す

API を呼び出すために、Private Subnet に展開された EC2 インスタンスを使用します。EC2 インスタンスと VPC エンドポイントに設定されたセキュリティグループは、双方向のインバウンドとアウトバウンドトラフィックを許可する必要があります。AWS System Manager Session Manager を使って EC2 インスタンスに接続し、VPC Reachability Analyzer を使って接続の問題をトラブルシュートすることができます。

Private API を呼び出すには、2 つの異なる DNS 名を使用することができます。

  • プライベート DNS 名(VPC エンドポイントの作成時にプライベート DNS の命名が有効になっている場合)
  • インターフェース VPC エンドポイントパブリック DNS 名

VPC エンドポイントの詳細ページには、以下のようにこれら 2 つの DNS 名が表示されます。

Private DNS 名の場合、API を呼び出すためのベース URL は以下のような形式になります。

https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql

これは、Private APIを作成した際に AppSync が生成した API URL と同じです。(AppSync Consoleの AppSync API 設定ページを参照してください)既に AppSync が生成した API URL を使用している場合は、アプリケーションを変更する必要がありません。

インターフェース 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 エンドポイントのパブリックホスト名を使用する場合、AppSync API エンドポイントのホスト名を Host または x-appsync-domain ヘッダーとしてリクエストに渡す必要があります。

$ curl -v 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 createTodo($createtodoinput: CreateTodoInput!) {createTodo(input: $createtodoinput) {id title description priority}}","variables":"{\"createtodoinput\": {\"title\": \"Hello, world!\",\"description\": \"Hello, world!\",\"priority\": 4}}"}'

サンプルの Todo API を試すために、プライベート DNS 名を使用して API を呼び出します。ここでは、Query と Mutation の送信に curl、Subscription に wscat を使用します。Amazon EC2 Linux では、wscat をインストールするために必要な npm をインストールする必要があります。中括弧内のすべての値を、AWS アカウントの対応する値に置き換えてください。

Mutation のテスト – createTodo リクエスト

$ curl -v https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql \
-H "Content-Type:application/graphql" \
-H "x-api-key:da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}" \
-d '{"query": "mutation createTodo($createtodoinput: CreateTodoInput!) {createTodo(input: $createtodoinput) {id title description priority}}","variables":"{\"createtodoinput\": {\"title\": \"Read emails\",\"description\": \"Read emails\",\"priority\": 4}}"}'

Mutation のテスト – createTodo レスポンス

{
  "data": {
    "createTodo": {
      "id": "fec31cdd-9a45-414f-85eb-fec711ba0a79",
      "title": "Read emails",
      "description": "Read emails",
      "priority": 4
    }
  }
}

Query のテスト – listTodos リクエスト

$ curl -v 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 {listTodos {items {id title description priority}}}","variables":"{}"}'

Query のテスト – listTodos レスポンス

{
  "data": {
    "listTodos": {
      "items": [
        {
          "description": "Read emails",
          "priority": 4,
          "id": "fec31cdd-9a45-414f-85eb-fec711ba0a79",
          "title": "Read emails"
        }
      ]
    }
  }
}

Subscription のテスト – createTodo Mutation のサブスクライブ

AppSync の GraphQL Subscription については「WebSocket リアルタイムクライアントの構築」を参照してください。 AZ1 の Private Subnet にある EC2 インスタンス を onCreateTodo Subscriptionのリクエストを開始するクライアントとして、AZ2 の Private Subnet にある EC2インスタンス をcreateTodo Mutation を実行するクライアントとして使用します。
AZ1 の Private Subnet にある EC2 インスタンスで、以下のコマンドを実行します。

$ header=`echo '{"host":"{api_url_identifier}.appsync-api.{region}.amazonaws.com","x-api-key":"da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}"}' | base64`
$ 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 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"}

AZ2 の Private Subnet にある EC2 インスタンスで、createTodo Mutation を実行します。

$ curl -v https://{api_url_identifier}.appsync-api.{region}.amazonaws.com/graphql \
-H "Content-Type:application/graphql" \
-H "x-api-key:da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}" \
-d '{"query": "mutation createTodo($createtodoinput: CreateTodoInput!) {createTodo(input: $createtodoinput) {id title description priority}}","variables":"{\"createtodoinput\": {\"title\": \"Go to the shops\",\"description\": \"Go to the shops\",\"priority\": 5}}"}'

AZ1 の Private Subnet にある EC2 インスタンスでは、Subscription 通知がトリガーされ、以下のようなメッセージ通知が表示されることが確認できました。

< {"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"}}}}

知っておきたい大切なこと

  • API を Private に設定できるのは、作成時のみです。API は作成後に Private にすることはできず、Private API は作成後に変更することはできません。
  • プライベート DNS を有効にして AWS AppSync の VPC インターフェースエンドポイントを設定すると、VPC 内のリソースが AppSync が生成した API URL を使用して他の AppSync Public APIを呼び出すことができなくなります。これは、Public API へのリクエストが、Public APIで許可されていないインターフェースエンドポイントを経由してルーティングされるためです。このシナリオで Public API を呼び出すには、Public API にカスタムドメイン名を設定し、VPC 内のリソースが Public APIを呼び出すために使用することを推奨します。
  • AWS AppSync の VPC インターフェースエンドポイントでは、同じ AWS アカウントおよびリージョン内の任意の Private API にアクセスすることができます。Private API へのアクセスをさらに制限するために、以下を考慮することができます:
    • 必要な管理者のみが AWS AppSync の VPC エンドポイントインターフェイスを作成できるようにする。
    • VPC 内のリソースから呼び出せる API を制限するために、VPC エンドポイントカスタムポリシーを使用します。
    • VPC 内のリソースに対して、AppSync の API を呼び出すために IAM 認可を使用することを推奨します。API に対してリソースがスコープダウンされたロールを与えられていることを確認してください。
  • Private API をテストするために、テストクライアントまたはクエリエディタは、AWS AppSync の VPC インターフェースエンドポイントを介して API にリクエストを送信する必要があります。テストクライアントは、インターフェイスエンドポイントへのネットワークルートを持つ VPC またはオンプレミスデータセンターのいずれかでセットアップすることができます。

今日から始めましょう!

AppSync Private API は、AWS AppSync が利用可能なすべての AWS リージョンで一般的に利用できます。AppSync が利用可能なリージョンは、AWS Regional Services List を参照して確認できます。Private API の詳細については、 AppSync のドキュメントを参照してください。

著者について

Ozioma Uzoegwu

Ozioma は、Amazon Web Services のシニアソリューションアーキテクトです。あらゆる規模のお客様が AWS クラウドプラットフォーム上で変革し、モダナイズできるよう、アーキテクチャーのガイダンスとベストプラクティスを提供することで支援しています。Web 開発、アーキテクチャ、クラウド、IT マネジメントの分野で長年の経験を持つ。AWS 入社前は、AWS アドバンストコンサルティングパートナーにて、AWS プラクティスのリードアーキテクトとして勤務していました。彼は、サーバーレス技術を使用したモダンなアプリケーションの構築に強い関心を持ち、ソフトウェア開発に情熱を持っています。

本記事は、Introducing Private APIs on AWS AppSync を翻訳したものです。翻訳はソリューションアーキテクトの稲田大陸が担当しました。