AWS Lambda 上的 .NET 工作负载

模块 6

模块 6:动手实验:创建并部署 Lambda 函数

 动手实验

实验目标

在这些实验中,您将把在本课程中学到的知识付诸实践

您将创建、部署和调用各种 NET 6/7 Lambda 函数。

本模块有 3 个实验:

实验 1:在 Arm64 上运行的 .NET 6 Web 应用程序
实验 2:在计算机上从 C# 程序调用 Lambda 函数
实验 3:从其他位置调用一个 Lambda 函数

先决条件

您有 AWS 账户。

您有一个已附加 AdministratorAccess 策略的 AWS 用户,如需了解详情,请参阅模块 3 中的“权限说明”部分。/p>

您已安装 .NET 6 SDK

您已安装适用于 .NET CLI 的 AWS 扩展程序(dotnet lambda…)。

您已安装 AWS Lambda for .NET Core 模板

您已安装 PowerShell。如果您需要为 Window/Mac/Linux 安装 PowerShell,请参阅 https://github.com/PowerShell/PowerShell

您可以在模块 2 中找到有关上述工具的更多信息。

您有适用于 CloudFormation 堆栈的 S3 存储桶。如果您没有,请按照以下说明进行操作。

 所需时间

45 分钟

实验 1:在 Arm64 上运行的 .NET 6 Web 应用程序

第 1 步:创建项目

在此步骤中,您将创建 .NET 无服务器项目。

1.创建无服务器 .NET 项目

dotnet new serverless.AspNetCoreWebApp -n AspNetCoreWebApp
这将在 AspNetCoreWebApp\src\AspNetCoreWebApp 目录中创建项目。
2.打开项目
在您最常用的 IDE 中打开此项目。

第 2 步:对代码进行一些修改

在此步骤中,您将修改生成的项目代码。
1.更新 Index.cshtml.cs
在 IDE 中打开项目后,在代码编辑器中打开 Pages/Index.cshtml.cs。

您可以将 using 语句和命名空间保持原样,但将 IndexModel 类替换为以下内容:
public class IndexModel : PageModel
{
    public string? Architecture { get; set; }
    public string? DotnetVersion { get; set; }
    
    public void OnGet()
    {
        Architecture = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString();
        DotnetVersion = Environment.Version.ToString();
    }
}

2.更新 Index.cshtml

打开 Pages/Index.cshtml 文件。

将文件中向下直到 </h2> 的内容替换为以下内容:
@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
  <h1 class="display-4">Welcome to .NET Lambda functions on AWS!</h1>
  <h2>Your application is using .NET <code>@Model.DotnetVersion</code>, <code>@Model.Architecture</code>.</h2>
</div>
保留 <svg> 元素。

执行这些更改后,您将能够查看正在运行的 .NET 版本,以及您正在使用的处理器的类型

第 3 步:配置处理器架构

在此步骤中,您要将处理器架构设置为 Arm64。
1.将处理器架构更改为 Arm64
再进行一项更改。

打开 serverless.template 文件。

