Como uso o AWS AppSync para acessar recursos privados na minha VPC?

Data da última atualização: 06/07/2022

Gostaria de acessar os recursos da Amazon Virtual Private Cloud (Amazon VPC) a partir da minha API do AWS AppSync GraphQL, mas não sei como fazer isso.

Breve descrição

Para acessar os recursos da Amazon VPC a partir de uma API do AWS AppSync GraphQL, siga estas etapas:

  1. Crie uma função do AWS Lambda para ser executada dentro da mesma Amazon VPC na qual estão os recursos que deseja acessar.
  2. Crie uma API do AWS AppSync e, em seguida, anexe a função do Lambda como a fonte de dados.
  3. Configure o esquema da API do AWS AppSync.
  4. Anexe um resolvedor Lambda ou um resolvedor Lambda direto ao campo GraphQL de destino.
  5. Teste o campo GraphQL.

Configurar uma função do Lambda para se conectar nas sub-redes privadas em uma Amazon VPC permite que o acesso aos recursos privados na Amazon VPC. Os resultados dos recursos privados downstream são então repassados de volta para a API do AWS AppSync GraphQL e retornados ao cliente. Os recursos privados incluem bancos de dados, contêineres, APIs privadas, domínios privados do Amazon OpenSearch Service ou outros serviços privados por trás de um Application ou Network Load Balancer.

O AWS AppSync invoca a API do Lambda por meio de endpoints de serviço público do Lambda. A API invocada é protegida pelo processo de assinatura Signature versão 4. Isso permite que o AWS AppSync assuma uma função do AWS Identity and Access Management (IAM) com permissões para invocar a função do Lambda de destino. Para obter informações sobre as funções do Lambda configuradas para acessar sua Amazon VPC, consulte rede VPC para Lambda.

Observação:

  • Somente os endpoints públicos são compatíveis com o AWS AppSync. Como solução alternativa, use os resolvedores do Lambda como um ponto de entrada para os recursos da Amazon VPC.
  • A adição de uma função do Lambda entre os recursos privados da Amazon VPC e a API do AWS AppSync apresenta uma nova camada de aplicação com uma pequena sobrecarga de latência.
  • Caso uma Amazon VPC seja usada com as funções do Lambda, haverá cobranças adicionais. Para obter mais informações, consulte definição de preço do Lambda.

Resolução

Observação: caso receba erros ao executar comandos da AWS CLI, verifique e confirme se a versão mais recente da AWS CLI está sendo usada.

Crie uma função do AWS Lambda para ser executada dentro da mesma Amazon VPC onde estão os recursos que deseja acessar

No cenário de exemplo a seguir, um Application Load Balancer interno existente é chamado a partir de uma função Python Lambda. Um valor de id é obtido a partir do parâmetro arguments que é passado no objeto de event que a invocação do AWS AppSync envia ao Lambda.

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

Observação: para resolvedores Lambda diretos, a função recebe uma carga útil que consiste em todo o objeto de contexto.

Exemplo de resposta da função Lambda:

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

Crie uma API do AWS AppSync e anexe a função do Lambda como fonte de dados

Como usar o Console de Gerenciamento da AWS

Para criar a API do GraphQL no AWS AppSync:

  1. Abra o console do AWS AppSync.
  2. No painel, escolha Criar API.
  3. Na página Conceitos básicos, em Personalizar sua API ou importar a partir do Amazon DynamoDB, escolha Criar do zero.
  4. Selecione Iniciar.
  5. No campo Nome da API, insira um nome para a API.
  6. Escolha Create (Criar).

Observação: as etapas anteriores criam automaticamente uma chave de API para autorização válida por sete dias. No entanto, é possível usar qualquer tipo de autorização.

Para criar a fonte de dados do Lambda:

  1. Abra o console do AWS AppSync.
  2. Escolha Fontes de dados.
  3. Escolha Criar fonte de dados.
  4. Em Criar nova fonte de dados, insira o nome da fonte de dados que deseja definir.
    Para Tipo de fonte de dados, selecione Função do Amazon Lambda.
    Para Região, selecione a região da AWS que contém a função Lambda.
    Para ARN da função, selecione a função criada.
  5. Forneça uma função existente para permitir que o AWS AppSync gerencie a função do Lambda. Também é possível permitir que o assistente crie uma função.
  6. Escolha Create (Criar).

Como usar a AWS Command Line Interface (AWS CLI)

1.    Crie a API do GraphQL usando API_KEY como o tipo de autenticação padrão para teste:

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

Observação: substitua api name pelo nome da sua API.

2.    Crie uma chave de API:

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

Observação: substitua o apiId com o ID da API.

3.    Crie o perfil do IAM usado pela fonte de dados e, em seguida, anexe a política de confiança que permite que o AWS AppSync assuma a função:

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

Política de confiança JSON:

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

4.    Incorpore a política de permissões na função:

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

Política de permissões JSON:

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

Observação: substitua o lambda-ARN pelo seu Lambda ARN.

5.    Crie a fonte de dados e indique o ARN do perfil do IAM e da função Lambda:

$ 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

Observação: substitua LambdaDataSourceName pelo nome da fonte de dados, apiId pelo ID da API, IAM-role-ARN pelo ARN do perfil do IAM e Lambda-function-ARN pelo ARN da sua função Lambda.

Configurar o esquema da API do AWS AppSync

Como usar o Console de Gerenciamento da AWS

Configure a definição de esquema do GraphQL para acessar a resposta da função Lambda:

1.    Abra o console do AWS AppSync.

2.    No painel esquerdo, escolha Esquema.

3.    Copie e cole o esquema fornecido no editor.

O esquema de exemplo a seguir tem uma consulta de resposta que retorna dados com a estrutura de tipo de Produto:

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

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

schema {
    query: Query
}

4.    Escolha Salvar esquema.

Usar a AWS CLI

1.    Salve o esquema anterior do GraphQL como schema.graphql.

2.    Crie o esquema no AWS AppSync:

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

Observação: substitua o apiId pelo ID da sua API.

Anexe um resolvedor Lambda ou um resolvedor Lambda direto a um campo GraphQL

Como usar o Console de Gerenciamento da AWS

Anexe o resolvedor:

  1. Abra o console do AWS AppSync.
  2. Na página Esquema da sua API, em Resolvedores, role até a consulta de resposta. Ou filtre por consulta nos tipos de resolvedor.
  3. Ao lado do campo Resposta, escolha Anexar.
  4. Na página Criar novo resolvedor, para Nome da fonte de dados, selecione o nome da fonte de dados do Lambda. Observação: a integração direta do Lambda é usada para o cenário de exemplo, portanto, não é necessário configurar os modelos de mapeamento.
  5. Escolha Salvar resolvedores.

Usar a AWS CLI

Crie o resolvedor Lambda direto e especifique o nome da fonte de dados das etapas anteriores:

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

Observação: substitua apiId pelo ID da API e LambdaDataSourceName pelo nome da fonte de dados criada.

Teste o campo GraphQL

Para testar o campo GraphQL:

1.    Abra o console do AWS AppSync.

2.    No painel de navegação esquerdo, escolha Consultas.

3.    No editor de consultas, crie sua consulta GraphQL.

Exemplo de consulta GraphQL:

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

A consulta anterior obtém o ID do produto 1 do Application Load Balancer.

4.    Para executar a consulta de teste, escolha Reproduzir.

Exemplo de resposta da API:

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

Uso do terminal

Execute a consulta chamando o método POST. O exemplo a seguir usa o comando 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":{}}'

Observação: substitua api-key por sua chave de API.