如何使用 AWS AppSync 访问我 VPC 中的私有资源?

4 分钟阅读
0

我想从自己的 AWS AppSync GraphQL API 访问 Amazon Virtual Private Cloud(Amazon VPC)资源,但我不知道该怎么做。

简短描述

要从 AWS AppSync GraphQL API 访问 Amazon VPC 资源,请按照以下步骤操作:

  1. 创建一个 AWS Lambda 函数,以便在与要访问的资源相同的 Amazon VPC 中运行。
  2. 创建一个 AWS AppSync API,然后将 Lambda 函数附加为数据来源
  3. 配置 AWS AppSync API 架构
  4. Lambda 解析程序Direct Lambda 解析程序附加到目标 GraphQL 字段。
  5. 测试 GraphQL 字段。

通过将 Lambda 函数配置为连接到 Amazon VPC 中的私有子网,您可以访问 Amazon VPC 中的私有资源。然后,下游私有资源的结果将传回 AWS AppSync GraphQL API 并返回给客户端。私有资源包括数据库、容器、私有 API、私有 Amazon OpenSearch Service 域,或应用程序或网络负载均衡器背后的其他私有服务。

AWS AppSync 通过 Lambda 公有服务端点调用 Lambda API。调用的 API 受签名版本 4 签名流程的保护。这允许 AWS AppSync 代入 AWS Identity and Access Management(IAM)角色,该角色具有调用目标 Lambda 函数的权限。有关配置为访问 Amazon VPC 的 Lambda 函数的信息,请参阅适用于 Lambda 的 VPC 网络

注意:

  • AWS AppSync 仅支持公有端点。使用 Lambda 解析程序作为 Amazon VPC 资源的入口点,也是一种解决方法。
  • 在 Amazon VPC 私有资源和 AWS AppSync API 之间添加 Lambda 函数,会引入一个延迟开销很小新应用程序层。
  • 如果您使用带有 Lambda 函数的 Amazon VPC,则会产生额外费用。有关更多信息,请参阅 Lambda 定价

解决方法

**注意:**如果您在运行 AWS CLI 命令时收到错误消息,请确保您运行的是最新版本的 AWS CLI

创建一个 AWS Lambda 函数,以便在与要访问的资源相同的 Amazon VPC 中运行

以下示例场景展示从 Python Lambda 函数调用现有的内部应用程序负载均衡器。从 AWS AppSync 调用发送到 Lambda 的 event 对象中传递的 arguments 参数中获得一个 id 值。

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

**注意:**对于 Direct 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(入门)页面的 Customize your API or import from Amazon DynamoDB(自定义 API 或从 Amazon DynamoDB 中导入)下,选择 Build from scratch(从头开始构建)。
  4. 选择 Start(开始)。
  5. API name(API 名称)字段中,输入 API 的名称。
  6. 选择 Create(创建)。

**注意:**上述步骤会自动创建有效期为七天的 API 密钥用于授权。不过,您可以使用任何授权类型

要创建 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 名称替换为您 API 的名称。

2.    创建 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 管理控制台

配置 GraphQL 架构定义以访问 Lambda 函数响应:

1.    打开 AWS AppSync 控制台

2.    在左侧面板中,选择 Schema(架构)。

3.    将提供的架构复制并粘贴到编辑器中。

以下架构示例具有的 response(响应)查询可返回 Product(产品)类型结构的数据:

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 解析程序或 Direct 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

创建 Direct 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
  }
}

上述查询从应用程序负载均衡器获取产品 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 密钥。


相关信息

使用 AWS AppSync 和 AWS Amplify 简化对多种微服务的访问

使用 AWS AppSync、AWS Lambda、Amazon ElastiCache 和 Amazon EventBridge 构建 Presence API

AWS AppSync 的安全最佳实践

Lambda 函数的预置并发功能

AWS 官方
AWS 官方已更新 2 年前