AWS AppSync を使用して VPC のプライベートリソースにアクセスするにはどうすればよいですか?

最終更新日: 2022 年 7 月 6 日

AWS AppSync GraphQL API から Amazon Virtual Private Cloud (Amazon VPC) リソースにアクセスする方法が分かりません。

簡単な説明

AWS AppSync GraphQL API から Amazon VPC リソースにアクセスするには、以下のステップに従います。

  1. アクセスするリソースと同じ Amazon VPC 内で実行する AWS [Lambda function] (Lamda 関数) を作成します。
  2. AWS AppSync API を作成し、Lambda 関数を[data source] (データソース) としてアタッチします。
  3. AWS AppSync の [API schema] (APIスキーマ) を設定します。
  4. [Lambda resolver] (Lamda リゾルバー) または[direct Lambda resolver] (ダイレクト Lambda リゾルバー) のいずれかをターゲットの GraphQL フィールドにアタッチします。
  5. GraphQL フィールドをテストします。

Amazon VPC のプライベートサブネットに接続するよう Lambda 関数を設定すると、Amazon VPC のプライベートリソースにアクセスできます。ダウンストリームのプライベートリソースの結果が、AWS AppSync GraphQL API に戻され、クライアントに返されます。プライベートリソースには、データベース、コンテナ、プライベート API、プライベート Amazon OpenSearch Service ドメイン、あるいはアプリケーションまたは Network Load Balancer の背後にあるその他のプライベートサービスが含まれます。

AWS AppSync は、[Lambda public service endpoints] (Lambda パブリックサービスエンドポイント) を介して Lambda API を呼び出します。呼び出された API は、[Signature Version 4 signing process] (Signature バージョン 4 の署名プロセス) によって保護されています。これにより、AWS AppSync は、ターゲットの Lambda 関数を呼び出す権限を持つ AWS Identity and Access Management (IAM) のロールを引き受けることができます。Amazon VPC にアクセスするように設定された Lambda 関数についての詳細は、「Lambda の VPC ネットワーキング」を参照してください。

注:

  • AWS AppSync がサポートするのはパブリックのエンドポイントのみです。 回避策として、Lambda リゾルバーを Amazon VPC リソースのエントリポイントに使用します。
  • Amazon VPC のプライベートリソースと AWS AppSync API の間に Lambda 関数を追加すると、わずかな遅延オーバーヘッドで新規アプリケーションレイヤーが導入されます。
  • Lambda 関数を備えた Amazon VPC の使用には、追加料金が発生します。詳細については、「Lambda の価格設定」を参照してください。

解決方法

注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生する場合は、最新の AWS CLI バージョンを使用していることを確認してください

アクセスするリソースと同じ Amazon VPC 内で実行する AWS Lambda 関数を作成します

次のシナリオ例では、既存の内部 Application Load Balancer が Python Lambda 関数から呼び出されています。Id 値は、AWS AppSync 呼び出しが Lambda に送信するイベントオブジェクトで渡す [arguments] (引数) パラメーターから取得されます。

import urllib.request
import json

def lambda_handler(event, context):
  URL = 'http://XXXXXXXXXXX.us-east-1.elb.amazonaws.com/' + event['arguments']['id']  
  #Open the JSON reponse, read it, convert it to JSON object and return it
  response = urllib.request.urlopen(URL)
  raw_json = response.read()
  loaded_json = json.loads(raw_json) 
  return loaded_json

注: ダイレクト Lambda リゾルバーの場合、関数は[context] (コンテキスト) オブジェクト全体を構成するペイロードを受け取ります。

Lambda 関数からのレスポンスの例:

{
  "id": "25",
  "name": "hamburger",
  "available": true
}

AWS AppSync API を作成し、Lambda 関数をデータソースとしてアタッチします

AWS マネジメントコンソールを使用する

AWS AppSync で GraphQL API を作成する。

  1. AWS AppSync コンソールを開きます。
  2. ダッシュボードで、[Create API] (APIを作成する) を選択します。
  3. [Getting Started] (はじめに) ページの [APIのカスタマイズ] または [Amazon DynamoDB からインポート] で、[Build from scratch] (最初からビルド) を選択します。
  4. [Start] (開始する) を選択します。
  5. [API name] (API 名) フィールドに API 名を入力します。
  6. [Create] (作成) を選択します。

注: 上記のステップで、7 日間有効な承認用 API キーが自動的に生成されます。ただし、[any authorization type] (任意の認証タイプ) を使用できます。

Lambda データソースを作成する。

  1. AWS AppSync コンソールを開きます。
  2. [Data Sources] (データソース) を選択します。
  3. [Create data source] (データソースの作成) を選択します。
  4. [Create new Data Source] (新しいデータソースの作成) で、定義するデータソース名を入力します。
    [Data source type] (データソースタイプ) で、[Amazon Lambda function] (Amazon Lambda 関数) を選択します。
    [Region] (リージョン)で、Lambda 関数を含む AWS リージョンを選択します。
    [Function ARN] (関数 ARN)で、作成した関数を選択します。
  5. AWS AppSync が Lambda 関数を管理できるように既存のロールを提供します。ウィザードに作成させることもできます。
  6. [Create] (作成) を選択します。

AWS コマンドラインインターフェイス (AWS CLI) を使用する

