Amazon ECS + ASP​.NET Core でヘルスチェック用のミドルウェアコンポーネントを導入する

2023.01.02

いわさです。

先日 AWS Deploy Tool for .NET を使ってサンプルアプリケーションを ECS に対してデプロイしました。

前回は公式の手順に従って Controller 上に明示的にヘルスチェック用のメソッドを用意しました。
しかし、その後 ASP.NET Core ではヘルスチェック用のミドルウェアコンポーネントが利用出来ることを知りました。

ここでいうミドルウェアというのは ASP.NET Core のミドルウェアのことです。

今回こちらのヘルスチェック用のミドルウェアコンポーネントを導入してみました。
前回よりも少し Controller がスリムになるのと、オプションで色々とカスタマイズも出来ます。

ミドルウェアコンポーネントの追加

基本的な正常性チェック構成であれば実装方法は非常に簡単です。
Program.csへ以下のハイライトコードを追加するのみです。エンドポイントのパスはカスタマイズ可能です。

Program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddHealthChecks();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseAuthorization();

app.MapControllers();

app.MapHealthChecks("/");

app.Run();

先日の記事で記載させて頂いたとおり、ASPNETCORE_URLSが適切に設定されていれば外部からステータスチェックが可能になります。

データベース接続性を含むディープヘルスチェック

ヘルスチェックの実装には色々な方法があります。

今回利用するミドルウェアコンポーネントでは様々な機能を追加することで多様なヘルスチェックパターンに対応することが出来ます。
ここではその中のひとつとしてヘルスチェックにて RDS for PostgreSQL への接続性も正常性の判定に含めてみます。

実装のために以下の 2 つの NuGet パッケージの追加導入が必要です。

% dotnet add package AspNetCore.HealthChecks.NpgSql --version 6.0.2
  Determining projects to restore...
  Writing /var/folders/4d/nhd1bp3d161crsn900wjrprm0000gp/T/tmppZmQvQ.tmp
info : X.509 certificate chain validation will use the fallback certificate bundle at '/usr/local/share/dotnet/sdk/6.0.404/trustedroots/codesignctl.pem'.

:

log  : Restored /Users/iwasa.takahito/work/hoge0102ecs/hogeapi2/hogeapi2.csproj (in 1.52 sec).

先程実装したProgram.csのヘルスチェックコードにコンポーネントを追加し、データベースへの接続文字列を設定します。
ここではハードコーディングしてしまっていますが、実際には構成ファイルの接続文字列を取得して利用する形になると思います。(builder.Configuration.GetConnectionString("DefaultConnection")など)

Program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddHealthChecks()
    .AddNpgSql("Server=hoge0102db.cpnu1ipu63g7.ap-northeast-1.rds.amazonaws.com;Port=5432;Database=hogedb;User Id=hoge;Password=hoge;");

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseAuthorization();

app.MapControllers();

app.MapHealthChecks("/");

app.Run();

以下は RDS for PostgreSQL に正常に接続出来る状態でのヘルスチェックエンドポイントへ GET リクエストを送信した際の動作です。

% curl -i http://localhost:5206
HTTP/1.1 200 OK
Content-Type: text/plain
Date: Mon, 02 Jan 2023 07:21:44 GMT
Server: Kestrel
Cache-Control: no-store, no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Pragma: no-cache
Transfer-Encoding: chunked

Healthy

その後 RDS for PostgreSQL を停止すると以下のようにレスポンスが変わりました。

% curl -i http://localhost:5206
HTTP/1.1 503 Service Unavailable
Content-Type: text/plain
Date: Mon, 02 Jan 2023 07:23:17 GMT
Server: Kestrel
Cache-Control: no-store, no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Pragma: no-cache
Transfer-Encoding: chunked

Unhealthy

ディープヘルスチェックを実装するかはともかく、ヘルスチェック要件にあわせて柔軟にカスタマイズ出来るのはとても良いですね。

さいごに

本日は Amazon ECS + ASP.NET Core 環境で、ヘルスチェック用のミドルウェアコンポーネントを導入して ALB のヘルスチェックを通過させてみました。

デフォルトで実装する際にいちいちヘルスチェック用のエンドポイントを独自実装するのは効率が悪いと思っていたので今回のようにミドルウェアコンポーネントでカバー出来るものは積極的に導入したいですね。