本文へスキップ
.NET Aspireで実現するクラウドネイティブ開発の実践ガイドのアイキャッチ画像
Architecture

.NET Aspireで実現するクラウドネイティブ開発の実践ガイド

公開: 更新: 約9分で読めます

複数のサービスとデータストアが連携する分散アプリケーションでは、ローカル開発環境の構築、サービス間の接続設定、可観測性の確保といった周辺作業が開発全体の負担になりがちです。.NET Aspire は、こうした「アプリケーションそのものではない部分」を .NET のコードとして一貫して記述できるようにする、クラウドネイティブ開発向けのスタックです。すでに GA を迎え、リリースごとに機能が加わり続けています。本稿では AppHost によるオーケストレーションから Integrations、Service Defaults、開発時ダッシュボード、そして Azure Container Apps や Kubernetes へのデプロイまで、実務で押さえておきたい構成要素を順に整理します。

.NET Aspire が解決する範囲

.NET Aspire は、単体のフレームワークというより、分散アプリケーションを構築・運用するための複数の要素を束ねたスタックとして設計されています。中心にあるのは、アプリを構成する要素をコードで宣言し、ローカルでも本番でも同じ定義から扱えるという考え方です。

従来、開発チームは Docker Compose のファイル、接続文字列を並べた環境変数、サービスディスカバリの仕組み、ログとメトリクスの収集設定を、それぞれ別の道具で管理してきました。.NET Aspire はこれらを .NET のプロジェクトと C# のコードに集約します。結果として、構成の意図がコードとして残り、レビューや差分管理の対象になります。

対象となるのは、Web API とフロントエンド、キャッシュやデータベース、メッセージング、外部のクラウドサービスといった複数のリソースが絡み合うアプリケーションです。単一プロセスの小さなアプリでは恩恵は限定的ですが、要素が増えるほど、構成を一元管理できる価値が大きくなります。

.NET Aspire の AppHost が Web フロントエンド、Catalog API、Redis、PostgreSQL を束ね、Service Defaults がヘルスチェック・回復性・OpenTelemetry を各サービスに提供し、ダッシュボードでトレース・メトリクス・ログを確認し、マニフェストから Azure Container Apps と Kubernetes へデプロイする構成を示した図
AppHost がプロジェクトとコンテナを束ね、Service Defaults と可観測性を共通化してデプロイまでつなぐ .NET Aspire の全体像

AppHost によるオーケストレーション

.NET Aspire の起点となるのが AppHost プロジェクトです。AppHost は、アプリケーションを構成する .NET プロジェクト、コンテナ、実行可能ファイルを一つの定義として束ね、それらの起動順序と依存関係を管理します。ソリューション内での「指揮者」にあたる役割です。

次の例では、Redis と PostgreSQL のコンテナを定義し、API プロジェクトがそれらを参照する形で依存関係を宣言しています。

var builder = DistributedApplication.CreateBuilder(args);

// キャッシュ用の Redis コンテナ
var cache = builder.AddRedis("cache");

// PostgreSQL コンテナと、その上に作成するデータベース
var postgres = builder.AddPostgres("postgres");
var catalogDb = postgres.AddDatabase("catalogdb");

// API プロジェクト。cache と catalogDb を参照する
var api = builder.AddProject<Projects.Catalog_Api>("catalog-api")
    .WithReference(cache)
    .WithReference(catalogDb)
    .WaitFor(catalogDb);

// Web フロントエンド。API を参照する
builder.AddProject<Projects.Web_Frontend>("web")
    .WithReference(api)
    .WithExternalHttpEndpoints();

builder.Build().Run();

WithReference は、参照先のリソースへの接続情報を参照元へ引き渡します。Redis なら接続文字列、PostgreSQL ならデータベースへの接続情報が、環境変数として自動的に注入されます。開発者が手作業でポートや接続文字列を管理する必要はありません。WaitFor は依存先の起動完了を待ってから対象を立ち上げる指定で、データベースが準備できる前に API が起動して失敗する、といった状況を避けられます。

