C#でAWS Lambda関数を書いてみた【Python経験者向け・開発の流れと作法まとめ】

AWS

はじめに

おつかされまです。tyamonです。

PythonでAWS Lambdaを使い慣れた方が「C#でもLambdaを書いてみよう」となったとき、最初に戸惑うのが「コードを貼るだけでは動かない」という点です。この記事では、C# Lambdaの開発フローとPythonとの違いを、実際に動かしながらまとめます。

結論:C# Lambdaは「書く→ビルド→テスト→デプロイ」の4ステップが必要で、専用ツールをそろえれば一連の流れはシンプルです。


PythonとC#の最大の違い:「貼るだけ」は通用しない

PythonはインタープリタなのでAWSコンソールのコードエディタにそのまま貼れば動きます。C#はコンパイル言語なので、コードをAWSコンソールに貼る機能自体ありません。

開発の全体像はこうなります。

書く(.cs)
  ↓
ビルド(.dllを生成)
  ↓
ローカルテスト(Lambda TestToolで動作確認)
  ↓
デプロイ(ZIPに固めてAWSにアップロード)

ビルドとデプロイの手間が増える分、型安全に書けるのがC#の強みです。入出力をクラスで定義できるため、大規模なLambdaになるほど恩恵を感じます。


必要なツールを準備する

3つのツールを用意します。

  1. .NET SDK 8以上公式サイトからインストール
  2. Amazon.Lambda.Toolsdotnet lambda deploy-function などのコマンドを使えるようにするCLI拡張
  3. Amazon.Lambda.TestTool — ローカルでLambdaを動かすためのツール

2と3はターミナルからインストールします。

# Lambda CLIツール
dotnet tool install -g Amazon.Lambda.Tools

# ローカルテストツール(.NETのバージョンに合わせる)
dotnet tool install -g Amazon.Lambda.TestTool-10.0

AWS CLIも必要です。認証情報(アクセスキー・リージョン)があらかじめ設定されていることを確認してください。


プロジェクトを作成する

Lambda用のプロジェクトテンプレートをインストールして、空のLambda関数を生成します。

# テンプレートをインストール(初回のみ)
dotnet new install Amazon.Lambda.Templates

# プロジェクトを作成
dotnet new lambda.EmptyFunction -n MyFirstLambda

生成されるファイルは3つです。

ファイル役割
Function.csハンドラーの実装
MyFirstLambda.csprojプロジェクト設定
aws-lambda-tools-defaults.jsonデプロイ設定

aws-lambda-tools-defaults.json はPythonにはない概念です。デプロイ時のリージョン・メモリサイズ・ハンドラー文字列などを書いておくことで、毎回オプションを指定せずに dotnet lambda deploy-function を実行できます。


C#のお作法:ハンドラーの書き方

クラスの中にメソッドを書く

C#はすべてのメソッドをクラスの中に書く必要があります。Pythonのように関数だけ書いてもコンパイルエラーになります。

using Amazon.Lambda.Core;

// JSONの読み書き方法をLambdaに伝えるおまじない(必須)
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace MyFirstLambda;

public class Function
{
    // ここがハンドラー(Pythonのlambda_handlerに相当)
    public string FunctionHandler(string input, ILambdaContext context)
    {
        context.Logger.LogInformation($"受け取った値: {input}");
        return input.ToUpper();
    }
}

[assembly: LambdaSerializer(...)] はファイルの先頭に1回書くだけでOKです。これがないとJSONのデシリアライズが動かないため、必ず入れます。

ILambdaContext はCloudWatch Logsへの書き込みやタイムアウト残り時間の確認に使います。不要なら引数から省略できます。

入出力をクラスで定義する

Pythonのdictに相当するのが、C#では専用クラスです。入力と出力をそれぞれクラスで定義すると、タイポがコンパイル時に検出され、IDEの補完も効くようになります。

// 入力クラス
public class GreetRequest
{
    public string Name { get; set; } = "";
    public int Age { get; set; }
}

// 出力クラス
public class GreetResponse
{
    public string Message { get; set; } = "";
    public bool IsAdult { get; set; }
}

public class Function
{
    public GreetResponse FunctionHandler(GreetRequest input, ILambdaContext context)
    {
        return new GreetResponse
        {
            Message = $"こんにちは、{input.Name}さん!",
            IsAdult = input.Age >= 18
        };
    }
}

このコードに対して { "name": "太郎", "age": 30 } を渡すと、{ "Message": "こんにちは、太郎さん!", "IsAdult": true } が返ります。LambdaSerializerがJSONとクラスの変換を自動でやってくれます。


ローカルでテストする

Lambda TestToolを使います。まずテスト用のペイロードをJSONファイルで用意します。

{ "name": "太郎", "age": 30 }

これを payload.json として保存し、ビルド後に実行します。

# ビルド
dotnet build

# ローカルテスト
dotnet lambda-test-tool-10.0 --no-ui --payload payload.json

実行結果はターミナルに表示されます。

Captured Log information:
  ...

Response:
{"Message":"こんにちは、太郎さん!","IsAdult":true}

Response: の行が実際のLambdaレスポンスです。CloudWatch Logsに出力される内容は Captured Log information: の下に表示されます。


AWSにデプロイする

デプロイ前の設定

aws-lambda-tools-defaults.json にリージョン・関数名・IAMロールを追記します。

{
  "profile": "default",
  "region": "ap-northeast-1",
  "configuration": "Release",
  "function-runtime": "dotnet10",
  "function-memory-size": 512,
  "function-timeout": 30,
  "function-handler": "MyFirstLambda::MyFirstLambda.Function::FunctionHandler",
  "function-name": "MyFirstLambda",
  "function-role": "arn:aws:iam::xxxxxxxxxxxx:role/LambdaExecutionRole"
}

function-role にはCloudWatch Logsへの書き込み権限(AWSLambdaBasicExecutionRole)を持つIAMロールのARNを指定します。

デプロイ実行

dotnet lambda deploy-function

このコマンド1つで、ビルド → linux-x64向けにパブリッシュ → ZIP化 → AWSにアップロード → Lambda関数を作成/更新 まで自動で行われます。

関数の更新も同じコマンドで完了します。Pythonのようにコンソールでコードを直接編集することはできないので、コードを変えたら必ずこの手順を踏みます。


まとめ

PythonとC# Lambdaの違いを対比するとこうなります。

PythonC#
コンソールでコード編集✅ できる❌ できない
ビルドステップ不要必要(dotnet build
ローカルテストSAM CLI などLambda TestTool
デプロイコマンドaws lambda update-function-code などdotnet lambda deploy-function
入出力の定義dictクラス
型安全弱い強い(コンパイル時にエラー検出)

C#はセットアップの手間こそありますが、一度流れをつかめば開発サイクルはシンプルです。型安全に書けるため、複雑なビジネスロジックを持つLambdaほどC#の強みが活きます。


参考資料

コメント

タイトルとURLをコピーしました