Exécution et appel de la fonction Lambda

Ce chapitre explique en détail le processus d'exécution et d'appel de la fonction Lambda et les étapes qui y sont impliquées.

Modèle d'exécution AWS Lambda

L'exécution d'AWS dépend des détails de configuration ajoutés pour AWS Lambda Function. Lorsque la fonction est créée, il y a unmemory et time allotted, qui est utilisé pour l'exécution de la fonction AWS Lambda.

À l'aide des détails de configuration, AWS Lambda crée un contexte d'exécution. Le contexte d'exécution est un environnement d'exécution temporaire qui est préparé avec toutes les dépendances externes telles que la connexion à la base de données, les points de terminaison http, les bibliothèques tierces, etc., le cas échéant.

Lorsque la fonction AWS Lambda est appelée pour la toute première fois ou si la fonction lambda est mise à jour, il y a peu de latence ajoutée en raison de la configuration du contexte d'exécution. Cependant, les appels suivants sont plus rapides par rapport au premier. AWS Lambda tente à nouveau de réutiliser le contexte d'exécution si la fonction Lambda est appelée avec moins de temps.

La réutilisation du contexte d'exécution a les implications suivantes -

  • Si une connexion à la base de données est établie pour l'exécution de Lambda, la connexion est maintenue pour une réutilisation. Le code Lambda doit donc être tel que la connexion doit d'abord être vérifiée - si elle existe et réutilisée; sinon, nous devrons établir une nouvelle connexion.

  • Le contexte d'exécution conserve un espace disque de 500 Mo dans /tmpannuaire. Les données requises sont mises en cache dans ce répertoire. Vous pouvez avoir une vérification supplémentaire dans le code pour voir si les données existent.

  • Si les rappels ou certains processus d'arrière-plan ne sont pas terminés lorsque la fonction Lambda a été appelée, l'exécution démarrera lorsque la fonction lambda sera à nouveau appelée. Dans le cas où vous n'avez pas besoin d'une telle chose, assurez-vous que vos processus sont tous terminés correctement, lorsque l'exécution de la fonction est terminée.

Vous devez utiliser le contexte d'exécution et les données stockées dans le répertoire tmp. Vous devrez ajouter les vérifications nécessaires dans le code pour voir si les données requises existent avant d'en créer de nouvelles. Cela économisera du temps lors de l'exécution et la rendra plus rapide.

Appel de la fonction AWS Lambda

Nous pouvons appeler AWS manuellement en utilisant aws cli. Nous avons déjà vu comment créer et déployer AWS Lambda en utilisantcli. Ici, nous allons d'abord créer une fonction en utilisantaws cli et invoquez le même.

Création d'une fonction AWS Lambda à l'aide de l'AWS CLI

Vous pouvez utiliser les commandes suivantes pour créer une fonction AWS Lambda à l'aide de aws cli -

Commands

create-function 
--function-name <value>
--runtime <value>
--role <value>
--handler <value>
[--code <value>] 
[--description <value>] 
[--timeout <value>] 
[--memory-size <value>] 
[--environment <value>] 
[--kms-key-arn <value>] 
[--tags <value>] 
[--zip-file <value>] 
[--cli-input-json <value>]

Command with values

aws lambda create-function 
--function-name "lambdainvoke" 
--runtime "nodejs8.10" 
--role "arn:aws:iam::625297745038:role/lambdaapipolicy" 
--handler "index.handler" 
--timeout 5 
--memory-size 256 
--zip-file "fileb://C:\nodeproject\index.zip"

La sortie est comme indiqué ci-dessous -

La fonction créée dans la console AWS est comme indiqué ci-dessous -

Maintenant, vous pouvez appeler la fonction en utilisant la commande:invoke

--function-name <value>
[--invocation-type <value>]
[--log-type <value>]
[--client-context <value>]
[--payload <value>]
[--qualifier <value>]
outfile <value>

Options

--function-name − Spécifiez le nom de la fonction que vous souhaitez appeler.

