X

📡 AWS CDK 101 ⛄ – ​​Utilisation de la construction de la passerelle API, limitation, quota, plans d’utilisation, clĂ©s API


🔰 DĂ©butants qui dĂ©couvrent AWS CDK, veuillez consulter mes articles prĂ©cĂ©dents un par un dans cette sĂ©rie.

Si vous avez ratĂ© l’article prĂ©cĂ©dent, retrouvez-le avec les liens ci-dessous.

🔁 Message prĂ©cĂ©dent original sur 🔗 Dev Post

https://devpost.hashnode.dev/aws-cdk-101-lambda-and-cdk-watch

🔁 RepubliĂ© le post prĂ©cĂ©dent Ă  🔗 dev Ă  @aravindvcyber

https://dev.to/aravindvcyber/aws-cdk-101-lambda-cdk-watch-le9

Dans cet article, introduisons une passerelle API devant notre fonction lambda de base que nous avons créée dans notre dernier article ci-dessus répertorié ci-dessus.

Pourquoi API Gateway dans notre solution

Étant donnĂ© que notre lambda n’est accessible que dans notre environnement aws, nous avons besoin de cette configuration de passerelle API qui aidera Ă  exposer un point de terminaison HTTP public que n’importe qui sur Internet peut atteindre avec un client HTTP.

En outre, une passerelle API peut bloquer les demandes inappropriĂ©es sans appeler les fonctions Lambda backend, lorsque les vĂ©rifications d’autorisation Ă©chouent. API Gateway peut ainsi rĂ©duire les coĂ»ts d’appel Lambda Ă©levĂ©s et peut Ă©galement dĂ©charger la validation des demandes de votre fonction Lambda, en fonction des besoins.

Commençons par éditer le lib/common-event-stact.ts déposer. Ici, importons les modules de aws-cdk-lib/aws-apigateway comme agigw.

 // this defines an new API Gateway REST API resource backed by our "eventEntry" function.
    const eventGateway = new apigw.LambdaRestApi(this, 'EventEndpoint', {
      handler: eventEntry
    });

Quand tu cours cdk diffvous pouvez vous attendre à un journal similaire sur les nouvelles ressources à créer ainsi que sur les modifications de stratégie IAM impliquées.

IAM Statement Changes

    Resource                                             Effect  Action                 Principal                                            Condition                                           

 +  ${EventEndpoint/CloudWatchRole.Arn}                  Allow   sts:AssumeRole         Service:apigateway.amazonaws.com                                                                         

 +  ${EventEntryHandler.Arn}                             Allow   lambda:InvokeFunction  Service:apigateway.amazonaws.com                     "ArnLike": {                                        
                                                                                                                                               "AWS:SourceArn": "arn:${AWS::Partition}:execute-a 
                                                                                                                                             pi:${AWS::Region}:${AWS::AccountId}:${EventEndpoint 
                                                                                                                                             82CBF40A}/${EventEndpoint/DeploymentStage.prod}/*/* 
                                                                                                                                             "                                                   
                                                                                                                                             }                                                   
 +  ${EventEntryHandler.Arn}                             Allow   lambda:InvokeFunction  Service:apigateway.amazonaws.com                     "ArnLike": {                                        
                                                                                                                                               "AWS:SourceArn": "arn:${AWS::Partition}:execute-a 
                                                                                                                                             pi:${AWS::Region}:${AWS::AccountId}:${EventEndpoint 
                                                                                                                                             82CBF40A}/test-invoke-stage/*/*"                    
                                                                                                                                             }                                                   
 +  ${EventEntryHandler.Arn}                             Allow   lambda:InvokeFunction  Service:apigateway.amazonaws.com                     "ArnLike": {                                        
                                                                                                                                               "AWS:SourceArn": "arn:${AWS::Partition}:execute-a 
                                                                                                                                             pi:${AWS::Region}:${AWS::AccountId}:${EventEndpoint 
                                                                                                                                             82CBF40A}/${EventEndpoint/DeploymentStage.prod}/*/" 
                                                                                                                                             }                                                   
 +  ${EventEntryHandler.Arn}                             Allow   lambda:InvokeFunction  Service:apigateway.amazonaws.com                     "ArnLike": {                                        
                                                                                                                                               "AWS:SourceArn": "arn:${AWS::Partition}:execute-a 
                                                                                                                                             pi:${AWS::Region}:${AWS::AccountId}:${EventEndpoint 
                                                                                                                                             82CBF40A}/test-invoke-stage/*/"                     
                                                                                                                                             }                                                   

IAM Policy Changes

    Resource                         Managed Policy ARN                                                                      

 +  ${EventEndpoint/CloudWatchRole}  arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs 