1.    API_KEY を使用して GraphQL API を作成し、テスト用のデフォルトの認証タイプとします。

$ aws appsync create-graphql-api --name api-name --authentication-type API_KEY

注: api name を API の名前に置き換えます。

2.    [Create an API key] (API キーの作成) :

$ aws appsync create-api-key --api-id apiId

注:apiId を API の ID に置き換えてください。

3.    データソースで使用される IAM ロールを作成してから、AWS AppSync がロールを引き受けることを許可する信頼ポリシーをアタッチします。

$ aws iam create-role --role-name Test-Role-for-AppSync --assume-role-policy-document file://trustpolicy.json

信頼ポリシー JSON:

{
  "Version": "2012-10-17",
  "Statement": [
      {
          "Effect": "Allow",
          "Principal": {
              "Service": "appsync.amazonaws.com"
          },   
         "Action": "sts:AssumeRole"
      }
  ]
}

4.    権限ポリシーをロールに埋め込みます。

$ aws iam put-role-policy --role-name Test-Role-for-AppSync --policy-name Permissions-Policy-For-AppSync --policy-document file://permissionspolicy.json

権限ポリシー JSON:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowFunctionInvocation",
      "Effect": "Allow",
      "Action": "lambda:InvokeFunction",
      "Resource": [
        "lambda-ARN"
      ]
    }
  ]
}

注: lambda-ARNを Lambda ARN に置き換えます。

5.    データソースを作成し、IAM ロールと Lambda 関数の ARN を示します。

$ aws appsync create-data-source --api-id apiId \
--name LambdaDataSourceName \
--type AWS_LAMBDA \
--service-role-arn IAM-role-ARN \
--lambda-config lambdaFunctionArn=Lambda-function-ARN

注: LambdaDataSourceNameをデータソースの名前に、apiIdを API の ID に、IAM-role-ARNを IAM ロールの ARN に、Lambda-function-ARNを Lambda 関数の ARN に置き換えます。

AWS AppSync API スキーマを設定する

AWS マネジメントコンソールを使用する

Lambda 関数の応答にアクセスするように GraphQL スキーマの定義を構成します。

1.    AWS AppSync コンソールを開きます。

2.    左側のパネルで、[Schema] (スキーマ) を選択します。

3.    提供されたスキーマをコピーしてエディターに貼り付けます。

次のスキーマの例には、[Product] (製品) タイプの構造を持つデータを返す[response] (レスポンス) クエリがあります。

type Product {
    id: ID!
    name: String
    available: Boolean
}

type Query {
    response(id: ID!): Product
}

schema {
    query: Query
}

4.    [Save Schema] (スキーマを保存) を選択します。

AWS CLI を使用する

1.    前の GraphQL スキーマを schema.graphqlとして保存します。

2.    AWS AppSync でスキーマを作成します

$ aws appsync start-schema-creation --api-id "apiId" --definition fileb://schema.graphql

注: apiId を API の ID に置き換えます。

Lambda リゾルバーまたは直接 Lambda リゾルバーのいずれかを GraphQL フィールドにアタッチします

AWS マネジメントコンソールを使用する

リゾルバーをアタッチする。

  1. AWS AppSync コンソールを開きます。
  2. API の [Schema] (スキーマ) ページの [Resolvers] (リゾルバー) で、[response query] (レスポンスクエリ) までスクロールします。または、リゾルバータイプの[query] (クエリ)でフィルタリングします。
  3. [Response] (レスポンス)フィールドの横にある [Attach] (アタッチ) を選択します。
  4. [Create new Resolver] (新しいリゾルバーの作成) ページの [Data source name] (データソース名)で、Lambda データソースの名前を選択します。注: シナリオの例では、 Lambda のダイレクトインテグレーションが使用されているため、マッピングテンプレートを設定する必要はありません。
  5. [Save Resolvers] (リゾルバーを保存) を選択します。

AWS CLI を使用する

ダイレクト Lambda リゾルバーを作成し、前のステップのデータソース名を指定します。

$ aws appsync create-resolver \
--field-name response \
--type-name Query \
--api-id "apiId" \
--data-source-name LambdaDataSourceName

注: apiIdを API の ID に、LambdaDataSourceNameを作成したデータソースの名前に置き換えます。

GraphQL フィールドのテスト

GraphQL フィールドをテストするには:

1.    AWS AppSync コンソールを開きます。

2.    左のナビゲーションペインで、[Queries] をクリックします。

3.    クエリエディタで、GraphQL クエリを設計します。

GraphQL クエリの例:

query MyQuery {
  response(id: "1") {
    available
    name
    id
  }
}

上記のクエリは、Application Load Balancer から製品 ID 1を取得します。

4.    テストクエリを実行するには、[Play] (再生) を選択します。

API からのレスポンスの例:

{
  "data": {
    "response": {
      "available": false,
      "id": "1",
      "name": "pizza"
    }
  }
}

ターミナルの使用

POST メソッドを呼び出してクエリを実行します。次の例では、curlコマンドを使用します。

$ curl --request POST 'https://<Grapqhl-API-endpoint>/graphql' \
--header 'Content-Type: application/graphql' \
--header 'x-api-key: api-key' \
--data-raw '{"query":"query MyQuery {\n  response(id: \"1\") {\n available\n    id\n    name\n  }\n}\n","variables":{}}'

注: api-keyを API キーに置き換えてください。