Поделиться через


Развертывание проекта .NET Aspire для Azure Container Apps с помощью Azure Developer CLI (подробное руководство)

Azure Developer CLI (azd) было расширено для поддержки развертывания .NET.NET Aspire проектов. В этом руководстве описан процесс создания и развертывания проекта .NET Aspire для Azure Container Apps с помощью Azure Developer CLI. В этом руководстве вы узнаете о следующих понятиях:

  • Узнайте, как работает интеграция azd с проектами .NET.NET Aspire
  • Подготовка и развертывание ресурсов в Azure для проекта .NET Aspire с помощью azd
  • Создание инфраструктуры Bicep и других файлов шаблонов с помощью azd

Необходимые условия

Для работы с .NET.NET Aspireвам потребуется следующее, установленное на локальном уровне:

Дополнительные сведения см. в разделе программы установки и инструментов и пакета SDK.

Вам также потребуется установить Azure Developer CLIлокально. Ниже приведены распространенные параметры установки:

winget install microsoft.azd

Как работает интеграция Azure Developer CLI

Рабочий процесс azd init предоставляет настраиваемую поддержку для проектов .NET.NET Aspire. На следующей схеме показано, как этот поток работает концептуально и как интегрированы azd и .NET.NET Aspire.

иллюстрация внутренней обработки `azd` при развертывании проекта .NET.NET Aspire.

  1. Когда azd предназначен для проекта .NET.NET Aspire, он запускает AppHost с специальной командой (dotnet run --project AppHost.csproj --output-path manifest.json --publisher manifest), которая создает файл манифеста Aspire.
  2. Файл манифеста обрабатывается логикой подкоманды azd provision для создания файлов Bicep только в памяти (по умолчанию).
  3. После генерации файлов Bicep развертывание запускается с использованием API ARM Azure, нацеленных на ранее указанную подписку и группу ресурсов.
  4. После настройки базовых ресурсов Azure выполняется логика вложенных команд azd deploy, которая использует тот же файл манифеста Aspire.
  5. В рамках развертывания azd вызывает dotnet publish, используя встроенную поддержку .NETдля публикации контейнеров с целью создания образов контейнеров.
  6. После того как azd создаёт образы контейнеров, он отправляет их в реестр ACR, который был создан на этапе настройки.
  7. Наконец, после того как образ контейнера находится в ACR, azd обновляет ресурс с помощью ARM, чтобы начать использовать новую версию образа контейнера.

Заметка

azd также позволяет вывести созданный Bicep в папку infra в проекте, о которой можно узнать больше в разделе Создание Bicep из .NET.NET Aspire модель приложений.

Подготовка и развертывание начального приложения .NET.NET Aspire

В этом разделе показано, как создать начальное приложение .NET Aspire и выполнить подготовку и развертывание ресурсов приложения для Azure с помощью azd.

Создание начального приложения .NET.NET Aspire

Создайте проект .NET.NET Aspire с помощью команды dotnet new. Вы также можете создать проект с помощью Visual Studio.

dotnet new aspire-starter --use-redis-cache -o AspireSample
cd AspireSample
dotnet run --project AspireSample.AppHost\AspireSample.AppHost.csproj

Предыдущие команды создают новый проект .NET.NET Aspire на основе шаблона aspire-starter, который включает зависимость от кэша Redis. Он запускает проект .NET.NET Aspire, который проверяет, работает ли все правильно.

Инициализация шаблона

  1. Откройте новое окно терминала и выполните cd в каталоге проекта AppHost вашего решения .NET.NET Aspire.

  2. Выполните команду azd init, чтобы инициализировать проект с помощью azd, которая будет проверять структуру локального каталога и определять тип приложения.

    azd init
    

    Дополнительные сведения о команде 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
    
  4. После сканирования каталога azd предложит убедиться, что он нашел правильный проект .NET.NET 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 и управления различными окружениями, такими как 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 .NET 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. Чтобы развернуть проект .NET Aspire, выполните проверку подлинности в Azure AD для вызова API управления ресурсами Azure.

    azd auth login
    

    Предыдущая команда запустит браузер для проверки подлинности сеанса командной строки.

  2. После прохождения аутентификации выполните следующую команду из каталога проекта AppHost для подготовки и развертывания приложения.

    azd up
    

    Важный

    Чтобы отправить образы контейнеров в реестр контейнеров Azure (ACR), необходимо иметь доступ к Microsoft.Authorization/roleAssignments/write. Это можно сделать, включив пользователя администратора в реестре. Откройте портал Azure, перейдите к ресурсу ACR, затем в раздел Настройки / Ключи доступа, и установите флажок ("Пользователь-администратор"). Дополнительные сведения см. в разделе Включение администратора.

  3. При появлении запроса выберите подписку и местоположение, в которые должны быть развернуты ресурсы. После выбора этих параметров будет развернут проект .NET.NET 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 .NET ASPIRE DASHBOARD>
    
    SUCCESS: Your up workflow to provision and deploy to Azure completed in 3 minutes 50 seconds.
    

    Последняя строка выходных данных из команды azd — это ссылка на портал Azure, в которой отображаются все развернутые Azure ресурсы:

    снимок экрана портала Azure с развернутыми ресурсами.

