fc2ブログ

記事一覧

Lambda を Visual Studio 2019 C# .NET Core で 構成する方法 | AWS

TOP > AWS > Lambda

今回は AWS のサーバーレスという分類に属する Lambda を Visual Studio 2019 C# で構成する方法について覚え書きします。AWS Toolkit をインストールすることで Visual Studio 上で作成した C# のコードを Lambda 関数としてデプロイすることが可能です。



前提条件
・Windows10 Pro 64Bit 2004
・Visual Studio 2019 Community v16.9.4
・C# .NET Core 3.1
・AWS で開発用のアカウントを取得して、決済情報を登録していること



1.Lambda の特徴

前提として AWS Lambda の特徴についておさらいしておきましょう。実行可能な条件がかなり厳しいために使用できる場面が限られてきますので、注意が必要です。
・1か月あたりの従量課金制です。
・1か月あたり100万リクエストまでの無料枠があります。
・1つの関数の処理実行時間は最大15分まで
・同時実行数1000まで処理が可能。
・同時実行数は事前申請で拡張が可能。
・同時実行数を超えた場合はスロットリング(制限)されます。
・初回実行時はコールドスタートのため、2~3秒ぐらい待ちます。
(※初回実行時は内部的にDockerコンテナを立ち上げる時間が必要なため、コールドスタートとなる。ウォームアップ状態(ホットスタンバイ)として待機するように設定するとDockerコンテナの使用時間が料金に加算されてしまうため、Fargateよりも高くなってしまうケースがあるなど懸念点は多い。)

上記から使用用途としては、スモールスタート的なアプリに適しており、大規模なシステムや実行速度を求める要件があるシステムでは使用が難しい条件ですね。また、処理時間の関係上、夜間バッチに使用することも難しいです。
Lambda関数を実装するにしても非同期処理でリトライ機能を持たせて、UIにはスピナーを表示してユーザーに処理中であることを通知することが望ましいでしょう。



2.AWS Toolkit のインストール

以下の AWS のサイトから Visual Studio 2019 用の AWS Toolkit をダウンロードしてインストールします。
https://aws.amazon.com/jp/visualstudio/
※アドオンであるため、Visual Studio が起動しているとインストールが途中で進まなくなります。

aws_lambda_toolkit_01.png



3.Visual Studio 上での開発方法