(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Resources
[+] AWS::ApiGateway::RestApi EventEndpoint EventEndpoint82CBF40A 
[+] AWS::IAM::Role EventEndpoint/CloudWatchRole EventEndpointCloudWatchRole4E252113 
[+] AWS::ApiGateway::Account EventEndpoint/Account EventEndpointAccount1A8CF478 
[+] AWS::ApiGateway::Deployment EventEndpoint/Deployment EventEndpointDeployment9E6BA6B96f1395a2ccbaf49542e68813f77a19e7 
[+] AWS::ApiGateway::Stage EventEndpoint/DeploymentStage.prod EventEndpointDeploymentStageprod2ED092D9 
[+] AWS::ApiGateway::Resource EventEndpoint/Default/{proxy+} EventEndpointproxyCBF9AFD2 
[+] AWS::Lambda::Permission EventEndpoint/Default/{proxy+}/ANY/ApiPermission.CommonEventStackEventEndpointB06FCC50.ANY..{proxy+} EventEndpointproxyANYApiPermissionCommonEventStackEventEndpointB06FCC50ANYproxy3F9D95E2 
[+] AWS::Lambda::Permission EventEndpoint/Default/{proxy+}/ANY/ApiPermission.Test.CommonEventStackEventEndpointB06FCC50.ANY..{proxy+} EventEndpointproxyANYApiPermissionTestCommonEventStackEventEndpointB06FCC50ANYproxy75C60637 
[+] AWS::ApiGateway::Method EventEndpoint/Default/{proxy+}/ANY EventEndpointproxyANY74421EDC 
[+] AWS::Lambda::Permission EventEndpoint/Default/ANY/ApiPermission.CommonEventStackEventEndpointB06FCC50.ANY.. EventEndpointANYApiPermissionCommonEventStackEventEndpointB06FCC50ANY7F8C8232 
[+] AWS::Lambda::Permission EventEndpoint/Default/ANY/ApiPermission.Test.CommonEventStackEventEndpointB06FCC50.ANY.. EventEndpointANYApiPermissionTestCommonEventStackEventEndpointB06FCC50ANYC6DC815A 
[+] AWS::ApiGateway::Method EventEndpoint/Default/ANY EventEndpointANY8620E9D3

RĂ©sumant la sortie ci-dessus đŸ’„

Pour résumer ce qui précÚde, comprenons ce qui se passe dans le backend comme suit et sera publié.

  • Une nouvelle stratĂ©gie IAM est crĂ©Ă©e CloudWatchRole et supposĂ© envoyer les journaux Ă  cloudwatch depuis apigateway.
  • Une Ă©tape de dĂ©ploiement prod est configurĂ©, nous pouvons avoir plusieurs Ă©tapes pour tester les fonctionnalitĂ©s prĂ©maturĂ©ment avec cela, sans affecter l’étape de production.
  • Les autorisations de ressources sont configurĂ©es avec les privilĂšges nĂ©cessaires pour tout Resource path, par dĂ©faut un chemin de ressource gourmand {proxy+} pour le point de terminaison normal et le point de terminaison de test pour cette API de repos.
  • Les autorisations de ressources sont configurĂ©es avec les privilĂšges nĂ©cessaires pour tout method pour le point de terminaison normal et le point de terminaison de la variante de test pour cette API de repos.

La comprĂ©hension approfondie des concepts ci-dessus nous aidera lorsque nous restreindrons davantage la passerelle API Ă  l’avenir pour des points de terminaison similaires basĂ©s sur le repos.

Maintenant, exécutons ce déploiement et vérifions les résultats.

Avant cela, permettez-moi de faire un autre changement dans notre lambda pour afficher le message approprié.

exports.receiver = async function(event:any) {
  console.log("request:", JSON.stringify(event, undefined, 2));
  return {
    statusCode: 200,
    headers: { "Content-Type": "text/plain" },
    body: `Message Received in lambda: ${JSON.stringify(event.body)}\n`
  };
};

cdk deploy CommonEventStack



   CommonEventStack

  Deployment time: 57.21s

Outputs:
CommonEventStack.EventEndpointA893C53E = https://lwo***********uvhg.execute-api.ap-south-1.amazonaws.com/prod/
Stack ARN:
arn:aws:cloudformation:ap-south-1:575066707855:stack/CommonEventStack/93688c10-a10a-11ec-b942-0ad3136ae540

  Total time: 68.43s

🏃 Tests de boucles

Lorsque nous effectuons une boucle pour vérifier ce point final de repos, voyons ce que nous obtenons.

curl https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/

Message Received: null

Ici, nous rĂ©ussissons Ă  envoyer un message au lambda et nous avons Ă©galement obtenu une sortie. Bien que nous ayons null parce que nous n’avons jamais envoyĂ© de corps dans notre initiale GET demande.

Envoyons maintenant un message via le corps de la demande du client dans une demande de publication.

curl -H "Content-Type: application/json" -d '{ "message": "client message"}' -X POST https://********.execute-api.ap-south-1.amazonaws.com/prod/

Message Received in lambda: "{ \"message\": \"client message\"}"

Nous avons configuré avec succÚs la passerelle agi, alors vérifions-la dans la console et testons-la également dans la console aws.

Passerelle API dans la console AWS

Inspecter le chemin du point de terminaison et les méthodes autorisées

Tester la requĂȘte POST d’invocation avec message

Affiner la passerelle Api créée ci-dessus

Maintenant, affinons la passerelle api crĂ©Ă©e pour qu’elle soit disponible uniquement pour la mĂ©thode POST et un chemin de ressource spĂ©cifique uniquement.

Documentation de rĂ©fĂ©rence de l’API CDK đŸŒ

Avant de faire cela, nous devons utiliser la documentation de référence cdk api. Désormais, nous pouvons explorer cette documentation de référence pour choisir les paramÚtres et options nécessaires pour chaque construction de ressource de pile cdk.

Ici, si vous vous souvenez, nous avons importé aws-cdk-lib/aws-apigatewaynous devons apprendre à utiliser la bibliothÚque de construction à https://docs.aws.amazon.com/cdk/api/v2

Plus précisément, nous devons naviguer vers https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway-readme.html. Ici, nous pourrions trouver la documentation nécessaire pour la construction apigateway et comment utiliser ses propriétés et ses méthodes, avec des exemples appropriés.

SpĂ©cifiez le bon chemin de ressource et la bonne mĂ©thode 🔩

Supprimons d’abord cette dĂ©finition de chemin de ressource de proxy gourmand.

const eventGateway = new apigw.LambdaRestApi(this, 'EventEndpoint', {
      handler: eventEntry,
      proxy: false
    });

Ici, l’attribut proxy supprime la dĂ©finition de chemin de ressource gourmande par dĂ©faut.

DĂ©clarons maintenant un chemin de ressource disponible comme dans l’exemple ci-dessous.

 const eventHandler: apigw.LambdaIntegration = new apigw.LambdaIntegration(eventEntry);
    const event = eventGateway.root.addResource('event');

    const eventMethod: apigw.Method = event.addMethod('POST', eventHandler, {  
       apiKeyRequired: false
    });

Maintenant, nous n’exposons et n’autorisons que le chemin et la mĂ©thode de ressource spĂ©cifiques avec succĂšs.

Lorsque nous accĂ©dons au chemin de ressource de base avec des mĂ©thodes interdites 🔩

Alors que nous pouvons accéder à notre API spécifique avec succÚs, notez la différence dans le full path avec la méthode autorisée.

Plan d’utilisation et clĂ©s API 🔔

Un plan d’utilisation spĂ©cifie qui peut accĂ©der Ă  une ou plusieurs Ă©tapes et mĂ©thodes d’API dĂ©ployĂ©es, et la frĂ©quence Ă  laquelle elles sont accessibles.

Le plan utilise des clĂ©s API pour identifier les clients API et mesurer l’accĂšs aux Ă©tapes API associĂ©es pour chaque clĂ© en consĂ©quence. Les plans d’utilisation permettent Ă©galement de configurer des limites de limitation et des limites de quota qui sont appliquĂ©es sur des clĂ©s d’API client individuelles.

L’exemple suivant montre comment crĂ©er et associer un plan d’utilisation et une clĂ© API :

const eventMethod: apigw.Method = event.addMethod('POST', eventHandler, {  
       apiKeyRequired: true,
    });

Pour utiliser une clĂ© API, il est nĂ©cessaire de configurer un plan d’utilisation, quelque chose de similaire Ă  l’exemple ci-dessous, puis nous pouvons l’associer Ă  la clĂ© que nous venons de crĂ©er.


const plan = eventGateway.addUsagePlan('UsagePlan', {
        name: 'Workshop',
        description: 'For Workshop',
        throttle: {
          burstLimit: 5,
          rateLimit: 10,
        },
        quota: {
          limit: 100,
          period: apigw.Period.DAY
        }
    });

    const normalUserKey = eventGateway.addApiKey('ApiKey',{
        apiKeyName: 'av-api-key',
        value: 'av-api-key-value-********',
    });
    plan.addApiKey(normalUserKey);

Niveau phase de dĂ©ploiement affinage du plan d’utilisation đŸŒ»

Le rĂ©glage fin du plan d’utilisation ci-dessus Ă  diffĂ©rentes Ă©tapes de dĂ©ploiement pour la mĂ©thode spĂ©cifique en plus et l’inclusion de limites d’accĂ©lĂ©ration au niveau de la mĂ©thode permettent un meilleur contrĂŽle des limites de consommation d’API et une plus grande utilisation des ressources avec plusieurs clients sur la base d’un contrat.

 plan.addApiStage({
      stage: eventGateway.deploymentStage,
      throttle: [
        {
          method: eventMethod,
          throttle: {
            rateLimit: 3,
            burstLimit: 2
          }
        }
      ]
    });

Limitation de l’api avec dĂ©bit et limite de rafale 🐇

Vous pouvez contrĂŽler efficacement le taux du nombre d’appels par seconde en limitant le dĂ©bit avant que la passerelle ne refuse toute demande supplĂ©mentaire Ă  l’entrĂ©e elle-mĂȘme.

  • La limite de rafale dĂ©finit le nombre de requĂȘtes que votre API peut gĂ©rer simultanĂ©ment.
  • La limite de dĂ©bit dĂ©finit le nombre de requĂȘtes autorisĂ©es par seconde.
 throttle: {
            rateLimit: 3,
            burstLimit: 2
          }

Limite de quota 🐡

La limite de quota permet de dĂ©finir le nombre cumulĂ© de requĂȘtes client reçues par la passerelle API avant que la limite de la passerelle ne soit dĂ©passĂ©e.

GĂ©nĂ©ralement, aws fournit un certain quota fixe pour chaque service par rĂ©gion, cela peut ĂȘtre gĂ©rĂ© efficacement en rĂ©servant une partie Ă  chaque plan d’utilisation comme vous le souhaitez. Cela peut Ă©galement vĂ©rifier pour limiter la consommation d’API utilisateur externe, en fonction de leur niveau de service.

 quota: {
      limit: 5,
      period: apigw.Period.DAY
      }

Une fois le quota allouĂ© Ă  l’utilisateur de la clĂ© API dĂ©passĂ©, les rĂ©ponses d’erreur sont envoyĂ©es.

Évaluer la clĂ© API limitĂ©e 🐠

Dans certains scĂ©narios oĂč vous devez crĂ©er une seule clĂ© API et configurer la limitation de dĂ©bit pour celle-ci, vous pouvez utiliser RateLimitedApiKey. Cette construction vous permet de spĂ©cifier des propriĂ©tĂ©s de limitation de dĂ©bit qui doivent ĂȘtre appliquĂ©es uniquement Ă  la clĂ© API en cours de crĂ©ation. La clĂ© API crĂ©Ă©e a les limites de taux spĂ©cifiĂ©es, telles que les quotas et les limitations, appliquĂ©es, mĂȘme sans aucune association Ă  un plan d’utilisation.

const rateLimitedKey = new apigw.RateLimitedApiKey(this, 'rate-limited-api-key', {
       apiKeyName: 'av-rate-limited-api-key',
        value: 'av-api-key-value-dreatenbwebrwiukjwnrn',
    customerId: 'external-client',
    resources: [eventGateway],
    quota: {
      limit: 5,
      period: apigw.Period.DAY
      },
      throttle: {
        rateLimit: 2,
        burstLimit: 1
      }
    });
    plan.addApiKey(rateLimitedKey);

Nous pouvons maintenant vĂ©rifier la mĂȘme chose dans la console API, oĂč nous pouvons trouver qu’un nouveau plan est crĂ©Ă© pour la clĂ© API nouvellement crĂ©Ă©e. Pour un contrĂŽle plus prĂ©cis pour les utilisateurs individuels ne faisant pas partie d’autres plans d’utilisation.

Importation des clĂ©s et plans d’utilisation existants 🐝

En plus de cela, nous pouvons Ă©galement importer les clĂ©s et le plan d’utilisation existants dans nos ressources de pile en suivant les exemples ci-dessous.

les plans d’utilisation peuvent ĂȘtre importĂ©s dans une application CDK Ă  l’aide de son identifiant.

const importedUsagePlan = apigateway.UsagePlan.fromUsagePlanId(this, 'imported-usage-plan', '<usage-plan-key-id>');

Les clĂ©s API peuvent Ă©galement ĂȘtre importĂ©es dans une application CDK Ă  l’aide de son identifiant.

const importedKey = apigateway.ApiKey.fromApiKeyId(this, 'imported-key', '<api-key-id>');

Nous ajouterons plus de connexions à cette passerelle api et lambda et la rendrons plus utilisable dans les prochains articles, restez abonné.

Nous avons notre prochain article en sans serveur, consultez

https://devpost.hashnode.dev/aws-cdk-101-building-constructs-and-simple-counter-store-in-dynamodb

🎉 Merci pour votre soutien ! 🙏

Ce serait vraiment génial si vous aimez Buy Me a Coffee, pour aider à stimuler mes efforts.

🔁 Message original sur 🔗 Dev Post

🔁 RepubliĂ© Ă  🔗 dev Ă  @aravindvcyber