В этом приложении развертываются три контейнера:

  • webfrontend: содержит код из веб-проекта в начальном шаблоне.
  • apiservice: содержит код из проекта службы API в начальном шаблоне.
  • cache: образ контейнера Redis для предоставления кэша интерфейсу.

Как и в локальной разработке, конфигурация строк подключения обрабатывается автоматически. В этом случае azd несет ответственность за интерпретацию модели приложения и перевод ее на соответствующие шаги развертывания. Например, рассмотрим строку подключения и переменные обнаружения служб, внедренные в контейнер webfrontend, чтобы он знал, как подключиться к кэшу Redis и apiservice.

Снимок экрана переменных среды в контейнерном приложении webfrontend.

Дополнительные сведения о том, как проекты .NET.NET Aspire обрабатывают строки подключения и обнаружение служб, см. в обзоре оркестрации .NET.NET Aspire.

Развертывание обновлений приложений

При выполнении команды azd up базовые ресурсы Azureподготовлены, а образ контейнера создается и развертывается в приложениях контейнеров, в которых размещается проект .NET.NET 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 .NET ASPIRE DASHBOARD>

Не обязательно развертывать все службы каждый раз. azd понимает модель проекта .NET.NET Aspire, можно развернуть только одну из служб, указанных с помощью следующей команды:

azd deploy webfrontend

Дополнительные сведения см. в Azure Developer CLI справочнике: azd deploy.

Развертывание обновлений инфраструктуры

При изменении структуры зависимостей в проекте .NET.NET Aspireazd необходимо повторно подготовить базовые ресурсы Azure. Команда azd provision используется для применения этих изменений к инфраструктуре.

Чтобы увидеть это в действии, обновите файл Program.cs в проекте AppHost следующим образом:

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.

Создать Bicep из модели проекта .NET.NET Aspire

Хотя команды разработчиков могут использовать команды azd up (или azd provision и azd deploy) для своих развертываний как в целях разработки, так и для рабочей среды, некоторые команды могут создавать файлы Bicep, которые они могут просматривать и управлять как часть управления версиями (это также позволяет ссылаться на эти файлы Bicep как часть более сложного развертывания Azure).

azd включает возможность вывода Bicep, используемого для развертывания с помощью следующей команды:

azd config set alpha.infraSynth on
azd infra synth

После выполнения этой команды в примере начального шаблона, используемого в этом руководстве, в каталоге проекта AppHost создаются следующие файлы:

  • infra/main.bicep: представляет основную точку входа для развертывания.
  • infra/main.parameters.json: используется в качестве параметров для main Bicep (сопоставляется с переменными среды, определенными в папке .azure).
  • infra/resources.bicep: определяет ресурсы Azure, необходимые для поддержки модели проекта .NET Aspire.
  • AspireSample.Web/manifests/containerApp.tmpl.yaml: определение приложения контейнера для webfrontend.
  • AspireSample.ApiService/manifests/containerApp.tmpl.yaml: определение приложения контейнера для apiservice.

Файл esources.bicep в инфракрасной\rне содержит определения самих приложений-контейнеров (за исключением приложений контейнеров, которые являются зависимостями, такими как и ):

@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 содержится в файлах containerApp/tmpl.yaml в каталоге 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: services__apiservice__0
        value: http://apiservice.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
      - name: services__apiservice__1
        value: https://apiservice.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
tags:
  azd-service-name: webfrontend
  aspire-resource-name: webfrontend

После выполнения команды azd infra synth при вызове azd provision и azd deploy они используют Bicep и поддерживают созданные файлы.

Важный

Если azd infra synth вызывается снова, он заменяет все измененные файлы новыми и запрашивает подтверждение перед этим.

Изолированные среды для отладки

Так как azd упрощает подготовку новых сред, каждый член команды может иметь изолированную облачную среду для отладки кода в параметре, который тесно соответствует рабочей среде. При этом каждый член команды должен создать собственную среду с помощью следующей команды:

azd env new

При этом пользователю будет предложено снова получить сведения о подписке и группе ресурсов, а затем azd up, azd provisionи azd deploy вызовы будут использовать эту новую среду по умолчанию. Параметр --environment можно применить к этим командам для переключения между средами.

Очистка ресурсов

Выполните следующую команду Azure CLI, чтобы удалить группу ресурсов, если вам больше не нужны созданные ресурсы Azure. При удалении группы ресурсов также удаляются ресурсы, содержащиеся в нем.

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

Дополнительные сведения см. в разделе Очистка ресурсов в Azure.