Comment utiliser AWS AppSync pour accéder aux ressources privées de mon VPC ?

Dernière mise à jour : 2022-07-06

Je souhaite accéder aux ressources Amazon Virtual Private Cloud (Amazon VPC) à partir de mon API AWS AppSync GraphQL, mais je ne sais pas comment procéder.

Brève description

Pour accéder aux ressources Amazon VPC à partir d'une API GraphQL AWS AppSync, procédez comme suit :

  1. Créez une fonction AWS Lambda qui s'exécutera dans le même Amazon VPC que les ressources auxquelles vous souhaitez accéder.
  2. Créez une API AWS AppSync, puis attachez la fonction Lambda en tant que source de données.
  3. Configurez le schéma de l'API AWS AppSync.
  4. Attachez un résolveur Lambda ou un résolveur Lambda direct au champ GraphQL cible.
  5. Testez le champ GraphQL.

La configuration d'une fonction Lambda pour se connecter aux sous-réseaux privés d'un Amazon VPC vous permet d'accéder aux ressources privées de l'Amazon VPC. Les résultats des ressources privées en aval sont ensuite renvoyés à l'API GraphQL AWS AppSync et renvoyés au client. Les ressources privées incluent les bases de données, les conteneurs, les API privées, les domaines privés Amazon OpenSearch Service ou d'autres services privés derrière un équilibreur de charge d'application ou du Network Load Balancer.

AWS AppSync appelle l'API Lambda via les points de terminaison du service public Lambda. L'API invoquée est sécurisée par le processus de signature Signature Version 4. Cela permet à AWS AppSync d'assumer un rôle AWS Identity and Access Management (IAM) avec des autorisations pour appeler la fonction Lambda cible. Pour plus d'informations sur les fonctions Lambda configurées pour accéder à votre Amazon VPC, consultez Mise en réseau de VPC pour Lambda.

Remarque :

  • Seuls les points de terminaison publics sont pris en charge par AWS AppSync. Pour contourner ce problème, utilisez les résolveurs Lambda comme point d'entrée vers les ressources Amazon VPC.
  • L'ajout d'une fonction Lambda entre vos ressources privées Amazon VPC et l'API AWS AppSync introduit une nouvelle couche d'application avec une surcharge de latence mineure.
  • Si vous utilisez un Amazon VPC avec des fonctions Lambda, des frais supplémentaires vous seront facturés. Pour plus d'informations, consultez la section Quotas Lambda.

Solution

Remarque: si vous recevez des erreurs lors de l'exécution de commandes depuis l'interface de ligne de commande AWS (AWS CLI), assurez-vous d'utiliser la version la plus récente de l'interface de ligne de commande AWS CLI.

Créez une fonction AWS Lambda à exécuter dans le même Amazon VPC que les ressources auxquelles vous souhaitez accéder

Dans l'exemple de scénario suivant, une Application Load Balancer interne existant est appelée à partir d'une fonction Lambda Python. Une valeur id est obtenue à partir du paramètre arguments transmis dans l'objet d'événement que l'appel AWS AppSync envoie à 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

Remarque : Pour les résolveurs Lambda directs, la fonction reçoit une charge utile composée de l'ensemble de l'objet de contexte.

Exemple de réponse de la fonction Lambda :

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

Créez une API AWS AppSync et associez la fonction Lambda en tant que source de données

À l'aide de la Console de gestion AWS

Pour créer l'API GraphQL dans AWS AppSync :

  1. Ouvrez la console AWS AppSync.
  2. Sur le tableau de bord, choisissez Create API.
  3. Sur la page Mise en route, sous Personnaliser votre API ou importer depuis Amazon DynamoDB, sélectionnez Créer à partir de zéro.
  4. Sélectionnez Démarrer.
  5. Dans le champ Nom de l'API, entrez un nom pour votre API.
  6. Choisissez Create (Créer).

Remarque : les étapes précédentes créent automatiquement une clé API pour l'autorisation valide pendant sept jours. Cependant, vous pouvez utiliser n'importe quel type d'autorisation.