AppHost はプロジェクトだけでなく、任意のコンテナイメージや実行可能ファイルも同じ枠組みで扱えます。Node.js で書かれたフロントエンドや、既製のコンテナとして提供されるミドルウェアも、同一の定義の中に組み込めるため、.NET 以外の要素を含む構成でも一貫して管理できます。

Integrations でリソースを組み込む

以前 Components と呼ばれていた仕組みは、現在 Integrations という名称に整理されています。Integrations は、Redis、PostgreSQL、RabbitMQ、Azure の各種サービスといった外部リソースを、.NET Aspire の流儀で組み込むための NuGet パッケージ群です。

Integrations は二つの側面を持ちます。一つは AppHost 側で使うホスティング用のパッケージで、先ほどの AddRedis や AddPostgres がこれにあたります。もう一つは、リソースを利用する各サービス側で使うクライアント用のパッケージです。クライアント側は、接続の確立に加えて、ヘルスチェック、再試行などの回復性、ログとトレースの計装をあらかじめ組み込んだ状態で提供されます。

たとえば Redis を利用する API プロジェクトでは、次のように登録します。

var builder = WebApplication.CreateBuilder(args);

// Aspire の Redis クライアント統合を登録する
// 接続文字列は AppHost から注入された "cache" を参照
builder.AddRedisClient("cache");

var app = builder.Build();

登録するだけで、接続設定、ヘルスチェックへの組み込み、OpenTelemetry による計装がまとめて有効になります。個々のライブラリごとに計装や回復性を手で設定していた作業が、Integration の登録に置き換わります。Azure 向けの Integrations では、Blob Storage や Service Bus、Cosmos DB といったマネージドサービスを同様の形で扱え、開発時はエミュレータやコンテナ、本番では実サービスへと接続先を切り替えられます。

Service Defaults で共通設定を束ねる

分散アプリケーションでは、すべてのサービスに共通して持たせたい設定があります。ヘルスチェックのエンドポイント、HTTP クライアントの回復性、OpenTelemetry による計装、サービスディスカバリの有効化などです。.NET Aspire のテンプレートは、これらをまとめた ServiceDefaults というプロジェクトを生成します。

ServiceDefaults は、各サービスから参照される共有プロジェクトで、拡張メソッドとして共通設定を提供します。個々のサービスでは一行呼び出すだけで、標準の構成が適用されます。

var builder = WebApplication.CreateBuilder(args);

// ヘルスチェック、回復性、OpenTelemetry、
// サービスディスカバリをまとめて適用する
builder.AddServiceDefaults();

builder.Services.AddControllers();

var app = builder.Build();

// /health と /alive のヘルスチェックエンドポイントを公開する
app.MapDefaultEndpoints();

AddServiceDefaults の中身は生成されたコードとして手元に残るため、組織の方針に合わせて計装対象やヘルスチェックの内容を調整できます。共通の関心事を一箇所に集約しておくことで、サービスが増えても計装や回復性の設定にばらつきが出にくくなります。

OpenTelemetry を標準で組み込む点は特に重要です。トレース、メトリクス、ログが最初から統一された形で出力されるため、後から可観測性を追加する場合に比べて、計装の抜けや不整合が起きにくくなります。出力先も、開発時のダッシュボードから本番の監視基盤まで、OpenTelemetry の標準に沿って切り替えられます。

サービスディスカバリと開発時ダッシュボード

複数のサービスが相互に通信する場合、通信先のアドレスをどう解決するかが課題になります。.NET Aspire は名前ベースのサービスディスカバリを提供し、AppHost で宣言した論理名を使ってサービスを呼び出せます。呼び出し側は、実際のホストやポートを意識せず、https://catalog-api のような論理名を用いた HttpClient の呼び出しを書くだけで済みます。名前から実アドレスへの解決は、環境に応じて自動的に行われます。

