AWS Lambda での.NET ワークロード

モジュール 6

モジュール 6: ハンズオンラボ:Lambda 関数の作成とデプロイ

 ハンズオンラボ

目標

これらのラボでは、このコースで学んだことを実践します。

さまざまな .NET 6/7 Lambda 関数を作成し、デプロイして呼び出します。

このモジュールには次の 3 つのラボがあります。

ラボ 1: Arm64 上で動作する.NET 6 ウェブアプリケーション
ラボ 2: コンピューター上の C# プログラムから Lambda 関数を呼び出す
ラボ 3: ある Lambda 関数を別の関数から呼び出す

前提条件

AWS アカウントをお持ちの場合は、

AdministratorAccess ポリシーがアタッチされた AWS ユーザーがいます。詳細については、モジュール 3 の「権限に関するメモ」セクションを参照してください。/p >

.NET 6 SDK がインストールされました。

.NET CLI 用 AWS 拡張機能 (dotnet lambda...) がインストールされました。

.NET 用 AWS Lambda コアテンプレートがインストールされました。

PowerShell がインストールされました。Window/Mac/Linux 用にインストールする必要がある場合は、https://github.com/PowerShell/PowerShell を参照してください。

上記のツールの詳細については、モジュール 2 を参照してください。

CloudFormation スタック用の S3 バケットがあります。そうでない場合は、以下の手順に従ってください。

 所要時間

45 分

ラボ 1: Arm64 上で動作する A.NET 6 ウェブアプリケーション

ステップ 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.インデックス.cshtml を更新

ページ/索引.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 に変更
もう一つ変更します。

サーバーレスの.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 ウェブ API プロジェクトを作成する
出力の最後に、APIURL が表示されます。これをブラウザで開きます。

ステップ 5: クリーンアップ

このステップでは、サーバーレスプロジェクトを AWS から削除します。
1.サーバーレスプロジェクトを削除する
実行中に作成されたすべてのリソースを削除するには:
dotnet lambda delete-serverless --stack-name AspNetCoreWebApp

ラボ 2: コンピューター上の C# プログラムから Lambda 関数を呼び出す

ステップ 1: 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 ポリシーの作成

ロールにアタッチしたポリシーには、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 関数を作成する

このステップでは、GetS3Buckets 関数を呼び出す Lambda 関数を作成します。

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 をデプロイする。

このステップでは、Lambda 関数からの GetS3BucketsCallFromLambdaFunction を 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 呼び出しには、GetS3 バケットを呼び出すための権限が必要だからです。

次のステップでは、GetS3BucketsCallFromLambdaFunction に必要なアクセス権限を付与するインラインポリシーを追加します。

ステップ 6: GetS3BucketsCallFromLambdaFunction 呼び出しに、GETS3 バケットを呼び出すための権限を付与する

このステップでは、GetS3BucketsCallFromLambdaFunction に GetS3 バケットを呼び出すためのアクセス権限を付与します。

1.GetS3Buckets の ARN を取得

GetS3BucketsCallFromLambdaFunction に呼び出し権限を付与する前に、GetS3 バケットの Amazon リソースネーム (ARN) を取得する必要があります。

これにはいくつかの方法があります。まず、AWS コンソールから。Lambda サービスにアクセスし、GetS3Buckets 関数を選択します。

強調表示された両方の領域から [Copy ARN] をクリックできます。

コマンドラインから GetS3Bucket の 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

役に立つ情報はたくさんありますが、必要なのは表の 2 行目の Arn です。

InvokeGetS3Buckets.json という名前のファイルを作成し、それに以下を追加します。

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

「リソース」を、コマンドラインまたはコンソール UI から取得した 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 呼び出し関数を使用して関数を呼び出す

今回は、次の関数を呼び出すことができます。

dotnet lambda invoke-function --function-name GetS3BucketsCallFromLambdaFunction

まとめ

これらのラボでは、学んだことを実践します。最初に、世界中のどこからでもアクセス可能な Web アプリケーションを作成しました。次に、コンピューター上の C# プログラムから直接呼び出した Lambda 関数をデプロイしました。次に、2 つ目のラボで別の Lambda 関数をデプロイし、別の Lambda 関数から呼び出して構築しました。また、権限の問題が発生したらすぐに解決する必要もありました。

ここから、Lambda 関数で他の AWS サービスを使用して、より複雑な Lambda アプリケーションを構築してみることができます。

このページは役に立ちましたか?