找到“Handler”键,然后在下一行添加:
"Architectures": ["arm64"],
现在,您的代码块应该如下所示:
"AspNetCoreFunction": {
  "Type": "AWS::Serverless::Function",
  "Properties": {
    "Handler": "AspNetCoreWebApp::AspNetCoreWebApp.LambdaEntryPoint::FunctionHandlerAsync",
    "Architectures": ["arm64"],
2.保存并构建
保存所有更改并构建应用程序,以确保您不会遇到任何编译错误。

第 4 步:部署函数

在此步骤中,您将部署并测试您的 Lambda 函数。
1.将函数部署到 AWS
从命令行运行:
dotnet lambda deploy-serverless --stack-name AspNetCoreWebApp --s3-bucket your-unique-bucket-name1234
等待 AWS 部署您的 Lambda 函数。

您将看到部署的每个步骤在进行和完成时的输出。
8/9/2022 1:45 PM     AspNetCoreFunctionProxyResourcePermissionProd CREATE_COMPLETE
8/9/2022 1:45 PM     AspNetCoreWebApp                         CREATE_COMPLETE
Stack finished updating with status: CREATE_COMPLETE

Output Name                    Value
------------------------------ --------------------------------------------------
ApiURL                         https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/Prod/
2.创建 .NET WebAPI 项目
输出的末尾有一个 ApiURL,请在浏览器中将其打开。

第 5 步:清理

在此步骤中,您将从 AWS 中删除无服务器项目。
1.删除无服务器项目
要移除运行期间创建的所有资源,请执行以下操作:
dotnet lambda delete-serverless --stack-name AspNetCoreWebApp

实验 2:在计算机上从 C# 程序调用 Lambda 函数

第 4 步:创建 Lambda 函数

在此步骤中,您将创建一个空白的 Lambda 项目。

1.创建项目

如果您仍位于为上一个实验创建的目录中,请从中移出,转到一个干净的目录。通过命令行创建新的 Lambda 函数:

dotnet new lambda.EmptyFunction -n GetS3Buckets
这将在 AspNetCoreWebApp\src\AspNetCoreWebApp 目录中创建项目。

第 2 步:代码更改

在此步骤中,您将修改生成的项目代码。

1.添加包

更改 GetS3Buckets\src\ GetS3Buckets 文件夹,并将 AWS SDK S3 包添加到项目:

cd GetS3Buckets\src\ GetS3Buckets
dotnet add package AWSSDK.S3

2.更新 Function.cs

在 IDE 中打开 Function.cs,然后将代码替换为以下内容:

using Amazon.Lambda.Core;
using Amazon.S3;
using Amazon.S3.Model;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace GetS3Buckets;

public class Function
{
   public async Task<IEnumerable<string>> FunctionHandler(ILambdaContext context)
    {
        var s3Client = new AmazonS3Client();

        ListBucketsRequest listBucketsRequest = new ListBucketsRequest();
        ListBucketsResponse listBucketsResponse = await s3Client.ListBucketsAsync(listBucketsRequest);

        var bucketNames = listBucketsResponse.Buckets.Select(b => b.BucketName);

        return bucketNames;
    }
}

第 3 步:部署函数

在此步骤中,您将部署并测试您的 Lambda 函数。

1.将函数部署到 AWS

使用以下代码将函数部署到 AWS:

dotnet lambda deploy-function GetS3Buckets

当系统要求您选择角色时,请选择用于创建新角色的选项。使用名称 GetS3BucketsRole 作为角色名称。

当系统要求您附加策略时,请选择针对 AWSLambdaBasicExecutionRole 的选项,在我的列表中,该选项在第 6 位。

第 4 步:添加 ListAllMyBuckets 权限

在此步骤中,您将添加权限来列出 S3 桶。

1.创建 IAM policy

您附加到该角色的策略没有必要权限,无法列出 S3 桶。

创建一个名为 S3ListAllMyBucketsPolicy.json 的新文件。

将以下内容粘贴到该文件中:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "*"
        }
    ]
}

2.为角色添加策略

将策略添加到 GetS3BucketsRole:。

aws iam put-role-policy --role-name GetS3BucketsRole --policy-name ListAllMyBuckets --policy-document file://S3ListAllMyBucketsPolicy.json

请稍等片刻,让权限得以应用。

第 5 步:从命令行调用 Lambda 函数

在此步骤中,您将部署并测试您的 Lambda 函数。

1.从命令行调用函数

在创建 C# 程序以调用函数之前,请先尝试从命令行调用它:

dotnet lambda invoke-function --function-name GetS3Buckets

您应该会看到输出中列出了您的所有桶。

这会验证 Lambda 函数是否按预期运行。

第 6 步:从命令行调用 Lambda 函数

