次の方法で共有


AspireプロジェクトをAzure Container Appsにデプロイする [Azure Developer CLI (詳細ガイド) を使用して]

Azure Developer CLI (azd) は、Aspire プロジェクトのデプロイをサポートするように拡張されました。 このガイドを使用して、AspireプロジェクトをAzure Container AppsにAzure Developer CLIを用いて作成および展開するプロセスを案内します。 このチュートリアルでは、次の概念について説明します。

  • azdとの統合がAspireプロジェクトでどのように機能するかを調べる
  • AzureでAspireプロジェクトのリソースをプロビジョニングしazdを使用してデプロイする
  • azd を使用して Bicep インフラストラクチャとその他のテンプレート ファイルを生成する

[前提条件]

Aspireを使用するには、次のものがローカルにインストールされている必要があります。

詳細については、Aspireセットアップとツール、および SDK のAspireに関する説明を参照してください。

Azure Developer CLIをローカルにインストールする必要もあります。 一般的なインストール オプションは次のとおりです。

winget install microsoft.azd

統合のしくみ Azure Developer CLI

azd init ワークフローは、Aspire プロジェクトに対してカスタマイズされたサポートを提供します。 次の図は、このフローの概念的な動作と、 azd と Aspire の統合方法を示しています。

プロジェクトをデプロイするときの 'azd' の内部処理 Aspire 図。

  1. azd Aspire プロジェクトをターゲットにすると、特殊なコマンド (dotnet run --project AppHost.csproj --output-path manifest.json --publisher manifest) を使用して AppHost が起動され、Aspiremanifest ファイルが生成されます。
  2. マニフェスト ファイルは、メモリ内でのみ Bicep ファイルを生成するために、 azd provision サブコマンド ロジックによって尋問されます (既定)。
  3. Bicep ファイルを生成すると、前に指定したサブスクリプションとリソース グループを対象とする Azure の ARM API を使用してデプロイがトリガーされます。
  4. 基になるAzure リソースが構成されると、同じazd deploy マニフェスト ファイルを使用するAspireサブコマンド ロジックが実行されます。
  5. デプロイazdの一環として、コンテナー イメージを生成するために、dotnet publishの組み込みのコンテナー発行サポートを使用して.NETを呼び出します。
  6. コンテナー イメージ azd ビルドされると、プロビジョニング フェーズ中に作成された ACR レジストリにプッシュされます。
  7. 最後に、コンテナー イメージが 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 プロジェクトが実行され、すべてが正常に動作していることを確認します。

テンプレートを初期化する

  1. 新しいターミナルウィンドウを開き、cdして、ソリューションのディレクトリに移動します。

  2. azd init コマンドを実行して、azdを使用してプロジェクトを初期化します。このコマンドにより、ローカル ディレクトリ構造が検査され、アプリの種類が決定されます。

    azd init
    

    コマンドの詳細については、azd init参照してください。

  3. が 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
    
  4. ディレクトリをスキャンした後、 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
    
  5. 環境名を入力します。これは、Azure でプロビジョニングされたリソースに名前を付け、devprodなどのさまざまな環境を管理するために使用します。

    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 リソースの名前付け規則と制限を参照してください。

初期デプロイ

  1. Aspire プロジェクトをデプロイするには、Azure AD に対して認証を行って、Azure リソース管理 API を呼び出します。

    azd auth login
    

    前のコマンドは、ブラウザーを起動してコマンド ライン セッションを認証します。

  2. 認証が完了したら、 AppHost プロジェクト ディレクトリから次のコマンドを実行して、アプリケーションをプロビジョニングしてデプロイします。

    azd up
    

    Important

    コンテナー イメージを Azure Container Registry (ACR) にプッシュするには、 Microsoft.Authorization/roleAssignments/write アクセス権が必要です。 これは、レジストリで 管理者ユーザー を有効にすることで実現できます。 Azure ポータルを開き、ACR リソース/設定/アクセス キーに移動し、[管理者ユーザー] チェック ボックスをオンにします。 詳細については、「 管理者ユーザーを有効にする」を参照してください。

  3. メッセージが表示されたら、リソースのデプロイ先となるサブスクリプションと場所を選択します。 これらのオプションを選択すると、 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 ポータルへのリンクです。

    デプロイされたリソースを示す Azure ポータルのスクリーンショット。

このアプリケーション内には、次の 3 つのコンテナーがデプロイされます。

  • webfrontend: スターター テンプレート内の Web プロジェクトのコードが含まれています。
  • apiservice: スターター テンプレートの API サービス プロジェクトのコードが含まれています。
  • cache: フロントエンドにキャッシュを提供する Redis コンテナー イメージ。

ローカル開発と同様に、接続文字列の構成は自動的に処理されます。 この場合、 azd はアプリケーション モデルを解釈し、適切なデプロイ手順に変換する役割を担いました。 たとえば、webfrontend キャッシュとRedisに接続する方法を認識できるように、apiservice コンテナーに挿入される接続文字列とサービス検出変数を考えてみましょう。

Webfrontend コンテナー アプリの環境変数のスクリーンショット。

プロジェクト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 provisionazd 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 provisionazd deployが呼び出されると、Bicep と生成されたファイルのサポートが使用されます。

Important

azd infra genが再度呼び出されると、変更されたファイルが新しく生成されたファイルに置き換えられ、その前に確認を求められます。

デバッグ用の分離された環境

azdを使用すると、新しい環境を簡単にプロビジョニングできるため、各チーム メンバーは、運用環境と密接に一致する設定でコードをデバッグするための分離されたクラウドホスト環境を持つことができます。 これを行う場合、各チーム メンバーは次のコマンドを使用して独自の環境を作成する必要があります。

azd env new

これにより、ユーザーはサブスクリプションとリソース グループの情報を再度入力するように求められます。その後の azd upazd provisionazd deploy の呼び出しでは、既定でこの新しい環境が使用されます。 --environment スイッチをこれらのコマンドに適用して、環境を切り替えることができます。

リソースをクリーンアップする

作成した Azure リソースが不要になったら、次の Azure CLI コマンドを実行してリソース グループを削除します。 リソース グループを削除すると、その中に含まれるリソースも削除されます。

az group delete --name <your-resource-group-name>

詳細については、「リソースをクリーンアップする」をAzureで参照してください。