--invocation-type(string) − par défaut, le type d'invocation est requestresponse. Les valeurs disponibles pour être utilisées avec le type d'invocation sontRequestResponse, Event et DryRun.

  • Le type d'appel d'événement doit être utilisé pour la réponse asynchrone.

  • DryRun doit être utilisé lorsque vous souhaitez vérifier la fonction Lambda sans avoir besoin de l'exécuter.

--log-type − Ce sera Tailsi le type d'appel est RequestResponse. Il donne les dernières données de journal encodées en base64 de 4 Ko. Les valeurs possibles sontTail et None.

--client-context −Vous pouvez transmettre des détails spécifiques au client à la fonction Lambda. Le clientcontext doit être au format json et encodé en base64. La taille maximale du fichier est de 3583 octets.

--payload − json entrée au format de votre fonction lambda.

--qualifier −Vous pouvez spécifier la version de la fonction Lambda ou le nom d'alias. Si vous transmettez la version de la fonction, l'API utilisera la fonction qualifiée arn pour appeler la fonction Lambda. Si vous spécifiez un nom d'alias, l'API utilise l'alias ARN pour appeler la fonction Lambda.

outfile − Il s'agit du nom de fichier dans lequel le contenu sera enregistré.

Command with values

aws lambda invoke --function-name "lambdainvoke" --log-type 
Tail C:\nodeproject\outputfile.txt

Vous pouvez utiliser l'option de charge utile pour envoyer un événement factice à la fonction lambda au format json, comme indiqué ci-dessous.

Le code AWS Lambda associé est le suivant:

exports.handler = async (event, callback) => {
   console.log("Hello => "+ event.name);
   console.log("Address =>"+ event.addr);
   callback(null, 'Hello '+event.name +" and address is "+ event.addr);
};

Observez que dans le code, nous avons la console event.name et event.addr. Maintenant, utilisons l'option payload dans aws cli pour envoyer l'événement avec le nom et l'adresse comme suit -

aws lambda invoke --function-name "lambdainvoke" --log-type 
Tail --payload file://C:\clioutput\input.txt C:\clioutput\outputfile.txt

Thenpayload prend l'entrée comme un chemin de fichier qui a une entrée json comme indiqué -

{"name":"Roy Singh", "addr":"Mumbai"}

La sortie correspondante est comme indiqué ci-dessous -

La sortie est stockée dans le fichier C:\clioutput\outputfile.txt comme suit -

"Hello Roy Singh and address is Mumbai"

Exemples d'événements

Vous pouvez tester la fonction AWS Lambda en transmettant un exemple d'événement. Cette section donne quelques exemples d'événements pour les services AWS. Vous pouvez utiliser leinvokecommande pour tester la sortie lorsqu'elle est déclenchée avec l'un des services. Observez les codes donnés pour les exemples d'événements correspondants ci-dessous -

Exemple d'événement Put Amazon S3

{
  "Records": [{
      "eventVersion": "2.0",
      "eventTime": "1970-01-01T00:00:00.000Z",
      "requestParameters": {
         "SourceIPAddress": "127.0.0.1"
      },
      "s3": {
         "configurationId": "testConfigRule",
         "object": {
            "eTag": "0123456789abcdef0123456789abcdef",
            "sequencer": "0A1B2C3D4E5F678901",
            "key": "HappyFace.jpg",
            "size": 1024
         },
         "bucket": { 
            "arn": bucketarn,
            "name": "Sourcebucket",
            "ownerIdentity": {
               "principalId": "EXAMPLE"
            }
         },
         "s3SchemaVersion": "1.0"
      },
      "responseElements": {
         "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH",
         "x-amz-request-id": "EXAMPLE123456789"
      },
      "awsRegion": "us-east-1",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
         "principalId": "EXAMPLE"
      },
      "eventSource": "aws:s3"
   }]
}

Pour obtenir le details of the file from the s3 put event, vous pouvez utiliser la commande suivante -

event.Records[0].s3.object.key   //will display the name of the file

À get the bucket name, vous pouvez utiliser la commande suivante -

event.Records[0].s3.bucket.name  //will give the name of the bucket.

À see the EventName, vous pouvez utiliser la commande suivante -

event.Records[0].eventName    // will display the eventname

Exemple d'événement de suppression d'Amazon S3

