模組 4:與其他 AWS 服務搭配使用
學習模組
使用其他 AWS 服務的方法有多種。
如果您存取的服務是 AWS RDS 資料庫 (例如 SQL Server 或 Postgres),則您使用的資料庫與您在自己的電腦或資料中心託管資料庫時使用的資料庫相同。您需要一個包含用戶名和密碼的連接字串,或者您選擇的其他身份驗證方式。與您日常使用資料庫的方式沒有什麼不同。您無需任何其他許可權即可存取資料庫伺服器。唯一需要注意的是,如果資料庫不可公開存取,則您需要將 Lambda 連接到 VPC (該過程需要額外的許可權)。
如果您的 Lambda 函數使用的是 S3、DynamoDB、Kinesis 等,則您可以使用 AWS SDK 與這些服務進行互動。Lambda 函數以之執行的角色需要適當的許可權才能與每項服務互動。例如,如果您想向 S3 儲存貯體新增專案,則該角色需要獲取許可權才能寫入該儲存貯體。如果您想從 DynamoDB 資料表中獲取項目,則該角色需要獲取許可權才能從該表中讀取項目。
第三種情況是,您希望其他服務觸發您的 Lambda 函數以回應某個事件。例如,您可能希望在向特定 S3 儲存貯體新增新項目,或者當事件到達 Kinesis 串流時觸發 Lambda 函數。為此,Lambda 函數必須使用「基於資源的政策」。此政策向其他服務提供調用您的 Lambda 函數的許可權。
完成時間
30 分鐘
透過 Lambda 函數存取 RDS 資料庫伺服器
使用熟悉的服務 (如 SQL Server、Postgres、MySQL) 的好處在於,從程式碼的角度來看,透過 Lambda 函式呼叫這些服務時無需任何不同於以往的操作。Entity Framework/ado/NpgSql 等與 AWS 託管資料庫一樣適用於本機/機架式資料庫。調用方式相同,您不需要 AWS SDK 資料庫,當然您仍然需要將相關的 NuGet 套件新增到您的專案中。但除此之外,都是一樣的。
透過 Lambda 函數存取 AWS 服務
2.作為獨立政策,您可以將其附加到任何角色。在 AWS 中,後者被稱為客戶管理的政策。
向角色授予盡可能少的許可權始終是最佳做法。在以下範例中,您將從 DynamoDB 資料表中讀取資料,您需要向 Lambda 角色授予兩項許可權:dynamodb:GetItem 和 dynamodb:DescribeTable。您可以將這些許可權限於您感興趣的特定資料表。
首先,建立一個名為「People」的新 DynamoDB 資料表。如果您使用的是 Windows 命令提示符,則以下命令將適用於 PowerShell,而 Linux Shell 需要對字串進行不同的轉義處理。
執行以下命令:
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
向資料表中新增一些項目:
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"}}'
然後使用以下命令建立 Lambda 函數:
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
使用以下程式碼將 Lambda 函數部署至 AWS Lambda:
dotnet lambda deploy-function LambdaFunctionDynamoDB
接下來,系統將詢問您「選擇為您的程式碼提供 AWS 憑證的 IAM 角色:」,您可能會看到之前建立的角色清單,但清單底部將顯示「**建立新 IAM 角色***」選項,在該選項旁邊輸入該數位。
系統將要求您「輸入新 IAM 角色的名稱:」。輸入「LambdaFunctionDynamoDBRole」。
然後,系統將要求您「選擇要附加到新角色的 IAM 政策並授予許可權」,並顯示政策清單。選擇「AWSLambdaBasicExecutionRole」,它位於清單第 6 位。(我知道有一個名為「AWSLambdaDynamoDBExecutionRole」的政策,但是這個模組的目標是向您展示如何自行新增必要的許可權)。
嘗試使用以下命令調用 Lambda 函數:
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"
意思就是,Lambda 函數以之執行的角色未獲得所需的 dynamodb:DescribeTable 許可權。
要解決該問題,您需要新增一個政策,以向該角色授予 dynamodb:DescribeTable 許可權。如上所述,您可以新增內聯政策 (僅適用於此角色) 或獨立政策 (適用於所有角色)。
在 LambdaFunctionDynamoDB /src/LambdaFunctionDynamoDB 資料夾中建立一個名為「DynamoDBAccessPolicy.json」的檔案。
編輯 DynamoDBAccessPolicy,但請使用您在資源中的帳號:
{
"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
這次的訊息是:
"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",
使用以下內容更新 DynamoDBAccessPolicy.json 檔案:
{
"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"
另一種選擇是將滑鼠懸停在您正在使用的 SDK 方法上,中繼資料可能包含有關許可權的有用資訊。並非所有方法中繼資料都包含許可權資訊。
現在,您知道了如何查找您的函數所需的許可權,以及如何向 Lambda 函數以之執行的角色授予正確的許可權。
允許其他服務調用 Lambda 函數
在上一節中,您學習了如何向 Lambda 函數授予對其他服務執行操作的許可權。在本節中,您將看到如何向其他服務授予調用您的 Lambda 函數的許可權。
如果您使用的是 serverless.* 範本,則可能已經向 API 閘道授予了調用 Lambda 函數所需的許可權。如果您已經部署了此類函數,請轉至「配置」標籤,選擇左側的「許可權」,然後滾動到「基於資源的政策」部分。您將看到允許 API 閘道調用您的 Lambda 函數的政策。此政策由 dotnet lambda deploy-serverless 命令和項目中的 serverless.template 新增。
在下圖中,您可以看到兩個允許 API 閘道調用 Lambda 函數的政策陳述式。
建立 S3 儲存貯體
如果您希望自己的儲存貯體位於 us-east-1,可以使用以下命令:
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
建立 Lambda 函數
從命令列執行:
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}");
}
}
}
如果 S3 事件是對已刪除物件的回應,則該函數會將儲存貯體/金鑰名稱記錄到 CloudWatch 中。
部署 Lambda 函數
dotnet lambda deploy-function S3EventHandler
接下來,系統將詢問您「選擇為您的程式碼提供 AWS 憑證的 IAM 角色:」,您可能會看到之前建立的角色清單,但清單底部將顯示「**建立新 IAM 角色***」選項,在該選項旁邊輸入該數位。
系統將要求您「輸入新 IAM 角色的名稱:」。輸入「S3EventHandlerRole」。
然後,系統將要求您「選擇要附加到新角色的 IAM 政策並授予許可權」,並顯示政策清單。選擇「AWSLambdaBasicExecutionRole」,它位於清單第 6 位。您需要新增政策來授予對 S3 儲存貯體的存取權限,這樣 GetObjectMetadataAsync(..) 調用才能生效。
授予 Lambda 函數獲取物件中繼資料的許可權
您將了解如何透過幾種方式做到這一點。
政策如下所示,但資源中包含您的儲存貯體名稱。注意最後的 /*,這意味著 s3:GetObject 適用於儲存貯體中的所有物件:
{
"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
然後將政策附加到您之前建立的角色。執行以下命令:
aws iam attach-role-policy --role-name S3EventHandlerRole --policy-arn arn:aws:iam::694977046108:policy/S3AccessPolicyForCourseBucket
按一下「配置」標籤、左側的「許可權」,然後按一下角色名稱。
按一下 新增許可權,然後按一下 附加政策。
按一下建立策略
在「操作」部分輸入 getobject,然後從清單中選擇 GetObject。
在「資源」部分選擇「特定」,然後按一下新增 ARN。
返回您按一下「建立政策」的標籤。請按照以下步驟執行操作:
1.重新載入政策清單
2.在篩檢程式中輸入 S3AccessPolicyForCourseBucket
3.選種政策旁邊的方框
4.按一下附加策略
此時,您有一個 S3 儲存貯體、Lambda 函數以及從 S3 儲存貯體獲取物件中繼資料所需的許可權。
現在是時候將 S3 儲存貯體連接到 Lambda 函數了,這樣建立和刪除事件便會觸發 Lambda 函數。
從 S3 儲存貯體中觸發 Lambda 函數
開啟 S3 中的儲存貯體清單 https://s3.console.aws.amazon.com/s3/buckets。
按一下您建立的儲存貯體。
向下滾動到「事件通知」部分。
按一下建立事件通知。
輸入事件通知名稱。
選擇左側的前兩個核取方塊:所有物件建立事件和所有物件移除事件。
滾動到底部的「目標」部分。
選擇 Lambda 函數作為目標。
在下拉清單中,輸入您之前建立的 Lambda 函數的名稱。
按一下儲存變更。
在 AWS Console 中,轉至您之前建立的 Lambda 函數。
請注意,S3 現在已列為了 Lambda 函數的觸發器。
按一下配置標籤,然後按一下左側的許可權。
您將看到一條允許 S3 調用 Lambda 函數的政策語句。
測試一下
相反,Lambda 函數會記錄到 CloudWatch 中,因此您必須去 CloudWatch 查看您的函數是否正常執行。
在您的電腦上建立要上傳到 S3 的文字檔。
從命令列執行:
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
現在,在 AWS Console 中轉至您的 Lambda 函數並查看日誌。
依次按一下監控標籤和在 CloudWatch 中查看日誌。
這三款工具的過程相似,開啟 AWS 擴充功能,按一下 CloudWatch 日誌,然後找到 /aws/lambda/S3EventHandler 的日誌串流/組。然後開啟最近的串流。
這三款工具的過程相似,開啟 AWS 擴充功能,按一下 CloudWatch 日誌,然後找到 /aws/lambda/S3EventHandler 的日誌串流/組。然後開啟最近的串流。
結語
以下是關鍵要點:如果您希望自己的 Lambda 函數與其他 AWS 服務互動,則需要向您的函數在其他服務上執行的許可權。
如果您希望其他服務調用您的函數,則需要使用基於資源的政策來授予這些服務存取您的函數的許可權。
知識檢查
1.若您想讓其他服務調用 Lambda 函數,您需要做什麼?(選擇一項)
b.建立基於資源的政策文件,向調用服務授予調用 Lambda 函數的許可權
c.無需執行任何操作,因為 Lambda 信任所有其他 AWS 服務
d.向 Lambda 函數以之執行的角色新增正確的許可權
2.您需要向角色新增什麼才能授予其存取 AWS 服務的許可權?(選擇一項)
b.基於資源的政策
c.具有必要許可權的政策
d.存取控制清單文件
3.建立與 Lambda 函數以之執行的角色一起使用的客戶管理政策的兩種方法是什麼?(選擇兩項)
a.透過命令列
b.包含在函數的原始程式碼中
c.透過 AWS Console
d.執行函數時將其新增到負載中
答案:1-b、2-c、3-ac
結語
以下是關鍵要點:如果您希望自己的 Lambda 函數與其他 AWS 服務互動,則需要向您的函數在其他服務上執行的許可權。
如果您希望其他服務調用您的函數,則需要使用基於資源的政策來授予這些服務存取您的函數的許可權。