Modul 4: Funktionsweise mit anderen AWS-Services
LERNMODUL
Es gibt verschiedene Möglichkeiten, mit anderen AWS-Services zu arbeiten.
Wenn es sich bei dem Service, auf den Sie zugreifen, um eine AWS-RDS-Datenbank wie SQL Server oder Postgres handelt, verwenden Sie dieselben Bibliotheken, die Sie verwenden würden, wenn Sie die Datenbanken auf Ihrem eigenen Computer oder Rechenzentrum hosten würden. Sie benötigen eine Verbindungszeichenfolge mit Benutzername und Passwort oder eine andere Form der Authentifizierung Ihrer Wahl. Es gibt keinen Unterschied zu Ihrer täglichen Nutzung der Datenbank. Sie benötigen keine zusätzlichen Berechtigungen, um auf den Datenbankserver zuzugreifen. Die einzige Einschränkung besteht darin, dass Sie das Lambda mit der VPC verbinden müssen, wenn die Datenbank nicht öffentlich zugänglich ist (für diesen Prozess sind zusätzliche Berechtigungen erforderlich).
Wenn Ihre Lambda-Funktion S3, DynamoDB, Kinesis usw. verwendet, verwenden Sie die AWS SDKs, um mit diesen Services zu interagieren. Die Rolle, unter der Ihre Lambda-Funktion ausgeführt wird, benötigt entsprechende Berechtigungen, um mit den einzelnen Services zu interagieren. Wenn Sie beispielsweise ein Element zu einem S3-Bucket hinzufügen möchten, benötigt die Rolle die Berechtigung, in diesen Bucket zu schreiben. Wenn Sie Elemente aus einer DynamoDB-Tabelle abrufen möchten, benötigt die Rolle Berechtigungen, um aus dieser Tabelle zu lesen.
Im dritten Szenario möchten Sie, dass ein anderer Service Ihre Lambda-Funktion als Reaktion auf ein Ereignis auslöst. Beispielsweise möchten Sie Ihre Lambda-Funktion vielleicht auslösen, wenn ein neues Element zu einem bestimmten S3-Bucket hinzugefügt wird oder wenn Ereignisse in einem Kinesis-Stream eintreffen. Dazu muss die Lambda-Funktion eine „ressourcenbasierte Richtlinie“ verwenden. Diese Richtlinie erteilt anderen Services die Erlaubnis, Ihre Lambda-Funktion aufzurufen.
Veranschlagte Zeit
30 Minuten
Zugriff auf RDS-Datenbankserver über eine Lambda-Funktion
Das Tolle an der Nutzung bekannter Services SQL Server, Postgres und MySQL ist, dass Sie in Bezug auf Code nichts anders machen müssen, wenn Sie sie von einer Lambda-Funktion aus aufrufen. Entity Framework/ADO/NpgSql usw. funktionieren mit einer von AWS gehosteten Datenbank genauso gut wie mit einer lokalen/gerackten Datenbank. Sie rufen Sie auf gleiche Weise auf, Sie benötigen keine AWS-SDK-Bibliothek, nur müssen Sie Ihrem Projekt natürlich trotzdem die entsprechenden NuGet-Pakete hinzufügen. Davon abgesehen ist alles gleich.
Zugriff auf AWS-Services über eine Lambda-Funktion
2. Als eigenständige Richtlinie, die Sie jeder Rolle zuordnen können. In AWS wird letztere als vom Kunden verwaltete Richtlinie bezeichnet.
Es empfiehlt sich immer, der Rolle die geringstmöglichen Berechtigungen zu geben. Im folgenden Beispiel, in dem Sie aus der DynamoDB-Tabelle lesen, müssen Sie der Lambda-Rolle zwei Berechtigungen gewähren: dynamodb:GetItem und dynamodb:DescribeTable. Sie werden diese Berechtigungen auf die eine Tabelle beschränken, an der Sie interessiert sind.
Erstellen Sie zunächst eine neue DynamoDB-Tabelle mit dem Namen „People“. Die folgenden Befehle funktionieren mit PowerShell, wenn Sie die Windows-Eingabeaufforderung verwenden, oder die Linux-Shell benötigt ein anderes Escaping für die Zeichenfolgen.
Führen Sie Folgendes aus:
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
Fügen Sie der Tabelle ein paar Elemente hinzu:
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"}}'
Erstellen Sie als Nächstes eine Lambda-Funktion mit:
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
Stellen Sie die Lambda-Funktion in AWS Lambda bereit, indem Sie Folgendes verwenden:
dotnet lambda deploy-function LambdaFunctionDynamoDB
Als Nächstes werden Sie gefragt: „Select IAM Role that to provide AWS credentials to your code:“ (Wählen Sie eine IAM-Rolle aus, um AWS-Anmeldeinformationen für Ihren Code bereitzustellen:). Möglicherweise wird Ihnen eine Liste der Rollen angezeigt, die Sie zuvor erstellt haben, aber am Ende der Liste befindet sich die Option „*** Create new IAM Role ***“ (*** Neue IAM-Rolle erstellen***). Geben Sie die Zahl neben dieser Option ein.
Sie sehen die Aufforderung „Enter name of the new IAM Role“ (Namen der neuen IAM-Rolle einzugeben). Geben Sie „LambdaFunctionDynamoDBRole“ ein.
Sie sehen dann die Aufforderung „Select IAM Policy to attach to the new role and grant permissions“ (IAM-Richtlinie auszuwählen, um sie an die neue Rolle anzuhängen und Berechtigungen zu gewähren), und eine Liste der Richtlinien wird angezeigt. Wählen Sie „AWSLambdaBasicExecutionRole“, das ist Nummer 6 auf meiner Liste. (Ich weiß, dass es eine Richtlinie namens AWSLambdaDynamoDBExecutionRole gibt, aber in diesem Modul sollen Sie erfahren, wie Sie die erforderlichen Berechtigungen selbst hinzufügen können).
Versuchen Sie, die Lambda-Funktion aufzurufen, indem Sie Folgendes verwenden:
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"
Dies bedeutet, dass die Rolle, unter der die Lambda-Funktion ausgeführt wird, nicht über die erforderliche dynamodb:DescribeTable-Berechtigung verfügt.
Um dies zu beheben, müssen Sie eine Richtlinie hinzufügen, die der Rolle die dynamodb:DescribeTable-Berechtigung gewährt. Wie oben erwähnt, können Sie eine Inline-Richtlinie (nur für diese Rolle) oder eine eigenständige Richtlinie (für alle Rollen verfügbar) hinzufügen.
Erstellen Sie eine Datei mit dem Namen DynamoDBAccessPolicy.json im Ordner LambdaFunctionDynamoDB /src/LambdaFunctionDynamoDB.
Bearbeiten Sie DynamoDBAccessPolicy, aber verwenden Sie in der Ressource Ihre Kontonummer:
{
"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
Diesmal lautet die Meldung:
"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",
Aktualisieren Sie die DynamoDBAccessPolicy.json-Datei wie folgt:
{
"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"
Eine andere Möglichkeit besteht darin, den Mauszeiger über die SDK-Methode zu bewegen, die Sie verwenden. Die Metadaten können nützliche Informationen zu Berechtigungen enthalten. Nicht alle Methoden-Metadaten enthalten Berechtigungsinformationen.
Jetzt wissen Sie, wie Sie herausfinden, welche Berechtigungen Ihre Funktion benötigt, und wie Sie der Rolle, unter der Ihre Lambda-Funktionen ausgeführt werden, die richtigen Berechtigungen gewähren.
Anderen Services erlauben, Lambda-Funktionen aufzurufen
Im vorherigen Abschnitt haben Sie gelernt, wie Sie der Lambda-Funktion Berechtigungen erteilen, um Aktionen für andere Services auszuführen. In diesem Abschnitt erfahren Sie, wie Sie anderen Services Berechtigungen zum Aufrufen Ihrer Lambda-Funktion erteilen.
Wenn Sie die serverless.*-Vorlagen verwenden, erteilen Sie einem API-Gateway wahrscheinlich bereits die erforderliche Berechtigung, um Ihre Lambda-Funktion aufzurufen. Wenn Sie eine solche Funktion bereitgestellt haben, wechseln Sie zur Registerkarte „Configuration“ (Konfiguration), wählen Sie dann links „Permissions“ (Berechtigungen) aus und scrollen Sie zum Abschnitt „Resource-based policy“ (Ressourcenbasierte Richtlinie). Sie werden Richtlinien sehen, mit denen der API-Gateway Ihre Lambda-Funktion aufrufen kann. Diese Richtlinie wurde durch den Befehl dotnet lambda deploy-serverless und die serverless.template in Ihrem Projekt hinzugefügt.
In der Abbildung unten sehen Sie zwei Richtlinienanweisungen, mit denen ein API-Gateway die Lambda-Funktion aufrufen kann.
Den S3-Bucket erstellen
Wenn Ihr Bucket in us-east-1 sein soll, können Sie den folgenden Befehl verwenden:
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
Die Lambda-Funktion erstellen
Führen Sie in der Befehlszeile Folgendes aus:
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}");
}
}
}
Wenn das S3-Ereignis auf das Löschen eines Objekts reagiert, protokolliert die Funktion die Bucket-/Schlüsselnamen in CloudWatch.
Die Lambda-Funktion löschen
dotnet lambda deploy-function S3EventHandler
Als Nächstes werden Sie gefragt: „Select IAM Role that to provide AWS credentials to your code:“ (Wählen Sie eine IAM-Rolle aus, um AWS-Anmeldeinformationen für Ihren Code bereitzustellen:). Möglicherweise wird Ihnen eine Liste der Rollen angezeigt, die Sie zuvor erstellt haben, aber am Ende der Liste befindet sich die Option „*** Create new IAM Role ***“ (*** Neue IAM-Rolle erstellen***). Geben Sie die Zahl neben dieser Option ein.
Sie sehen die Aufforderung „Enter name of the new IAM Role“ (Namen der neuen IAM-Rolle einzugeben). Geben Sie „S3EventHandlerRole“ ein.
Sie sehen dann die Aufforderung „Select IAM Policy to attach to the new role and grant permissions“ (IAM-Richtlinie auszuwählen, um sie an die neue Rolle anzuhängen und Berechtigungen zu gewähren), und eine Liste der Richtlinien wird angezeigt. Wählen Sie „AWSLambdaBasicExecutionRole“, das ist Nummer 6 auf meiner Liste. Sie müssen eine Richtlinie hinzufügen, um Zugriff auf den S3-Bucket zu gewähren, damit der Aufruf GetObjectMetadataAsync (..) funktioniert.
Der Lambda-Funktion Berechtigungen zum Abrufen der Objektmetadaten erteilen
Sie bekommen verschiedene Möglichkeiten dafür gezeigt.
Die Richtlinie wird so aussehen, wird aber Ihren Bucket-Namen in der Ressource enthalten. Beachten Sie das /* am Ende, das bedeutet, dass S3:GetObject für alle Objekte im Bucket gilt:
{
"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
Hängen Sie dann die Richtlinie an die Rolle an, die Sie zuvor erstellt haben. Führen Sie Folgendes aus:
aws iam attach-role-policy --role-name S3EventHandlerRole --policy-arn arn:aws:iam::694977046108:policy/S3AccessPolicyForCourseBucket
Klicken Sie auf den Tab „Configuration“ (Konfiguration), dann auf der linken Seite auf „Permissions“ (Berechtigungen) und dann auf den Namen der Rolle.
Klicken Sie auf Add permissions (Berechtigungen hinzufügen) und Attach policies (Richtlinien anhängen).
Klicken Sie auf Create policy (Richtlinie erstellen)
Geben Sie im Abschnitt „Actions“ (Aktionen) GetObject ein und wählen Sie GetObject aus der Liste aus.
Wählen Sie im Abschnitt „Resources“ (Ressourcen) die Option „Specific“ (Spezifisch) aus und klicken Sie auf Add ARN (ARN hinzufügen).
Kehren Sie zu dem Tab zurück, auf dem Sie auf „Create policy“ (Richtlinie erstellen) geklickt haben. Gehen Sie folgendermaßen vor:
1. Laden Sie die Liste der Richtlinien erneut
2. Geben Sie in dem Filter S3AccessPolicyForCourseBucket ein
3. Kreuzen Sie das Kästchen neben der Richtlinie an
4. Klicken Sie auf Attach policies (Richtlinien anfügen)
Zu diesem Zeitpunkt verfügen Sie über einen S3-Bucket, die Lambda-Funktion und die erforderlichen Berechtigungen, um die Objektmetadaten aus dem S3-Bucket abzurufen.
Jetzt ist es an der Zeit, den S3-Bucket mit der Lambda-Funktion zu verbinden, sodass Erstellungs- und Löschereignisse die Lambda-Funktion auslösen.
Die Lambda-Funktion vom S3-Bucket aus auslösen
Öffnen Sie die Liste der Buckets in S3 https://s3.console.aws.amazon.com/s3/buckets.
Klicken Sie auf den Bucket, den Sie erstellt haben.
Scrollen Sie nach unten zum Abschnitt „Event notifications“ (Ereignisbenachrichtigungen).
Klicken Sie auf Create event notification (Ereignisbenachrichtigung erstellen).
Geben Sie einen Namen für die Ereignisbenachrichtigung ein.
Aktivieren Sie die ersten beiden Kontrollkästchen auf der linken Seite: All object create events (Alle Ereignisse zum Erstellen von Objekten) und All object removal events (Alle Ereignisse zum Entfernen von Objekten).
Scrollen Sie nach unten zum Abschnitt „Destination“ (Ziel).
Wählen Sie die „Lambda function“ (Lambda-Funktion) als Ziel aus.
Geben Sie in der Dropdownliste den Namen der Lambda-Funktion ein, die Sie zuvor erstellt haben.
Klicken Sie auf Save changes (Änderungen speichern).
Rufen Sie in der AWS-Konsole die Lambda-Funktion auf, die Sie zuvor erstellt haben.
Beachten Sie, dass S3 jetzt als Trigger für die Lambda-Funktion aufgeführt ist.
Klicken Sie auf die Registerkarte Configuration (Konfiguration) und dann links auf Permissions (Berechtigungen).
Sie sehen eine Richtlinienanweisung, die es S3 ermöglicht, die Lambda-Funktion aufzurufen.
Testen
Stattdessen protokolliert die Lambda-Funktion in CloudWatch, sodass Sie dort prüfen müssen, wie Ihre Funktion funktioniert.
Erstellen Sie eine Textdatei auf Ihrem Computer, um sie in S3 hochzuladen.
Führen Sie in der Befehlszeile Folgendes aus:
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
Gehen Sie nun zu Ihrer Lambda-Funktion in der AWS-Konsole und überprüfen Sie die Protokolle.
Klicken Sie auf die Registerkarte Monitor (Überwachen) und dann auf View Logs in CloudWatch (Protokolle in CloudWatch anzeigen).
Der Vorgang ist für alle drei ähnlich. Öffnen Sie die AWS-Erweiterung, klicken Sie auf „CloudWatch logs“ (CloudWatch-Protokolle) und suchen Sie den Protokollstream/die Gruppe für /aws/lambda/S3EventHandler. Öffnen Sie dann den neuesten Stream.
Der Vorgang ist für alle drei ähnlich. Öffnen Sie die AWS-Erweiterung, klicken Sie auf „CloudWatch logs“ (CloudWatch-Protokolle) und suchen Sie den Protokollstream/die Gruppe für /aws/lambda/S3EventHandler. Öffnen Sie dann den neuesten Stream.
Zusammenfassung
Hier ist die wichtigste Erkenntnis: Wenn Sie möchten, dass Ihre Lambda-Funktion mit anderen AWS-Services interagiert, müssen Sie Ihrer Funktion die Berechtigungen erteilen, auf diesen anderen Service zu reagieren.
Wenn Sie möchten, dass andere Services Ihre Funktion aufrufen, müssen Sie ressourcenbasierte Richtlinien verwenden, um diesen Services Zugriff auf Ihre Funktion zu gewähren.
Wissensabfrage
1. Was müssen Sie tun, wenn ein anderer Service eine Lambda-Funktion aufrufen soll? (wählen Sie eine aus)
b. Erstellen Sie ein ressourcenbasiertes Richtliniendokument, das den aufrufenden Services die Erlaubnis erteilt, die Lambda-Funktion aufzurufen
c. Nichts, Lambda vertraut allen anderen AWS-Services
d. Fügen Sie der Rolle, die die Lambda-Funktion ausführt, die richtigen Berechtigungen hinzu1
2. Was müssen Sie einer Rolle hinzufügen, um ihr Berechtigungen für den Zugriff auf AWS-Services zu erteilen? (Wählen Sie eine Antwort aus)
b. Eine ressourcenbasierte Richtlinie
c. Eine Richtlinie mit den erforderlichen Berechtigungen
d. Ein Dokument mit einer Zugriffskontrollliste
3. Welche zwei Möglichkeiten gibt es, eine vom Kunden verwaltete Richtlinie zur Verwendung mit der Rolle zu erstellen, unter der eine Lambda-Funktion ausgeführt wird? (Wählen Sie zwei Antworten aus)
a. Über die Befehlszeile
b. Aufnahme in den Quellcode der Funktion
c. Über die AWS-Konsole
d. Fügen Sie sie der Nutzlast hinzu, wenn Sie die Funktion ausführen
Antworten: 1-b, 2-c, 3-ac
Zusammenfassung
Hier ist die wichtigste Erkenntnis: Wenn Sie möchten, dass Ihre Lambda-Funktion mit anderen AWS-Services interagiert, müssen Sie Ihrer Funktion die Berechtigungen erteilen, auf diesen anderen Service zu reagieren.
Wenn Sie möchten, dass andere Services Ihre Funktion aufrufen, müssen Sie ressourcenbasierte Richtlinien verwenden, um diesen Services Zugriff auf Ihre Funktion zu gewähren.