{
   "Records": [{
      "eventVersion": "2.0",
      "eventTime": "1970-01-01T00:00:00.000Z",
      "requestParameters": {
         "SourceIPAddress": "127.0.0.1"
      },
      "s3": {
         "configurationId": "testConfigRule",
         "object": {
            "sequencer": "0A1B2C3D4E5F678901",
            "key": "HappyFace.jpg"
         },
         "bucket": {
            "arn": bucketarn,
            "name": "Sourcebucket",
            "ownerIdentity": {
               "principalId": "EXAMPLE"
            }
         },
        "s3SchemaVersion": "1.0"
      },
      "responseElements": {
         "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH",
         "x-amz-request-id": "EXAMPLE123456789"
      },
      "awsRegion": "us-east-1",
      "eventName": "ObjectRemoved:Delete",
      "userIdentity": {
         "principalId": "EXAMPLE"
      },
      "eventSource": "aws:s3"
   }]
}

Amazon DynamoDB

Amazon DynamoDB peut être un événement sur AWS Lambda lorsque des modifications sont apportées à la table DynamoDB. Nous pouvons effectuer des opérations comme ajouter une entrée, mettre à jour et supprimer des enregistrements de la table DynamodDB.

Un exemple d'événement pour l'événement d'ajout, d'insertion et de suppression DynamoDB est affiché ici -

{
  "Records": [{
      "eventID": "1",
      "eventVersion": "1.0",
      "dynamodb": {
         "Keys": {
            "Id": {
               "N": "101"
            }
         },
         "NewImage": {
            "Message": {
               "S": "New item!"
            },
            "Id": {
               "N": "101"
            }
         },
         "StreamViewType": "NEW_AND_OLD_IMAGES",
         "SequenceNumber": "111",
         "SizeBytes": 26
      },
      "awsRegion": "us-west-2",
      "eventName": "INSERT",
      "eventSourceARN": eventSourcearn,
      "eventSource": "aws:dynamodb"
   },
   {
      "eventID": "2",
      "eventVersion": "1.0",
      "dynamodb": {
         "OldImage": {
            "Message": {
               "S": "New item!"
            },
            "Id": {
               "N": "101"
            }
         },
        "SequenceNumber": "222",
        "Keys": {
            "Id": {
               "N": "101"
            }
         },
        "SizeBytes": 59,
        "NewImage": {
            "Message": {
               "S": "This item has changed"
            },
            "Id": {
				   "N": "101"
            }
         },
         "StreamViewType": "NEW_AND_OLD_IMAGES"
      },
      "awsRegion": "us-west-2",
      "eventName": "MODIFY",
      "eventSourceARN": Sourcearn,
      "eventSource": "aws:dynamodb"
   },
   {      
   "eventID": "3",
      "eventVersion": "1.0",
      "dynamodb": {
         "Keys": {
            "Id": {
               "N": "101"
            }
         },
         "SizeBytes": 38,
         "SequenceNumber": "333",
         "OldImage": {
            "Message": {
               "S": "This item has changed"
            },
            "Id": {
               "N": "101"
            }
         },
         "StreamViewType": "NEW_AND_OLD_IMAGES"
      },      "awsRegion": "us-west-2",
      "eventName": "REMOVE",
      "eventSourceARN": Sourcearn,
      "eventSource": "aws:dynamodb"    
   }]
}

Service de notification simple d'Amazon

AWS Lambda peut être utile pour traiter la notification créée dans Simple Notification Service (SNS). Chaque fois qu'un message est publié dans SNS, la fonction Lambda peut être déclenchée avec un événement SNS, qui contient les détails des messages. Ces messages peuvent être traités dans la fonction Lambda et peuvent être envoyés à d'autres services selon les besoins.

Une fois le message saisi, SNS déclenchera la fonction Lambda. Si une erreur tente d'appeler la fonction Lambda, SNS réessaiera d'appeler la fonction lambda jusqu'à trois fois.

Exemple d'événement Amazon SNS

Un exemple d'événement contenant tous les détails disponibles dans la fonction AWS Lambda pour exécuter le processus supplémentaire est illustré ci-dessous:

{
  "Records": [{
      "EventVersion": "1.0",
      "EventSubscriptionArn": eventsubscriptionarn,
      "EventSource": "aws:sns",
      "Sns": {
         "SignatureVersion": "1",
         "Timestamp": "1970-01-01T00:00:00.000Z",
         "Signature": "EXAMPLE",
         "SigningCertUrl": "EXAMPLE",
         "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
         "Message": "Hello from SNS!",
         "MessageAttributes": {
            "Test": {
               "Type": "String",
               "Value": "TestString"
            },
            "TestBinary": {
               "Type": "Binary",
               "Value": "TestBinary"
            }
         },
         "Type": "Notification",
         "UnsubscribeUrl": "EXAMPLE",
         "TopicArn": topicarn,
         "Subject": "TestInvoke"
      }
   }]
}

Amazon Simple Mail Service

Amazon Simple Mail Service peut être utilisé pour envoyer des messages et également pour recevoir des messages. La fonction AWS Lambda peut être appelée sur Simple Mail Service lorsque le message est reçu.

Exemple d'événement de réception d'e-mails Amazon SES

Les détails de l'événement SES lorsqu'il est utilisé dans AWS Lambda sont indiqués ci-dessous:

{
  "Records": [{
      "eventVersion": "1.0",
      "ses": {
         "mail": {
            "commonHeaders": {
               "from": [
                  "Jane Doe <[email protected]>"
               ],
            "to": [
               "[email protected]"
            ],
            "returnPath": "[email protected]",
            "messageId": "<0123456789Source.com>",
            "date": "Wed, 7 Oct 2015 12:34:56 -0700",
            "subject": "Test Subject"
         },
         "example": "[email protected]",
         "timestamp": "1970-01-01T00:00:00.000Z",
         "destination": [
            "[email protected]"
         ],
         "headers": [{
            "name": "Return-Path",
            "value": "<[email protected]>"
         },
         {
            "name": "Received",
            "value": "from mailer.example.com (mailer.example.com [203.0.113.1]) by inbound-smtp.us-west-2.amazonaws.com with SMTP id o3vrnil0e2ic for [email protected]; Wed, 07 Oct 2015 12:34:56 +0000 (UTC)"
         },
         {
            "name": "DKIM-Signature",
            "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=example; h=mime-version:from:date:message-id:subject:to:content-type; bh=jX3F0bCAI7sIbkHyy3mLYO28ieDQz2R0P8HwQkklFj4=; b=sQwJ+LMe9RjkesGu+vqU56asvMhrLRRYrWCbV"
         },
         {
            "name": "MIME-Version",
            "value": "1.0"
         },
         {
            "name": "From",
            "value": "Jane Doe <[email protected]>"
         },
         {
            "name": "Date",
            "value": "Wed, 7 Oct 2015 12:34:56 -0700"
         },
         {
            "name": "Message-ID",
            "value": "<0123456789example.com>"
         },
         {
            "name": "Subject",
            "value": "Test Subject"
         },
         {
            "name": "To",
            "value": "[email protected]"
         },
         {
            "name": "Content-Type",
            "value": "text/plain; charset=UTF-8"
         }],
         "headersTruncated": false,
         "messageId": "o3vrnil0e2ic28tr"
      },
      "receipt": {
         "recipients": [
            "[email protected]"
         ],
         "timestamp": "1970-01-01T00:00:00.000Z",
         "spamVerdict": {
            "status": "PASS"
         },
         "dkimVerdict": {
            "status": "PASS"
         },
         "processingTimeMillis": 574,
         "action": {
            "type": "Lambda",
            "invocationType": "Event",
            "functionArn": "arn:aws:lambda:us-west-2:012345678912:function:example"
         },
         "spfVerdict": {
            "status": "PASS"
         },
         "virusVerdict": {
            "status": "PASS"
         }
      }
   },
   "eventexample": "aws:ses"
   }]
}

Journaux Amazon Cloudwatch