開発時の可観測性を担うのがダッシュボードです。AppHost を起動すると、ブラウザで開けるダッシュボードが立ち上がり、次の情報を一つの画面で確認できます。

  • リソース一覧 — 各プロジェクトやコンテナの起動状態、エンドポイント、環境変数を把握できる
  • 構造化ログ — 全サービスのログを横断して閲覧し、絞り込みできる
  • 分散トレース — リクエストがどのサービスを経由したかを時系列で追跡できる
  • メトリクス — 各サービスの処理件数や応答時間などを可視化できる

これらは OpenTelemetry を通じて収集されるため、コードに監視用の特別な処理を書き加える必要はありません。分散システムで問題が起きた際、どのサービスのどの処理で時間がかかっているか、どこでエラーが発生したかを、開発中から追跡できます。ダッシュボードは AppHost とは独立したコンテナとしても提供されており、Aspire 以外の構成で OpenTelemetry の出力先として利用することもできます。

マニフェスト生成とデプロイ

ローカルで組み上げた構成を本番へ運ぶ際、.NET Aspire は AppHost の定義をマニフェストとして出力します。マニフェストは、アプリを構成するリソースとその関係を記述した中間表現で、これを各デプロイ先向けの成果物へ変換します。

Azure へのデプロイでは、Azure Developer CLI(azd)との連携が用意されています。azd は AppHost のマニフェストを解釈し、Azure Container Apps 向けのインフラ定義を生成してプロビジョニングとデプロイまでを担います。基本的な流れは、プロジェクトの初期化、インフラのプロビジョニング、アプリのデプロイという手順に整理されます。

// azd の基本的な操作の流れ(コマンドライン)
//
// azd init      … AppHost を検出し、azd 構成を生成する
// azd provision … Azure 上にリソースを作成する
// azd deploy    … コンテナをビルドしてデプロイする
// azd up        … provision と deploy をまとめて実行する

Container Apps 以外では、Kubernetes を対象にすることもできます。マニフェストから Kubernetes 向けの成果物を生成するツールが提供されており、既存のクラスタ運用に組み込めます。いずれの場合も、AppHost で宣言した依存関係と接続情報がデプロイ先の設定へと引き継がれるため、ローカルと本番で構成の考え方を揃えられます。デプロイ時の接続文字列やシークレットは、環境変数に平文で置くのではなく、マネージド ID やシークレットストアと連携する形へ切り替えるのが実務上の基本方針です。

導入にあたっての考え方

既存のマイクロサービス群を .NET Aspire へ移行する場合、一度にすべてを置き換えるのではなく、段階的に進めるのが現実的です。まず AppHost プロジェクトを追加し、既存のサービスをプロジェクト参照として取り込みます。次に、データストアやキャッシュを Integrations に置き換え、Service Defaults を適用して計装を揃えていきます。既存の運用を止めずに、構成管理と可観測性の恩恵を少しずつ取り込めます。

ローカル開発時のリソース消費には注意が必要です。すべてのサービスとコンテナを同時に起動すると、開発マシンのメモリを圧迫します。作業対象のサービスだけを起動する、コンテナの割り当てを調整するといった運用で、開発体験と負荷のバランスを取ります。導入初期は概念の把握に時間がかかりますが、公式テンプレートから小さな構成で始め、リソースを一つずつ増やしていく進め方が理解の助けになります。

エンハンスド株式会社では、.NET を用いたクラウドネイティブ開発の内製化を支援しています。.NET Aspire を軸にした開発基盤の設計、既存システムからの段階的な移行、可観測性とデプロイパイプラインの整備まで、チームの状況に合わせてご相談を承ります。分散アプリケーションの構成管理に課題をお持ちの際は、お気軽にお問い合わせください。

参考リンク

この記事をシェア

コピーしました

関連記事