Visual Studio を起動して、新しいプロジェクトの作成または追加をします。
AWS Lambda Project(.NET Core - C#)を選択して、次に進みます。

aws_lambda_vs_01.png


プロジェクトのディレクトリや名称を決定して次に進むと、 Lambda で使用する開発テンプレートの選択画面になります。ここでは Empty Function を選択します。デフォルトで .NET Core 3.1 の開発テンプレートになっています。

aws_lambda_vs_02.png


Finish ボタンを押下すると、Lambda用のプロジェクトが VS のソリューションエクスプローラーに表示され、開発ができるようになります。



4.C# .NET Core の構成方法

初期の Lambda のプロジェクト内に Function.cs が作成されていますが、これを以下のように書き換えます。(あくまでサンプルです。他にも構成方法があります。)


AWSLambdaSampleApp.Function.cs 

using System.Collections.Generic;
using Amazon.Lambda.Core;
using Newtonsoft.Json;
using System.Net;

// 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 AWSLambdaSampleApp
{
    /// <summary>
    /// Lambdaのリクエスト情報を保持する
    /// </summary>
    public class LambdaRequest
    {
        [JsonProperty(PropertyName = "body")]
        public string body { get; set; }
    }

    /// <summary>
    /// Lambdaのレスポンス情報を保持する
    /// Lambdaプロキシ統合を使用する場合は、
    /// 以下の 4つのプロパティの名称が異なっていたり、大文字小文字の違いや、
    /// 綴りが間違っていると502の内部エラーになってしまいますので注意が必要です。
    /// </summary>
    public class LambdaResponse
    {
        [JsonProperty(PropertyName = "isBase64Encoded")]
        public bool isBase64Encoded { get; set; }

        [JsonProperty(PropertyName = "statusCode")]
        public HttpStatusCode statusCode { get; set; }

        [JsonProperty(PropertyName = "headers")]
        public Dictionary<string, string> headers { get; set; }

        [JsonProperty(PropertyName = "body")]
        public string body { get; set; }
    }

    /// <summary>
    /// Lambdaに送信したい情報のモデルクラスです。任意の構成が可能です。
    /// </summary>
    public class RequestParam
    {
        [JsonProperty(PropertyName = "value1")]
        public int value1 { get; set; }

        [JsonProperty(PropertyName = "value2")]
        public int value2 { get; set; }
    }

    /// <summary>
    /// Lambdaから受信したい情報のモデルクラスです。任意の構成が可能です。
    /// </summary>
    public class ResponseParam
    {
        [JsonProperty(PropertyName = "result")]
        public int result { get; set; }
    }

    /// <summary>
    /// Lambda関数
    /// </summary>
    public class Function
    {
        /// <summary>
        /// Lambdaのエントリポイント
        /// </summary>
        /// <param name="input">リクエスト情報</param>
        /// <param name="context"></param>
        /// <returns></returns>
        public LambdaResponse FunctionHandler(LambdaRequest input, ILambdaContext context)
        {
            var data = JsonConvert.DeserializeObject<RequestParam>(input.body);
            var header = new Dictionary<string, string>()
            {
                {"x-custom-header" , "my custom header value" }
            };
            return new LambdaResponse
            {
                //Lambdaプロキシ統合を使用する場合は、
                //レスポンスの形式はこの形式でないとHTTPステータスコード502の内部エラー(Internal Sever Error)で返ってきてしまいます。
                isBase64Encoded = false,
                statusCode = HttpStatusCode.OK,
                headers = header,
                body = JsonConvert.SerializeObject(
                    new ResponseParam
                    { 
                        result = data.value1 * data.value2 * 2 //処理結果を示す簡単な計算式です(任意です)
                    })
            };
        }
    }
}


aws_lambda_vs_03.png



5.Lambda へのデプロイ方法

C# での開発が完了したら、初回のみ AWS へデプロイするためのアクセスキーを埋め込みます。VS メニューの 表示 > AWS Explorer を選択し、アカウントを追加します。

aws_lambda_vs_07.png


以下の画面に アクセスキーとシークレットアクセスキーを入力します。Region は Lambda を実行するリージョンを指定します。

aws_lambda_vs_08.png


アクセスキーがない場合は、AWS のコンソール上で アカウント名 > マイセキュリティ資格情報 と進み、アクセスキーを発行します。

aws_iam_accesskey_01.png


アカウントが登録できたら、VS の Lambda プロジェクトを右クリックして、「Publish To AWS Lambda...」を選択します。

aws_lambda_vs_04.png


次に AWS Lambda で表示するための項目を入力します。

項目名入力する値について
Package Type Zipを選択します。DLLなどのファイルをまとめて圧縮してAWSに送信します。
Lambda Runtime C#プロジェクトで使用している対象のフレームワークを設定します。
Configration Release/Debug を選択します。Debug にしても AWS にアタッチができないため、コードのデバッグはできませんでした。
Function Name AWS Lambda の画面で表示する関数名
Assembly プロジェクトのプロパティで設定しているアセンブリ名。デフォルトはプロジェクト名称が入っています。
Type プロジェクト名.Function
Method Function.cs内のエントリポイントの関数名

aws_lambda_vs_05.png


次に AWS で Lambda のフルアクセス権限をもつロールを選択します。ロールを作成していない場合は、事前に AWS IAM のサイトで作成します。メモリはサンプルの為の構成なので、最低の 128MB を選択しました。実行するプログラムに合わせて変更する必要があります。Uploadボタンを押下すると AWS に Lambda 関数がデプロイされます。

aws_lambda_vs_06.png

※SQSのエラーが表示されているかもしれませんが、SQSは使用しないため、無視して進みます。



6.Lambda の実行方法

(1) VS 上での実行方法
Lambda をデプロイしたら、VS 上に Test Function の画面が表示されます。
Example Request のボディ欄に以下のJSONを入力して、Invoke ボタンを押下すると、右側の Response 欄に結果が表示されます。

{
  "body": "{\"value1\": 3, \"value2\": 4}"
}
※API Gateway を経由しない場合は、プロキシ統合を使用するしないに関わらず上記のJSONフォーマットになります。

aws_lambda_vs_09.png


(2)AWS Lambda コンソール上での確認方法
AWS Lambda > 関数 > {Lambda関数名} > テスト からテストが行えます。
同じくBodyにJSONを入力して、テストボタンを押下すると、結果が詳細の中に表示されます。

aws_lambda_vs_10.png


(3)API Gateway を構成して、インターネット越しにアクセスする方法
これは本番環境と同じ構成となります。上記の AWS Lambda 画面に「トリガーを追加」ボタンがありますので、押下します。
以下の構成でAPI Gateway を作成します。

項目名入力する値について
追加するトリガー API Gateway
API APIを作成する
APIタイプ REST API
セキュリティ オープン
追加の設定 なし(デフォルトのまま)

aws_lambda_vs_11.png


API Gateway が追加できたら、まずは AWS のコンソールから API Gateway のテストを行います。
Lambda > 関数 > 関数名 > トリガー > API Gateway > 統合リクエスト > テスト と進みます。

以下のように メソッドとBodyを入力してテストボタンから実行すると結果が得られます。正常に返ってくる状態であれば、API Gateway をデプロイします。

※API Gateway でプロキシ統合を使用する場合は以下のようなリクエストになります。
{
  "value1": 3, "value2": 4
}

aws_lambda_vs_13.png

※上記イメージ画像ではプロキシ統合を使用しないリクエスト・レスポンスになっています。


そして、完全に外部からアクセスするには、API Gateway の URL を確認する必要があります。API Gateway を選択すると詳細から URL を取得できますので、Chrome のアドオンである、Advanced REST clientAdvanced REST client などのツールを使用して POST のテストを行います。

aws_lambda_vs_12.png

※上記イメージ画像ではプロキシ統合を使用しないリクエスト・レスポンスになっています。


以上で、インターネット越しのアクセスが正常に確認でき、Visual Studio 2019 C# .NET Core で作成したプロジェクトを AWS Lambda で実行できたことが確認できました。
その他、注意点としましては、別プロジェクトの共通処理があるために、プロジェクト参照などしていると、そのままでは正しくデプロイできず、プロジェクト参照を「ローカルにコピー」の設定にするとデプロイができる点や、プロキシ統合を使用するしないでリクエストレスポンスの形式が若干異なる点や、API Gateway の設定手順の違いで HTTPステータスコード 502 Internal Server Error になる場合があるなど、注意が必要な点がありました。





関連記事

コメント

コメントの投稿

※名前とタイトルが入力されていないコメントでは他のコメントとの区別ができません。

 入力されていないコメントには返信しませんのであらかじめご了承くださいませ。

※ニックネームでも良いので必ずご入力ください。

    

※必ずご入力ください。

    
    

※必ずご入力ください。

※技術的な質問には環境やエラーについて正確かつ詳細にお教えください。

・正確なエラーの内容

・Windowsのバージョン番号

・Visual Studioのバージョン

・機器の型番

・アプリやソフトのバージョン

    

カテゴリ別記事一覧

広告

プロフィール

石河 純


著者名 :石河 純
自己紹介:素人上がりのIT技術者。趣味は卓球・車・ボウリング

IT関連の知識はざっくりとこんな感じです。
【OS関連】
WindowsServer: 2012/2008R2/2003/2000/NT4
Windows: 10/8/7/XP/2000/me/NT4/98
Linux: CentOS RedHatLinux9
Mac: macOS Catalina 10.15 / Mojave 10.14 / High Sierra 10.13 / Sierra 10.12 / OSX Lion 10.7.5 / OSX Snow Leopard 10.6.8
【言語】
VB.net ASP.NET C#.net Java VBA
Xamarin.Forms
【データベース】
Oracle 10g/9i
SQLServer 2016/2008R2/2005/2000
SQLAnywhere 16/11/8
【BI/レポートツール】
Cognos ReportNet (IBM)
Microsoft PowerBI
ActiveReport (GrapeCity)
CrystalReport
【OCX関連】
GrapeCity InputMan SPREAD MultiRow GridView
【ネットワーク関連】
CCNP シスコ技術者認定
Cisco Catalyst シリーズ
Yamaha RTXシリーズ
FireWall関連
【WEB関連】
SEO SEM CSS jQuery IIS6/7 apache2

休みの日は卓球をやっています。
現在、卓球用品通販ショップは休業中です。