Module 4 : Collaboration avec d'autres services AWS
MODULE D'APPRENTISSAGE
Il existe plusieurs manières de collaborer avec d'autres services AWS.
Si le service auquel vous accédez est une base de données AWS RDS, telle que SQL Server ou Postgres, vous utilisez les mêmes bibliothèques que si vous hébergiez les bases de données sur votre propre ordinateur ou centre de données. Vous avez besoin d'une chaîne de connexion avec nom d'utilisateur et mot de passe, ou d'une autre forme d'authentification de votre choix. Cela ne diffère pas de votre utilisation quotidienne de la base de données. Vous n'avez pas besoin d'autorisations supplémentaires pour accéder au serveur de base de données. Le seul inconvénient est que si la base de données n'est pas accessible au public, vous devez connecter le Lambda au VPC (ce processus nécessite des autorisations supplémentaires).
Si votre fonction Lambda utilise S3, DynamoDB, Kinesis, etc., vous utilisez les kits SDK AWS pour interagir avec ces services. Le rôle sous lequel s'exécute votre fonction Lambda nécessite les autorisations appropriées pour interagir avec chaque service. Par exemple, si vous souhaitez ajouter un élément à un compartiment S3, le rôle devra être autorisé à écrire dans ce compartiment. Si vous souhaitez obtenir des éléments d'une table DynamoDB, le rôle doit être autorisé à lire à partir de cette table.
Dans le troisième scénario, vous souhaitez qu'un autre service déclenche votre fonction Lambda en réponse à un événement. Par exemple, vous souhaiterez peut-être déclencher votre fonction Lambda lorsqu'un nouvel élément est ajouté à un compartiment S3 particulier ou lorsque des événements arrivent dans un flux Kinesis. Pour ce faire, la fonction Lambda doit utiliser une « politique basée sur les ressources ». Cette politique donne aux autres services l'autorisation d'invoquer votre fonction Lambda.
Durée
30 minutes
Accès aux serveurs de base de données RDS à partir d'une fonction Lambda
L'avantage de l'utilisation de services familiers tels que SQL Server, Postgres, MySQL est que, du point de vue du code, vous n'avez rien à faire de différent lorsque vous les appelez à partir d'une fonction Lambda. Entity Framework/ADO/NpgSql, etc., fonctionnent aussi bien avec une base de données hébergée sur AWS qu'avec une base de données locale/rackée. Vous pouvez l'appeler de la même manière, vous n'avez pas besoin d'une bibliothèque AWS SDK. Bien entendu, vous devez tout de même ajouter les packages NuGet pertinents à votre projet. Mais sinon, c'est pareil.
Accès aux services AWS depuis une fonction Lambda
2. En tant que politique autonome que vous pouvez associer à n'importe quel rôle. Dans AWS, cette dernière est appelée politique gérée par le client.
Il est toujours recommandé d'accorder au rôle le moins d'autorisations possible. Dans l'exemple suivant, dans lequel vous allez lire un extrait de la table DynamoDB, vous devez accorder deux autorisations au rôle Lambda : DynamoDB:GetItem et DynamoDB:DescribeTable. Et vous limiterez ces autorisations à la table spécifique qui vous intéresse.
Tout d'abord, créez une nouvelle table DynamoDB appelée People. Les commandes suivantes fonctionneront avec PowerShell, si vous utilisez l'invite de commande Windows, sinon le shell Linux nécessitera un échappement différent pour les chaînes.
Exécutez la requête suivante :
aws dynamodb create-table --table-name People --attribute-definitions AttributeName=PersonId,AttributeType=N --key-schema AttributeName=PersonId,KeyType=HASH --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
Ajoutez quelques éléments au tableau :
aws dynamodb put-item --table-name People --item '{"PersonId":{"N":"1"},"State":{"S":"MA"}, "FirstName": {"S":"Alice"}, "LastName": {"S":"Andrews"}}'
aws dynamodb put-item --table-name People --item '{"PersonId":{"N":"2"},"State":{"S":"MA"}, "FirstName": {"S":"Ben"}, "LastName": {"S":"Bradley"}}'
aws dynamodb put-item --table-name People --item '{"PersonId":{"N":"3"},"State":{"S":"MA"}, "FirstName": {"S":"Claire"}, "LastName": {"S":"Connor"}}'
Puis, sélectionnez créez une fonction Lambda à l'aide de :
dotnet new lambda.EmptyFunction -n LambdaFunctionDynamoDB
cd LambdaFunctionDynamoDB /src/LambdaFunctionDynamoDB
dotnet add package AWSSDK.DynamoDBv2
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.Lambda.Core;
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
namespace LambdaFunctionDynamoDB ;
public class Function
{
public async Task<string> FunctionHandler(ILambdaContext lambdaContext)
{
AmazonDynamoDBConfig clientConfig = new AmazonDynamoDBConfig();
AmazonDynamoDBClient client = new AmazonDynamoDBClient(clientConfig);
DynamoDBContext dynamoDbContext = new DynamoDBContext(client);
Person person = await dynamoDbContext.LoadAsync<Person>(1);
return $"{person.FirstName} {person.LastName} lives in {person.State}";
}
}
[DynamoDBTable("People")]
public class Person
{
[DynamoDBHashKey]
public int PersonId {get; set;}
public string State {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
}
dotnet lambda deploy-function LambdaFunctionDynamoDB
Déployez la fonction Lambda sur AWS Lambda à l'aide de :
dotnet lambda deploy-function LambdaFunctionDynamoDB
Ensuite, il vous sera demandé « Sélectionnez le rôle IAM qui doit fournir des informations d'identification AWS à votre code : ». Une liste des rôles que vous avez créés précédemment peut vous être présentée, mais au bas de la liste se trouve l'option « *** Créer un nouveau rôle IAM *** », saisissez ce numéro à côté de cette option.
Il vous sera demandé de « saisir le nom du nouveau rôle IAM : ». Tapez « LambdaFunctionDynamoDBRole ».
Il vous sera ensuite demandé de « sélectionner la politique IAM à associer au nouveau rôle et d'accorder des autorisations » et une liste de politiques sera présentée. Sélectionnez AWSLambdaBasicExecutionRole, c'est le numéro 6 sur ma liste. (Je sais qu'il existe une politique appelée AWSLambdaDynamoDBExecutionRole, mais l'objectif de ce module est de vous montrer comment ajouter vous-même les autorisations nécessaires).
Ensuite, essayez d'invoquer à nouveau la fonction Lambda à l'aide de :
dotnet lambda invoke-function LambdaFunctionDynamoDB
"errorMessage": "User: arn:aws:sts::YOUR_ACCOUNT_NUMBER:assumed-role/LambdaFunctionDynamoDB Role/LambdaFunctionDynamoDB is not authorized to perform: dynamodb:DescribeTable on resource: arn:aws:dynamodb:us-east-1:YOUR_ACCOUNT_NUMBER:table/People because no identity-based policy allows the dynamodb:DescribeTable action"
Cela indique que le rôle sous lequel la fonction Lambda est exécutée ne dispose pas de l'autorisation DynamoDB:DescribeTable requise.
Pour résoudre ce problème, vous devez ajouter une politique accordant au rôle l'autorisation DynamoDB:DescribeTable. Comme indiqué ci-dessus, vous pouvez ajouter une politique en ligne (uniquement pour ce rôle) ou une politique autonome (disponible pour tous les rôles).
Créez un fichier appelé DynamoDBAccessPolicy.json dans le dossier LambdaFunctionDynamoDB /src/LambdaFunctionDynamoDB.
Modifiez DynamoDBAccessPolicy, mais utilisez votre numéro de compte dans la ressource :
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:DescribeTable"
],
"Resource": "arn:aws:dynamodb:us-east-1:YOUR_ACCOUNT_NUMBER:table/People"
}
]
}
aws iam put-role-policy --role-name LambdaFunctionDynamoDBRole --policy-name LambdaFunctionDynamoDBAccess --policy-document file://DynamoDBAccessPolicy.json
dotnet lambda deploy-function LambdaFunctionDynamoDB
dotnet lambda invoke-function LambdaFunctionDynamoDB
Cette fois, le message est le suivant :
"errorMessage": "User: arn:aws:sts::YOUR_ACCOUNT_NUMBER:assumed-role/LambdaFunctionDynamoDB Role/LambdaFunctionDynamoDB is not authorized to perform: dynamodb:GetItem on resource: arn:aws:dynamodb:us-east-1:YOUR_ACCOUNT_NUMBER:table/People because no identity-based policy allows the dynamodb:GetItem action",
Mettez à jour le fichier DynamoDBAccessPolicy.json avec les informations suivantes :
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:DescribeTable",
"dynamodb:GetItem"
],
"Resource": "arn:aws:dynamodb:us-east-1:YOUR_ACCOUNT_NUMBER:table/People"
}
]
}
dotnet lambda deploy-function LambdaFunctionDynamoDB
dotnet lambda invoke-function LambdaFunctionDynamoDB
Amazon Lambda Tools for .NET Core applications (5.4.2)
Project Home: https://github.com/aws/aws-extensions-for-dotnet-cli, https://github.com/aws/aws-lambda-dotnet
Payload:
"Alice Andrews lives in MA"
Une autre option consiste à survoler la méthode SDK que vous utilisez. Les métadonnées peuvent contenir des informations utiles sur les autorisations. Les métadonnées des méthodes ne contiendront pas toutes des informations d'autorisation.
Vous savez maintenant comment déterminer les autorisations dont votre fonction a besoin et comment accorder les autorisations appropriées au rôle sous lequel s'exécutent vos fonctions Lambda.
Autoriser d'autres services à invoquer des fonctions Lambda
Dans la section précédente, vous avez découvert comment autoriser la fonction Lambda à effectuer des actions sur d'autres services. Dans cette section, vous allez voir comment autoriser d'autres services à invoquer votre fonction Lambda.
Si vous utilisez les modèles sans serveur.*, vous accordez probablement déjà à une API Gateway l'autorisation requise pour invoquer votre fonction Lambda. Si vous avez déployé une telle fonction, accédez à l'onglet Configuration, puis sélectionnez Autorisations sur la gauche, puis accédez à la section Politique basée sur les ressources. Vous verrez des politiques permettant à l'API Gateway d'invoquer votre fonction Lambda. Cette politique a été ajoutée par la commande dotnet lambda deploy-serverless et par le modèle sans serveur dans votre projet.
Dans l'image ci-dessous, vous pouvez voir deux déclarations de politique permettant à une passerelle d'API d'invoquer la fonction Lambda.
Création du compartiment S3
Si vous voulez que votre compartiment soit dans us-east-1, vous pouvez utiliser la commande suivante :
aws s3api create-bucket --bucket my-unique-bucket-name-lambda-course
aws s3api create-bucket --bucket my-unique-bucket-name-lambda-course --create-bucket-configuration LocationConstraint=REGION
Créer la fonction Lambda
À partir de la ligne de commande, exécutez :
dotnet new lambda.S3 -n S3EventHandler
cd S3EventHandler/src/S3EventHandler
public async Task FunctionHandler(S3Event evnt, ILambdaContext context)
{
context.Logger.LogInformation($"A S3 event has been received, it contains {evnt.Records.Count} records.");
foreach (var s3Event in evnt.Records)
{
context.Logger.LogInformation($"Action: {s3Event.EventName}, Bucket: {s3Event.S3.Bucket.Name}, Key: {s3Event.S3.Object.Key}");
if (!s3Event.EventName.Contains("Delete"))
{
try
{
var response = await this.S3Client.GetObjectMetadataAsync(s3Event.S3.Bucket.Name, s3Event.S3.Object.Key);
context.Logger.LogInformation( $"The file type is {response.Headers.ContentType}");
}
catch (Exception e)
{
context.Logger.LogError(e.Message);
context.Logger.LogError($"An exception occurred while retrieving {s3Event.S3.Bucket.Name}/{s3Event.S3.Object.Key}. Exception - ({e.Message})");
}
}
else
{
context.Logger.LogInformation($"You deleted {s3Event.S3.Bucket.Name}/{s3Event.S3.Object.Key}");
}
}
}
Si l'événement S3 fait suite à la suppression d'un objet, la fonction enregistre les noms des compartiments et des clés dans CloudWatch.
Déployez la fonction Lambda
dotnet lambda deploy-function S3EventHandler
Ensuite, il vous sera demandé « Sélectionnez le rôle IAM qui doit fournir des informations d'identification AWS à votre code : ». Une liste des rôles que vous avez créés précédemment peut vous être présentée, mais au bas de la liste se trouve l'option « *** Créer un nouveau rôle IAM *** », saisissez ce numéro à côté de cette option.
Il vous sera demandé de « saisir le nom du nouveau rôle IAM : ». Tapez « S3EventHandlerRole ».
Il vous sera ensuite demandé de « sélectionner la politique IAM à associer au nouveau rôle et d'accorder des autorisations » et une liste de politiques sera présentée. Sélectionnez AWSLambdaBasicExecutionRole, c'est le numéro 6 sur ma liste. Vous devrez ajouter une politique pour autoriser l'accès au compartiment S3 pour que l'appel GetObjectMetadataAsync (..) fonctionne.
Accordez à la fonction Lambda les autorisations nécessaires pour obtenir les métadonnées de l'objet
Vous verrez comment procéder de différentes manières.
La politique ressemblera à ceci, mais avec le nom de votre compartiment dans la ressource. Notez le /* à la fin, cela signifie que s3:GetObject s'applique à tous les objets du compartiment :
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::my-unique-bucket-name-lambda-course/*"
}
]
}
aws iam create-policy --policy-name S3AccessPolicyForCourseBucket --policy-document file://S3AccessPolicyForCourseBucket.json
Associez ensuite la politique au rôle que vous avez créé précédemment. Exécutez la requête suivante :
aws iam attach-role-policy --role-name S3EventHandlerRole --policy-arn arn:aws:iam::694977046108:policy/S3AccessPolicyForCourseBucket
Cliquez sur l'onglet Configuration, puis sur Autorisations sur la gauche, puis cliquez sur le nom du rôle.
Cliquez sur Ajouter des autorisations, puis sur Joindre des politiques.
Cliquez sur Créer une stratégie
Dans la section Actions, saisissez getobject et sélectionnez GetObject dans la liste.
Dans la section des ressources, choisissez Spécifique, puis cliquez sur Ajouter un ARN.
Revenez à l'onglet dans lequel vous avez cliqué sur Créer une stratégie. Procédez comme suit :
1. Rechargez la liste des stratégies
2. Tapez S3AccessPolicyForCourseBucket dans le filtre
3. Cochez la case à côté de la stratégie
4. Cliquez sur Attacher des stratégies.
À ce stade, vous disposez d'un compartiment S3, de la fonction Lambda et des autorisations requises pour obtenir les métadonnées de l'objet à partir du compartiment S3.
Il est maintenant temps de connecter le compartiment S3 à la fonction Lambda, afin que les événements de création et de suppression déclenchent la fonction Lambda.
Déclenchez la fonction Lambda depuis le compartiment S3
Ouvrez la liste des compartiments dans S3 https://s3.console.aws.amazon.com/s3/buckets.
Cliquez sur celui que vous avez créé.
Faites défiler la page jusqu'à la section Notifications d'événements.
Cliquez sur Créer une notification d'événement.
Entrez un nom pour la notification de l'événement.
Cochez les deux premières cases sur la gauche : Tous les événements de création d'objets et Tous les événements de suppression d'objets.
Accédez à la section Destination en bas de l'écran.
Choisissez la fonction Lambda comme destination.
Dans la liste déroulante, saisissez le nom de la fonction Lambda que vous avez créée précédemment.
Cliquez sur Enregistrer les modifications.
Dans la console AWS, accédez à la fonction Lambda que vous avez créée précédemment.
Notez que S3 est désormais répertorié comme déclencheur de la fonction Lambda.
Cliquez sur l'onglet Configuration, puis sur Autorisations sur la gauche.
Vous verrez une déclaration de politique autorisant S3 à invoquer la fonction Lambda.
Je le teste
Au lieu de cela, la fonction Lambda se connecte à CloudWatch. C'est là que vous devez vous rendre pour voir votre fonction fonctionner.
Créez un fichier texte sur votre ordinateur à télécharger sur S3.
À partir de la ligne de commande, exécutez :
aws s3api put-object --bucket my-unique-bucket-name-lambda-course --key Hello.txt --body Hello.txt --content-type "text/plain"
aws s3api delete-object --bucket my-unique-bucket-name-lambda-course --key Hello.txt
Accédez maintenant à votre fonction Lambda dans la console AWS et consultez les journaux.
Cliquez sur l'onglet Surveiller, puis sur Afficher les journaux dans CloudWatch.
Le processus est similaire pour les trois : ouvrez l'extension AWS, cliquez sur journaux CloudWatch et recherchez le flux de journaux/ groupe pour /AWS/Lambda/S3EventHandler. Ouvrez ensuite le flux le plus récent.
Le processus est similaire pour les trois : ouvrez l'extension AWS, cliquez sur journaux CloudWatch et recherchez le flux de journaux/ groupe pour /AWS/Lambda/S3EventHandler. Ouvrez ensuite le flux le plus récent.
Conclusion
Voici le principal point à retenir : si vous souhaitez que votre fonction Lambda interagisse avec d'autres services AWS, vous devez autoriser votre fonction à agir sur cet autre service.
Si vous souhaitez que d'autres services invoquent votre fonction, vous devez utiliser des politiques basées sur les ressources pour permettre à ces services d'accéder à votre fonction.
Évaluation des connaissances préalables
1. Lorsque vous souhaitez qu'un autre service invoque une fonction Lambda, que devez-vous faire ? (sélectionnez une option)
b. Créer un document de politique basé sur les ressources donnant aux services appelants l'autorisation d'invoquer la fonction Lambda
c. Rien, le Lambda fait confiance à tous les autres services AWS
d. Ajouter les autorisations appropriées au rôle que la fonction Lambda exécute en tant que 1
2. Que devez-vous ajouter à un rôle pour lui donner l'autorisation d'accéder aux services AWS ? (sélectionnez une option)
b. Une politique basée sur les ressources
c. Une politique avec les autorisations nécessaires
d. Un document de liste de contrôle d'accès
3. Quelles sont les deux manières de créer une politique gérée par le client à utiliser avec le rôle sous lequel une fonction Lambda s'exécute ? (choisissez-en deux)
a. À l'aide de la ligne de commande :
b. Inclure dans le code source de la fonction
c. Via cette console AWS
d. Ajoutez-le à la charge utile lors de l'exécution de la fonction
Réponses : 1-b, 2-c, 3-ac
Conclusion
Voici le principal point à retenir : si vous souhaitez que votre fonction Lambda interagisse avec d'autres services AWS, vous devez autoriser votre fonction à agir sur cet autre service.
Si vous souhaitez que d'autres services invoquent votre fonction, vous devez utiliser des politiques basées sur les ressources pour permettre à ces services d'accéder à votre fonction.