在此步骤中,您将创建用于调用 Lambda 函数的 C# 程序。

1.创建控制台应用程序

使用以下代码创建 .NET 控制台应用程序:

dotnet new console -n GetS3BucketsCallFromLocal

2.添加 AWSSDK.Lambda 包

更改为 GetS3BucketsCallFromLocal 文件夹。

cd GetS3BucketsCallFromLocal

添加 AWS SDK Lambda 包,以便调用 Lambda 函数:

dotnet add package AWSSDK.Lambda

3.更新 Program.cs

打开 Program.cs 文件并将其替换为以下内容:

using System.Text.Json;
using Amazon.Lambda;
using Amazon.Lambda.Model;

AmazonLambdaClient client = new AmazonLambdaClient();

var request = new InvokeRequest
{
    FunctionName = "GetS3Buckets"
};

var result = await client.InvokeAsync(request);

var buckets = JsonSerializer.Deserialize<IEnumerable<string>>(result.Payload);

foreach (var bucket in buckets)
{
    Console.WriteLine(bucket);
}

第 7 步:试用

在此步骤中,您将测试控制台程序并调用 Lambda 函数。

1.运行控制台应用程序

从 GetS3BucketsCallFromLocal 目录的命令行中,运行:

dotnet run 

您应该会看到桶名称列表。

第 8 步:清理

在下一个实验中,您会用到此函数,因此暂时不要清理。

实验 3:从其他位置调用一个 Lambda 函数

第 1 步:创建 GetS3Buckets 函数

完成之前的实验。

第 2 步:创建 Lambda 函数

在此步骤中,您将创建一个 Lambda 函数来调用 GetS3Buckets 函数。

1.创建一个空白的 Lambda 项目

从命令行运行:

dotnet new lambda.EmptyFunction -n GetS3BucketsCallFromLambdaFunction

2.更改文件夹

更改为 GetS3BucketsCallFromLambdaFunction\src\GetS3BucketsCallFromLambdaFunction 目录。

第 3 步:更新代码

在此步骤中,您将更新项目代码。

1.添加 AWSSDK.Lambda 包

将 AWS SDK Lambda 包添加到项目:

dotnet add package AWSSDK.Lambda

2.更新 Function.cs

打开 Function.cs 文件,将代码替换为以下内容:

using Amazon.Lambda;
using Amazon.Lambda.Core;
using Amazon.Lambda.Model;
using System.Text.Json;
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace GetS3BucketsCallFromLambdaFunction;

public class Function
{
    
    public async Task<IEnumerable<string>> FunctionHandler(ILambdaContext context)
    {
        AmazonLambdaClient client = new AmazonLambdaClient();

        var request = new InvokeRequest
        {
            FunctionName = "GetS3Buckets",
        };

        var result = await client.InvokeAsync(request);

        var bucketNames = JsonSerializer.Deserialize<IEnumerable<string>>(result.Payload);

        return bucketNames;
    }
}

在此示例中,GetS3BucketsCallFromLambdaFunction Lambda 函数正在调用 GetS3Buckets 函数并返回响应,没有对响应做任何更改。

第 4 步:部署 GetS3BucketsCallFromLambdaFunction

在此步骤中,您要将 GetS3BucketsCallFromLambdaFunction Lambda 函数部署到 AWS。

1.部署函数

从命令行运行:

dotnet lambda deploy-function GetS3BucketsCallFromLambdaFunction

2.创建角色

为已命名的函数创建新角色 

GetS3BucketsCallFromLambdaFunctionRole.

3.将策略附加到角色

AWSLambdaBasicExecutionRole 策略附加到角色。

第 5 步,尝试调用 GetS3BucketsCallFromLambdaFunction

在此步骤中,您将尝试调用函数。

1.部署函数

尝试调用 GetS3BucketsCallFromLambdaFunctionRole:

dotnet lambda invoke-function --function-name GetS3BucketsCallFromLambdaFunction

您将会遇到类似如下的错误:

Payload:
{
  "errorType": "AmazonLambdaException",
  "errorMessage": "User: arn:aws:sts::000000000000:assumed-role/GetS3BucketsCallFromLambdaFunctionRole/GetS3BucketsCallFromLambdaFunction 
is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-east-1:000000000000:function:GetS3Buckets because no 
identity-based policy allows the lambda:InvokeFunction action",

这是因为 GetS3BucketsCallFromLambdaFunction 需要有权限才能调用 GetS3Buckets。

在下一步中,您将添加内联策略,为 GetS3BucketsCallFromLambdaFunction 授予所需权限

第 6 步:授权 GetS3BucketsCallFromLambdaFunction 调用 GetS3Buckets

在此步骤中,您将授权 GetS3BucketsCallFromLambdaFunction 调用 GetS3Buckets。

1.获取 GetS3Buckets 的 ARN

在授予 GetS3BucketsCallFromLambdaFunction 调用权限之前,您需要先获取 GetS3Buckets 的 Amazon 资源名称(ARN)。

您可以通过几种方式来做到这一点。第一种,使用 AWS 管理控制台。转到 Lambda 服务,然后选择“GetS3Buckets”函数

您可以在两个突出显示的区域中单击“复制 ARN”。

要从命令行中获取 GetS3Buckets 的 ARN,请运行:

dotnet lambda get-function-config GetS3Buckets

您将看到如下所示的输出:

项目首页:https://github.com/aws/aws-extensions-for-dotnet-cli

 https://github.com/aws/aws-lambda-dotnet

Name:                         GetS3Buckets
Arn:                          arn:aws:lambda:us-east-1:000000000000:function:GetS3Buckets
Package Type:                 Zip
Runtime:                      dotnet6
Function Handler:             GetS3Buckets::GetS3Buckets.Function::FunctionHandler
Last Modified:                2022-08-10T13:58:29.211+0000
Memory Size:                  256
Ephemeral Storage Size:       512
Role:                         arn:aws:iam::000000000000:role/GetS3Buckets
Timeout:                      30
Version:                      $LATEST
State:                        Active
Last Update Status:           Successful
KMS Key ARN:                  (default) aws/lambda

有用信息有很多,但您需要的信息位于表格的第二行,即 ARN。

创建名为 InvokeGetS3Buckets.json 的文件,为其添加以下内容:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action":[
                "lambda:InvokeFunction"
            ],
            "Resource": "arn:aws:lambda:us-east-1:000000000000:function:GetS3Buckets"
        }
    ]
}
Repl

将“Resource”替换为您从命令行或控制台用户界面中获取的 Lambda 函数 ARN。

2.更新权限

运行以下命令:

aws iam put-role-policy --role-name GetS3BucketsCallFromLambdaFunctionRole
 --policy-name InvokeGetS3BucketsFunction 
 --policy-document file://InvokeGetS3Buckets.json

在 AWS 上更新权限可能需要几分钟。

第 7 步:再次调用 GetS3BucketsCallFromLambdaFunction

在此步骤中,您将再次调用函数。

1.使用 dotnet lambda invoke-function 调用函数

这一次,您能够调用函数:

dotnet lambda invoke-function --function-name GetS3BucketsCallFromLambdaFunction

结论

在这些实验中,您将所学知识付诸实践。首先,您创建了一个可以全球范围内均可访问的 Web 应用程序。然后,您部署了可以直接在计算机上从 C# 程序中调用的 Lambda 函数。之后,您在第二个实验基础上进行构建,您部署了另一个 Lambda 函数并从其他地方调用了一个 Lambda 函数。您还必须解决出现的权限问题。

在这里,您可以尝试使用其他支持 Lambda 函数的 AWS 服务并构建更复杂的 Lambda 应用程序。

此页内容对您是否有帮助?