Azure Developer CLI (azd) は、Aspire プロジェクトのデプロイをサポートするように拡張されました。 このガイドを使用して、AspireプロジェクトをAzure Container AppsにAzure Developer CLIを用いて作成および展開するプロセスを案内します。 このチュートリアルでは、次の概念について説明します。
-
azdとの統合がAspireプロジェクトでどのように機能するかを調べる -
AzureでAspireプロジェクトのリソースをプロビジョニングし
azdを使用してデプロイする -
azdを使用して Bicep インフラストラクチャとその他のテンプレート ファイルを生成する
[前提条件]
Aspireを使用するには、次のものがローカルにインストールされている必要があります。
-
.NET 8.0 または .NET 9.0。
- Aspire 9.4 以降では、.NET 10 Preview 5 以降がサポートされています。
- OCI 準拠のコンテナー ランタイム。次に例を示します。
- Docker デスクトップ または Podman. 詳細については、「コンテナー ランタイム」を参照してください。
- 次のような統合開発者環境 (IDE) またはコード エディター。
- Visual Studio 2022 バージョン 17.9 以降 (任意)
-
Visual Studio Code (任意)
- C# Dev Kit: 拡張 (オプション)
- jetBrains Rider と Aspire プラグイン (省略可能)
詳細については、Aspireセットアップとツール、および SDK のAspireに関する説明を参照してください。
Azure Developer CLIをローカルにインストールする必要もあります。 一般的なインストール オプションは次のとおりです。
統合のしくみ Azure Developer CLI
azd init ワークフローは、Aspire プロジェクトに対してカスタマイズされたサポートを提供します。 次の図は、このフローの概念的な動作と、 azd と Aspire の統合方法を示しています。
-
azdAspire プロジェクトをターゲットにすると、特殊なコマンド (dotnet run --project AppHost.csproj --output-path manifest.json --publisher manifest) を使用して AppHost が起動され、Aspiremanifest ファイルが生成されます。 - マニフェスト ファイルは、メモリ内でのみ Bicep ファイルを生成するために、
azd provisionサブコマンド ロジックによって尋問されます (既定)。 - Bicep ファイルを生成すると、前に指定したサブスクリプションとリソース グループを対象とする Azure の ARM API を使用してデプロイがトリガーされます。
- 基になるAzure リソースが構成されると、同じ
azd deployマニフェスト ファイルを使用するAspireサブコマンド ロジックが実行されます。 - デプロイ
azdの一環として、コンテナー イメージを生成するために、dotnet publishの組み込みのコンテナー発行サポートを使用して.NETを呼び出します。 - コンテナー イメージ
azdビルドされると、プロビジョニング フェーズ中に作成された ACR レジストリにプッシュされます。 - 最後に、コンテナー イメージが ACR に入ると、
azdは ARM を使用してリソースを更新し、コンテナー イメージの新しいバージョンの使用を開始します。
注
azdまた、生成された Bicep をプロジェクト内のinfra フォルダーに出力することもできます。詳細については、「アプリ モデルからの Bicep の生成」セクションAspire参照してください。
Aspire スターター アプリをプロビジョニングしてデプロイする
このセクションの手順では、Aspire開始アプリを作成し、Azureを使用してazdするアプリ リソースのプロビジョニングとデプロイを処理する方法について説明します。
Aspire スターター アプリを作成する
Aspire コマンドを使用して、新しいdotnet new プロジェクトを作成します。
Visual Studioを使用してプロジェクトを作成することもできます。
dotnet new aspire-starter --use-redis-cache -o AspireSample
cd AspireSample
dotnet run --project AspireSample.AppHost\AspireSample.AppHost.csproj
前のコマンドは、キャッシュへの依存関係を含むAspire テンプレートに基づいて新しいaspire-starter プロジェクトRedis作成します。
Aspire プロジェクトが実行され、すべてが正常に動作していることを確認します。
テンプレートを初期化する
新しいターミナルウィンドウを開き、
cdして、ソリューションのディレクトリに移動します。azd initコマンドを実行して、azdを使用してプロジェクトを初期化します。このコマンドにより、ローカル ディレクトリ構造が検査され、アプリの種類が決定されます。azd initコマンドの詳細については、azd init 参照してください。 が 3 つのアプリ初期化オプションを求められたら、
azd[現在のディレクトリのコードを使用する] を選択します。? How do you want to initialize your app? [Use arrows to move, type to filter] > Use code in the current directory Select a template Create a minimal projectディレクトリをスキャンした後、
azd正しい AspireAppHost プロジェクトが見つかったことを確認するメッセージが表示されます。 [確認] を選択し、アプリを初期化するオプションを続行します。Detected services: .NET (Aspire) Detected in: D:\source\repos\AspireSample\AspireSample.AppHost\AspireSample.AppHost.csproj azd will generate the files necessary to host your app on Azure using Azure Container Apps. ? Select an option [Use arrows to move, type to filter] > Confirm and continue initializing my app Cancel and exit環境名を入力します。これは、Azure でプロビジョニングされたリソースに名前を付け、
devやprodなどのさまざまな環境を管理するために使用します。Generating files to run your app on Azure: (✓) Done: Generating ./azure.yaml (✓) Done: Generating ./next-steps.md SUCCESS: Your app is ready for the cloud! You can provision and deploy your app to Azure by running the azd up command in this directory. For more information on configuring your app, see ./next-steps.md
azd は、多数のファイルを生成し、作業ディレクトリに配置します。 これらのファイルは次のとおりです。
- azure.yaml: AppHost プロジェクトなどのアプリのサービス Aspire について説明し、それらを Azure リソースにマップします。
-
.azure/config.json: 現在のアクティブな環境が何であるかを
azd通知する構成ファイル。 - .azure/aspireazddev/.env: 環境固有のオーバーライドが含まれています。
azure.yaml ファイルの内容は次のとおりです。
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
name: AspireSample
services:
app:
language: dotnet
project: .\AspireSample.AppHost\AspireSample.AppHost.csproj
host: containerapp
リソースの名前付け
新しい Azure リソースを作成するときは、名前付けの要件に従う必要があります。 Azure Container Appsの場合、名前の長さは 2 ~ 32 文字で、小文字、数字、ハイフンで構成されている必要があります。 名前は文字で始まり、英数字で終わる必要があります。
詳細については、Azure リソースの名前付け規則と制限を参照してください。
初期デプロイ
Aspire プロジェクトをデプロイするには、Azure AD に対して認証を行って、Azure リソース管理 API を呼び出します。
azd auth login前のコマンドは、ブラウザーを起動してコマンド ライン セッションを認証します。
認証が完了したら、 AppHost プロジェクト ディレクトリから次のコマンドを実行して、アプリケーションをプロビジョニングしてデプロイします。
azd upImportant
コンテナー イメージを Azure Container Registry (ACR) にプッシュするには、
Microsoft.Authorization/roleAssignments/writeアクセス権が必要です。 これは、レジストリで 管理者ユーザー を有効にすることで実現できます。 Azure ポータルを開き、ACR リソース/設定/アクセス キーに移動し、[管理者ユーザー] チェック ボックスをオンにします。 詳細については、「 管理者ユーザーを有効にする」を参照してください。メッセージが表示されたら、リソースのデプロイ先となるサブスクリプションと場所を選択します。 これらのオプションを選択すると、 Aspire プロジェクトが配置されます。
By default, a service can only be reached from inside the Azure Container Apps environment it is running in. Selecting a service here will also allow it to be reached from the Internet. ? Select which services to expose to the Internet webfrontend ? Select an Azure Subscription to use: 1. <YOUR SUBSCRIPTION> ? Select an Azure location to use: 1. <YOUR LOCATION> Packaging services (azd package) Provisioning Azure resources (azd provision) Provisioning Azure resources can take some time. Subscription: <YOUR SUBSCRIPTION> Location: <YOUR LOCATION> You can view detailed progress in the Azure Portal: <LINK TO DEPLOYMENT> (✓) Done: Resource group: <YOUR RESOURCE GROUP> (✓) Done: Container Registry: <ID> (✓) Done: Log Analytics workspace: <ID> (✓) Done: Container Apps Environment: <ID> SUCCESS: Your application was provisioned in Azure in 1 minute 13 seconds. You can view the resources created under the resource group <YOUR RESOURCE GROUP> in Azure Portal: <LINK TO RESOURCE GROUP OVERVIEW> Deploying services (azd deploy) (✓) Done: Deploying service apiservice - Endpoint: <YOUR UNIQUE apiservice APP>.azurecontainerapps.io/ (✓) Done: Deploying service webfrontend - Endpoint: <YOUR UNIQUE webfrontend APP>.azurecontainerapps.io/ Aspire Dashboard: <LINK TO DEPLOYED Aspire DASHBOARD> SUCCESS: Your up workflow to provision and deploy to Azure completed in 3 minutes 50 seconds.azdコマンドからの出力の最後の行は、デプロイされたすべてのAzure リソースを表示するAzure ポータルへのリンクです。
このアプリケーション内には、次の 3 つのコンテナーがデプロイされます。
-
webfrontend: スターター テンプレート内の Web プロジェクトのコードが含まれています。 -
apiservice: スターター テンプレートの API サービス プロジェクトのコードが含まれています。 -
cache: フロントエンドにキャッシュを提供する Redis コンテナー イメージ。
ローカル開発と同様に、接続文字列の構成は自動的に処理されます。 この場合、 azd はアプリケーション モデルを解釈し、適切なデプロイ手順に変換する役割を担いました。 たとえば、webfrontend キャッシュとRedisに接続する方法を認識できるように、apiservice コンテナーに挿入される接続文字列とサービス検出変数を考えてみましょう。
プロジェクトAspire接続文字列とサービス検出を処理する方法の詳細については、オーケストレーションの概要Aspire参照してください。
アプリケーションの更新プログラムをデプロイする
azd up コマンドが実行されると、基になるAzure リソースがプロビジョニングされ、コンテナー イメージがビルドされ、 プロジェクトをホストするコンテナー アプリにAspire。 通常、開発が進行中で、 Azure リソースがデプロイされると、コードが更新されるたびに Azure リソースをプロビジョニングする必要はありません。これは、開発者の内部ループに特に当てはまります。
コード変更のデプロイを高速化するために、 azd では、コンテナー イメージでのコード更新プログラムのデプロイがサポートされています。 これを行うには、 azd deploy コマンドを使用します。
azd deploy
Deploying services (azd deploy)
(✓) Done: Deploying service apiservice
- Endpoint: <YOUR UNIQUE apiservice APP>.azurecontainerapps.io/
(✓) Done: Deploying service webfrontend
- Endpoint: <YOUR UNIQUE webfrontend APP>.azurecontainerapps.io/
Aspire Dashboard: <LINK TO DEPLOYED Aspire DASHBOARD>
毎回すべてのサービスをデプロイする必要はありません。
azd は、 Aspire プロジェクト モデルを理解しているため、次のコマンドを使用して指定したサービスのいずれかをデプロイできます。
azd deploy webfrontend
詳細については、「 Azure Developer CLI リファレンス: azd deploy」を参照してください。
インフラストラクチャの更新プログラムをデプロイする
Aspire プロジェクト内の依存関係構造が変更されるたびに、azdは基になるAzure リソースを再プロビジョニングする必要があります。
azd provision コマンドは、これらの変更をインフラストラクチャに適用するために使用されます。
この動作を確認するには、AppHost プロジェクトの AppHost.cs ファイルを次のように更新します。
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
// Add the locations database.
var locationsdb = builder.AddPostgres("db").AddDatabase("locations");
// Add the locations database reference to the API service.
var apiservice = builder.AddProject<Projects.AspireSample_ApiService>("apiservice")
.WithReference(locationsdb);
builder.AddProject<Projects.AspireSample_Web>("webfrontend")
.WithReference(cache)
.WithReference(apiservice);
builder.Build().Run();
ファイルを保存し、次のコマンドを発行します。
azd provision
azd provision コマンドは、Postgres データベースをホストするコンテナー アプリを作成してインフラストラクチャを更新します。
azd provision コマンドは、apiservice コンテナーの接続文字列を更新しませんでした。 新しくプロビジョニングされた Postgres データベースを指すように接続文字列を更新するには、 azd deploy コマンドを再度呼び出す必要があります。 不明な場合は、 azd up を使用してプロビジョニングとデプロイの両方を行います。
リソースをクリーンアップする
このチュートリアルで作成した Azure リソースを必ずクリーンアップしてください。
azdはリソースを作成したリソース グループを認識しているため、次のコマンドを使用して環境をスピンダウンするために使用できます。
azd down
前のコマンドの実行には時間がかかる場合がありますが、完了したらリソース グループとそのすべてのリソースを削除する必要があります。
Deleting all resources and deployed code on Azure (azd down)
Local application code is not deleted when running 'azd down'.
Resource group(s) to be deleted:
• <YOUR RESOURCE GROUP>: <LINK TO RESOURCE GROUP OVERVIEW>
? Total resources to delete: 7, are you sure you want to continue? Yes
Deleting your resources can take some time.
(✓) Done: Deleting resource group: <YOUR RESOURCE GROUP>
SUCCESS: Your application was removed from Azure in 9 minutes 59 seconds.
プロジェクトモデルAspireからBicepを生成する
開発チームは、開発と運用の両方の目的で azd up (または azd provision と azd deploy) コマンドを展開に自由に使用できますが、一部のチームは、バージョン管理の一部としてレビューおよび管理できる Bicep ファイルを生成することを選択できます (これにより、これらの Bicep ファイルをより複雑な Azure 展開の一部として参照することもできます)。
生成されたインフラストラクチャを運用環境のシナリオに合わせてカスタマイズするための包括的なガイダンスについては、「AspireAzureデプロイのカスタマイズ」を参照してください。
azd には、次のコマンドを使用してプロビジョニングに使用する Bicep を出力する機能が含まれています。
azd config set alpha.infraSynth on
azd infra gen
このガイドで使用されているスターター テンプレートの例でこのコマンドを実行すると、 AppHost プロジェクト ディレクトリに次のファイルが作成されます。
- infra/main.bicep: デプロイのメイン エントリ ポイントを表します。
- infra/main.parameters.json: メイン Bicep のパラメーターとして使用されます ( .azure フォルダーで定義されている環境変数にマップされます)。
- infra/resources.bicep: Azure プロジェクト モデルをサポートするために必要なAspire リソースを定義します。
-
AspireSample.Web/manifests/containerApp.tmpl.yaml:
webfrontendのコンテナー アプリ定義。 -
AspireSample.ApiService/manifests/containerApp.tmpl.yaml:
apiserviceのコンテナー アプリ定義。
infra\resources.bicep ファイルには、コンテナー アプリ自体の定義は含まれません (RedisやPostgresなどの依存関係であるコンテナー アプリを除きます)。
@description('The location used for all deployed resources')
param location string = resourceGroup().location
@description('Tags that will be applied to all resources')
param tags object = {}
var resourceToken = uniqueString(resourceGroup().id)
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: 'mi-${resourceToken}'
location: location
tags: tags
}
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
name: replace('acr-${resourceToken}', '-', '')
location: location
sku: {
name: 'Basic'
}
tags: tags
}
resource caeMiRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(containerRegistry.id, managedIdentity.id, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d'))
scope: containerRegistry
properties: {
principalId: managedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
}
}
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
name: 'law-${resourceToken}'
location: location
properties: {
sku: {
name: 'PerGB2018'
}
}
tags: tags
}
resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' = {
name: 'cae-${resourceToken}'
location: location
properties: {
appLogsConfiguration: {
destination: 'log-analytics'
logAnalyticsConfiguration: {
customerId: logAnalyticsWorkspace.properties.customerId
sharedKey: logAnalyticsWorkspace.listKeys().primarySharedKey
}
}
}
tags: tags
}
resource cache 'Microsoft.App/containerApps@2023-05-02-preview' = {
name: 'cache'
location: location
properties: {
environmentId: containerAppEnvironment.id
configuration: {
service: {
type: 'redis'
}
}
template: {
containers: [
{
image: 'redis'
name: 'redis'
}
]
}
}
tags: union(tags, {'aspire-resource-name': 'cache'})
}
resource locations 'Microsoft.App/containerApps@2023-05-02-preview' = {
name: 'locations'
location: location
properties: {
environmentId: containerAppEnvironment.id
configuration: {
service: {
type: 'postgres'
}
}
template: {
containers: [
{
image: 'postgres'
name: 'postgres'
}
]
}
}
tags: union(tags, {'aspire-resource-name': 'locations'})
}
output MANAGED_IDENTITY_CLIENT_ID string = managedIdentity.properties.clientId
output AZURE_CONTAINER_REGISTRY_ENDPOINT string = containerRegistry.properties.loginServer
output AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID string = managedIdentity.id
output AZURE_CONTAINER_APPS_ENVIRONMENT_ID string = containerAppEnvironment.id
output AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN string = containerAppEnvironment.properties.defaultDomain
Bicep を使用してデプロイを自動化してAzureする方法の詳細については、「Bicep とは」を参照してください。
.NET サービス プロジェクトからのコンテナー アプリの定義は、各プロジェクトの ディレクトリの manifests ファイルにそれぞれ含まれています。
webfrontend プロジェクトの例を次に示します。
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: {{ .Env.SERVICE_WEBFRONTEND_IMAGE_NAME }}
name: webfrontend
env:
- name: AZURE_CLIENT_ID
value: {{ .Env.MANAGED_IDENTITY_CLIENT_ID }}
- name: ConnectionStrings__cache
value: {{ connectionString "cache" }}
- name: OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES
value: "true"
- name: OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES
value: "true"
- name: APISERVICE_HTTP
value: http://apiservice.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
- name: APISERVICE_HTTPS
value: https://apiservice.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
- name: services__apiservice__http__0
value: http://apiservice.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
- name: services__apiservice__https__0
value: https://apiservice.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
tags:
azd-service-name: webfrontend
aspire-resource-name: webfrontend
azd infra gen コマンドを実行した後、azd provisionとazd deployが呼び出されると、Bicep と生成されたファイルのサポートが使用されます。
Important
azd infra genが再度呼び出されると、変更されたファイルが新しく生成されたファイルに置き換えられ、その前に確認を求められます。
デバッグ用の分離された環境
azdを使用すると、新しい環境を簡単にプロビジョニングできるため、各チーム メンバーは、運用環境と密接に一致する設定でコードをデバッグするための分離されたクラウドホスト環境を持つことができます。 これを行う場合、各チーム メンバーは次のコマンドを使用して独自の環境を作成する必要があります。
azd env new
これにより、ユーザーはサブスクリプションとリソース グループの情報を再度入力するように求められます。その後の azd up、 azd provision、 azd deploy の呼び出しでは、既定でこの新しい環境が使用されます。
--environment スイッチをこれらのコマンドに適用して、環境を切り替えることができます。
リソースをクリーンアップする
作成した Azure リソースが不要になったら、次の Azure CLI コマンドを実行してリソース グループを削除します。 リソース グループを削除すると、その中に含まれるリソースも削除されます。
az group delete --name <your-resource-group-name>
詳細については、「リソースをクリーンアップする」をAzureで参照してください。
Aspire