はじめに
この記事は .NET Aspire に関する一連の記事の一部です。
- .NET Aspire って何? - 概要
- .NET Aspire を使ってみる
- .NET Aspire をデプロイする
- .NET Aspire で Prometheus, Jaeger, Grafana を使う
- Next.js + ASP.NET Core を .NET Aspire で構成する(with YARP)
- .NET Aspire でデータベースを扱う - PostgreSQL編
- .NET Aspire でデータベースを扱う - SQL Server編
- .NET Aspire のダッシュボードを単独で使う
.NET Aspire + Dapr についてはこちらをご覧ください。メインは Dapr についてですが、.NET Aspire を使用する場合についても記載があります。
この記事は .NET Aspire で構築したアプリケーションを Azure Developer CLI を使って Azure Container Apps にデプロイする記事です。
開発環境
- Windows 11
- Visual Studio 2022 17.9.0 Preview 2.0
- Docker Desktop 4.26.1 (131620)
- Azure Developer CLI 1.5.2
.NET Aspire は VSCode でも扱うことができますが、本記事では Visual Studio 2022 Preview 版を使用します。
.NET Aspire 管理下のアプリをデプロイするとは
.NET Aspire はコンテナで稼働することを前提としています。そのため、各プロジェクトをコンテナ化してコンテナレジストリに Uploadしてから対象のリソースにデプロイする、という順番をとることになります。
次に .NET Aspire 管理下のシステムのうち、デプロイ対象となる箇所がどこなのかを理解しておく必要があります。サンプル構成をもう一度確認してみましょう。
これは .NET Aspire を使ってみる で構築した分散アプリケーションのプロジェクト構成図です。このうち、デプロイの対象となるのは次の赤枠で囲われた箇所になります。
手動で各プロジェクトをコンテナ化しなければならないわけですが、数が多くなるとちょっとうんざりですね。
Azure Developer CLI で Azure にデプロイする
幸いなことに Azure Developer CLI を使うと各プロジェクトのコンテナ化からデプロイ先の Azure リソースの作成、そしてイメージの Upload、デプロイまでを全て自動的にやってくれます。
もちろん Azure CLI などを使って1ずつ手作業で行った上でデプロイすることも可能です。その際には環境変数の設定などにも注意が必要です。
Deploy a .NET Aspire app to Azure Container Apps
Azure Developer CLI の方が圧倒的に便利です。ただし Azure Developer CLI を使う場合、2023/12現在では Azure Container Apps へのデプロイしかサポートされていません。 Kubernetes へのデプロイはコミュニティベース作成された Asipirate というツールによる Manifest 作成サポートはありますが、公式なものではないことに注意が必要です。
Aspirate は操作感が Terraform のようなコマンドで Kubernetes 用の Manifest を作成するツールのようです。詳しくはリンク先をご確認ください。
1. 既存プロジェクトを解析する
では Azure Developer CLI を使って Azure にデプロイしてみましょう。まずはソリューションのルートに移動します。
その後に次のコマンドを叩きます。
> azd init
現在のディレクトリを解析するのか、テンプレートからデプロイするのかを選択するように聞かれます。
「Use code in the current directory」を選びます。
AppHost プロジェクトが見つかることで、これは .NET Aspire 管理下のシステムであると認識されて
Azure Container Apps にデプロイするための Manifest を作ることが宣言されます。
「Confirm and continue initializing my app」を選択します。
次に外部公開(インターネット公開)するサービスを選択します。frontendに矢印を動かしてからスペースを押下すると選択状態になります。
最後に環境名をつけることを求められます。これは Azure Developer CLI の作成した Manifest で認識されるものです。今回は deploytest としました。
azure.yml と next-steps.md という2つのファイルが作成されたことがわかります。
実はこの2つ以外にも .azure というフォルダ作られていて、その中にいくつかファイルが作成されます。この中のあるファイルは azd init コマンドで入力と選択した値が格納されます。つまり、環境変数名(上で入力した deploytest)と、選択した外部公開するサービス名(上で選択した frontend)を保持しています。
azure.yaml ファイルを見てみる
生成された azure.yaml を見てみましょう。
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
name: BlazorApp1
services:
app:
language: dotnet
project: .\BlazorApp1.AppHost\BlazorApp1.AppHost.csproj
host: containerapp
このファイルには AppHost プロジェクトの場所が記載してあるだけです。てっきり ARMテンプレートや Bicep ファイルが生成されるのかと思いきや、記載してあるのはこれだけです。どういうことなのでしょうか。
next-steps.md ファイルを見てみる
戸惑いつつ、 next-steps.md ファイルを見てみましょう。中は4つのセクションに分かれています。
- Next Steps
- What was added
- Billing
- Troubleshooting
1.Next Steps
次に何をすればいいか、です。 azd up コマンドを叩くと、インフラが用意されてデプロイまでワンステップで実行してくれる、と書いてあります。そして、GitHub Action と Azure Pipelines 用の Starter Yaml ファイルの用意があることがわかりますね。
azd pipeline config -e を起動すると、デプロイ用パイプラインがAzureにセキュアに接続するための設定をする。と書いてあります。要するにサービスプリンシパルを生成して、シークレット情報をパイプラインにセットアップしてくれる訳です。本番や検証など複数のデプロイ先に応じて enveriontname で切り替えることができるわけです。
2. What was added
azure.yaml ファイルにインフラとアプリケーションの構成について記載してある、と書いてあるようです。でも azure.yaml には AppHost プロジェクトへの参照しか含まれていない、とも書いてあります。azd コマンドは必要なインフラを必要な時にメモリ内にコード生成して使用する、とのことです。だから ARM テンプレートも Bicep ファイルもなかったという訳なんですね。
もし azd コマンドが使用する構成を見たい、もしくは修正したいなら azd infra synth コマンドを叩けば次の2つのファイルを生成する、と書いてあります。
- infra/main.bicep
- infra/resources.bicep
さらに、アプリホストから参照されるプロジェクトリソースごとに、プロジェクト ファイルの階層に manifests という名前のディレクトリが作成され、その中に containerApp.tmpl.yaml ファイルが作成されます。との書いて書いてあります。そしてこのファイルには、Azure Container Apps 上でプロジェクトを実行するためのインフラストラクチャがコードとして含まれているそうです。
では実際にソリューションディレクトリでinf azd infra synth コマンドを叩いてみましょう。
> azc infra synth
この機能はまだアルファ版である、と警告が表示されて生成が完了します。
説明にあった通り、ソリューションファイルのあるフォルダに infra というフォルダが作成されていました。
infra フォルダを覗くと、ファイルは2つではなく3つできていました。
ファイルの中身を掲載すると無駄に長くなってしまいますのでやめておきますが、main.bicep でリソースグループを作成し、 resources.bicep を呼び出しています。resources.bicep の中を見てみると、 Azure Container Registry、 Log Analytics Workspace、Azure Container Environment、Redisコンテナを作成していることがわかります。
.NET アプリケーションについて見てみましょう。Blazor プロジェクトと WebAPI プロジェクトのフォルダを見てみると、説明にあった通り manifests フォルダが作成されています。
どちらの manifests フォルダにも containerApp.tmpl.yaml ファイルが1つだけ生成されています。Blazor アプリの方の中を見てみましょう。
location: {{ .Env.AZURE_LOCATION }}
identity:
type: UserAssigned
userAssignedIdentities:
? "{{ .Env.AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID }}"
: {}
properties:
environmentId: {{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_ID }}
configuration:
activeRevisionsMode: single
ingress:
external: true
targetPort: 8080
transport: http
allowInsecure: false
registries:
- server: {{ .Env.AZURE_CONTAINER_REGISTRY_ENDPOINT }}
identity: {{ .Env.AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID }}
template:
containers:
- image: {{ .Image }}
name: frontend
env:
- name: AZURE_CLIENT_ID
value: {{ .Env.MANAGED_IDENTITY_CLIENT_ID }}
- name: ConnectionStrings__cache
value: cache:6379
- name: OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES
value: "true"
- name: OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES
value: "true"
- name: services__backend__0
value: http://backend.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
- name: services__backend__1
value: https://backend.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
scale:
minReplicas: 1
tags:
azd-service-name: frontend
aspire-resource-name: frontend
Azure Container Apps にデプロイするためのマニフェストであることがわかります。環境変数で OpenTelemetry用の設定値が OTEL_ を接頭辞として設定されていたり、Redisコンテナへの接続文字列や、WebAPIである backend に接続するためのホスト名が設定されていることがわかります。
ここで改めて What was added を見てみましょう。下に Note として注意が記載されています。
インフラストラクチャをディスクに同期(保存)すると、AppHostプロジェクトに加えた変更はインフラストラクチャに反映されない、と書かれています。変更を反映するためには azd infra synth を再度実行することで、インフラストラクチャを再生成することができる、とのことなので注意しましょう。
3. Billing, 4. Troubleshooting
Billing は課金の話、トラブルシューティングは問題発生時の一般的な解決方法が雑に記載されています。
2. 既存プロジェクトを Azure にデプロイする
ソリューションファイルのある階層で azd up コマンドを叩きます。
azd up
サブスクリプションの選択画面になります。
リージョンを選択します。
しばらく待つと、最後に SUCCESS と表示されてコマンドが終了します。
Azure Portalからデプロイ結果を確認します。 rg- という接頭辞をつけた環境名のリソースグループが作成されて、その中に Azure Container Registry、Azure Container Envrionment, Azure Container Apps, Log Analytics Workspace, Managed ID が作成されていることがわかります。
frontend を開いてエンドポイントを開いてみます。ちゃんと出力キャッシュが効いていることが確認できるでしょう。
まとめ
Azure Developer CLI を使うと簡単に Azure Container Apps にデプロイできることがわかりました。また、生成された Markdown ファイルには、GitHub Action や Azure Pipelines を使った CI/CD のスターターファイル(yaml)も用意されていました。
Azure 以外にデプロイするシナリオはまだ Azure Developer CLI ではサポートされていません。もちろん手動でデプロイすることはできますが、OpenTelemtery や Service Discovery用の環境変数を自分で設定しなければなりません。
.NET Aspire はまだ Prevew です。これから少しずつ他のリソースへのデプロイもサポートされると思いますので期待したいですね。