AWS Lambda peut être déclenché à partir d'Amazon CloudWatch Logs à l'aide du CloudWatch Logs Subscriptions. Les abonnements CloudWatch Logs contiennent des données en temps réel sur les journaux qui peuvent être traitées et analysées dans AWS Lambda ou peuvent être utilisées pour charger sur d'autres systèmes.

Exemple d'événement Amazon CloudWatch Logs

{
   "awslogs": {
      "data": "H4sIAAAAAAAAAHWPwQqCQBCGX0Xm7EFtK+smZBEUgXoLCdMhFtKV3akI8d0bLYmibvPPN3wz00CJxmQnTO41whwW
      QRIctmEcB6sQbFC3CjW3XW8kxpOpP+OC22d1Wml1qZkQGtoMsScxaczKN3plG8zlaHIta5KqWsozoTYw3/djzwhpL
      wivWFGHGpAFe7DL68JlBUk+l7KSN7tCOEJ4M3/qOI49vMHj+zCKdlFqLaU2ZHV2a4Ct/an0/ivdX8oYc1UVX860fQ
      DQiMdxRQEAAA=="
   }
}

Amazon API Gateway

La fonction AWS Lambda peut être appelée sur httpsurl. Cela peut être fait surGET, POST, PUT. Lorsque l'url https est appelée, la fonction AWS Lambda est également déclenchée et les données transmises à https à l'aide de get / post peuvent être rendues disponibles dans AWS Lambda pour être utilisées pour être insérées dans DynamoDB ou pour envoyer du courrier, etc.

Événement de demande de proxy de passerelle API

{
   "path": "/test/hello",
   "headers": {
      "Accept":  "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
      "Accept-Encoding": "gzip, deflate, lzma, sdch, br",
      "Accept-Language": "en-US,en;q=0.8",
      "CloudFront-Forwarded-Proto": "https",
      "CloudFront-Is-Desktop-Viewer": "true",
      "CloudFront-Is-Mobile-Viewer": "false",
      "CloudFront-Is-SmartTV-Viewer": "false",
      "CloudFront-Is-Tablet-Viewer": "false",
      "CloudFront-Viewer-Country": "US",
      "Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com",
      "Upgrade-Insecure-Requests": "1",
      "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
      "Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)",
      "X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==",
      "X-Forwarded-For": "192.168.100.1, 192.168.1.1",
      "X-Forwarded-Port": "443",
      "X-Forwarded-Proto": "https"
   },
   "pathParameters": {
      "proxy": "hello"
   },
   "requestContext": {
      "accountId": "123456789012",
      "reexampleId": "us4z18",
      "stage": "test",
      "requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9",
	   "identity": {
         "cognitoIdentityPoolId": "",
         "accountId": "",
         "cognitoIdentityId": "",
         "caller": "",
         "apiKey": "",
         "exampleIp": "192.168.100.1",
         "cognitoAuthenticationType": "",
         "cognitoAuthenticationProvider": "",
         "userArn": "",
         "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
         "user": ""
      },
      "reexamplePath": "/{proxy+}",
      "httpMethod": "GET",
      "apiId": "wt6mne2s9k"
   },
   "reexample": "/{proxy+}",
   "httpMethod": "GET",
   "queryStringParameters": {
      "name": "me"
   },
   "stageVariables": {
      "stageVarName": "stageVarValue"
   }
}

Événement de réponse du proxy API Gateway

{
   "statusCode": 200,
   "headers": {
      "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
      "Accept-Encoding": "gzip, deflate, lzma, sdch, br",
      "Accept-Language": "en-US,en;q=0.8",
      "CloudFront-Forwarded-Proto": "https",
      "CloudFront-Is-Desktop-Viewer": "true",
      "CloudFront-Is-Mobile-Viewer": "false",
      "CloudFront-Is-SmartTV-Viewer": "false",
      "CloudFront-Is-Tablet-Viewer": "false",
      "CloudFront-Viewer-Country": "US",
      "Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com",
      "Upgrade-Insecure-Requests": "1",
      "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
      "Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)",
      "X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==",
      "X-Forwarded-For": "192.168.100.1, 192.168.1.1",
      "X-Forwarded-Port": "443",
      "X-Forwarded-Proto": "https"
   },
   "body": "Hello World"
}