Pour créer la source de données Lambda :

  1. Ouvrez la console AWS AppSync.
  2. Choisissez Sources de données.
  3. Sélectionnez Créer une source de données.
  4. Sous Créer une nouvelle source de données, entrez le nom de la source de données que vous souhaitez définir.
    Pour Type de source de données, sélectionnez la fonction Amazon Lambda.
    Pour Region, sélectionnez la Région AWS qui contient la fonction Lambda.
    Pour Lambda function (Fonction Lambda), sélectionnez la fonction que vous avez créée.
  5. Fournissez un rôle existant pour permettre à AWS AppSync de gérer la fonction Lambda. Vous pouvez également laisser l'assistant en créer un pour vous.
  6. Choisissez Create (Créer).

Utilisation de l’interface de la ligne de commande AWS (AWS CLI)

1.    Créez l'API GraphQL en utilisant API_KEY comme type d'authentification par défaut pour les tests :

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

Remarque : remplacez le nom de l'API par le nom de votre API.

2.    Créez une clé API :

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

Remarque : remplacez APIid par l'ID de votre API.

3.    Créez le rôle IAM utilisé par la source de données, puis attachez la stratégie d'approbation qui permet à AWS AppSync d'assumer le rôle :

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

Politique d'approbation JSON :

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

4.    Intégrez la stratégie d'autorisation au rôle :

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

Stratégie d'autorisations JSON :

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

Remarque : remplacez Lambda-ARN par votre ARN Lambda.

5.    Créez la source de données et indiquez l'ARN du rôle IAM et de la fonction 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

Remarque : remplacez LambdaDataSourceName par le nom de votre source de données, APIid par l'ID de votre API, IAM-Role-ARN par l'ARN de votre rôle IAM et Lambda-Function-ARN par l'ARN de votre fonction Lambda.

Configuration du schéma de l'API AWS AppSync

À l'aide de la Console de gestion AWS

Configurez la définition du schéma GraphQL pour accéder à la réponse de la fonction Lambda :

1.    Ouvrez la console AWS AppSync.

2.    Dans le panneau de gauche, choisissez Schema.

3.    Copiez et collez le schéma fourni dans l'éditeur.

L'exemple de schéma suivant comporte une requête de réponse qui renvoie des données avec la structure Type de produit :

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

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

schema {
    query: Query
}

4.    Choisissez Save Schema (enregistrer le schéma).

Utilisation de l'interface de ligne de commande AWS (AWS CLI)

1.    Enregistrez le schéma GraphQL précédent sous schema.graphql.

2.    Créez le schéma dans AWS AppSync :

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

Remarque : remplacez APIid par l'ID de votre API.

Attachez un résolveur Lambda ou un résolveur Lambda direct à un champ GraphQL

À l'aide de la Console de gestion AWS

Joignez le résolveur :

  1. Ouvrez la console AWS AppSync.
  2. Sur la page Schema (Schéma) de votre API, sous Resolvers (Résolveurs), faites défiler jusqu'à Query (Requête). Vous pouvez également filtrer par requête dans les types de résolveur.
  3. En regard du champ Réponse, choisissez Attach.
  4. Sur la page Create new Resolver, pour Data source name, sélectionnez le nom de la source de données Lambda. Remarque : l'intégration directe Lambda est utilisée pour l'exemple de scénario, il n'est donc pas nécessaire de configurer les modèles de mappage.
  5. Choisissez Save Resolvers (Enregistrer les résolveurs).

Utilisation de l'interface de ligne de commande AWS (AWS CLI)

Créez le résolveur Lambda direct et spécifiez le nom de la source de données à partir des étapes précédentes :

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

Remarque : remplacez APIid par l'ID de votre API et LambdaDataSourceName par le nom de la source de données créée.

Tester le champ GraphQL

Pour tester le champ GraphQL :

1.    Ouvrez la console AWS AppSync.

2.    Dans le panneau de navigation de gauche, choisissez Queries (Requêtes).

3.    Dans l'éditeur de requêtes, concevez votre requête GraphQL.

Exemple de requête GraphQL :

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

La requête précédente obtient l'ID de produit 1 de l'Application Load Balancer.

4.    Pour exécuter la requête de test, choisissez Play.

Exemple de réponse de l'API :

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

Utiliser le terminal

Exécutez la requête en appelant la méthode POST. L'exemple suivant utilise la commande 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":{}}'

Remarque : remplacez api-key par votre clé API.