Развертывание проекта .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вам потребуется следующее, установленное на локальном уровне:
- .NET 8.0 или .NET 9.0
- Среда выполнения контейнера, совместимая с OCI, например:
- Docker Рабочий стол или Podman. Дополнительные сведения см. в среде выполнения контейнеров.
- Интегрированная среда разработки (IDE) или редактор кода, например:
- Visual Studio 2022 версии 17.9 или более поздней (необязательно)
-
Visual Studio Code (необязательно)
- C# Dev Kit: расширение (необязательно)
- JetBrains Rider с плагином .NET.NET Aspire (необязательно)
Дополнительные сведения см. в разделе
Вам также потребуется установить Azure Developer CLIлокально. Ниже приведены распространенные параметры установки:
Как работает интеграция Azure Developer CLI
Рабочий процесс azd init
предоставляет настраиваемую поддержку для проектов .NET.NET Aspire. На следующей схеме показано, как этот поток работает концептуально и как интегрированы azd
и .NET.NET Aspire.
- Когда
azd
предназначен для проекта .NET.NET Aspire, он запускает AppHost с специальной командой (dotnet run --project AppHost.csproj --output-path manifest.json --publisher manifest
), которая создает файл манифеста Aspire. - Файл манифеста обрабатывается логикой подкоманды
azd provision
для создания файлов Bicep только в памяти (по умолчанию). - После генерации файлов Bicep развертывание запускается с использованием API ARM Azure, нацеленных на ранее указанную подписку и группу ресурсов.
- После настройки базовых ресурсов Azure выполняется логика вложенных команд
azd deploy
, которая использует тот же файл манифеста Aspire. - В рамках развертывания
azd
вызываетdotnet publish
, используя встроенную поддержку .NETдля публикации контейнеров с целью создания образов контейнеров. - После того как
azd
создаёт образы контейнеров, он отправляет их в реестр ACR, который был создан на этапе настройки. - Наконец, после того как образ контейнера находится в 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, который проверяет, работает ли все правильно.
Инициализация шаблона
Откройте новое окно терминала и выполните
cd
в каталоге проекта AppHost вашего решения .NET.NET Aspire.Выполните команду
azd init
, чтобы инициализировать проект с помощьюazd
, которая будет проверять структуру локального каталога и определять тип приложения.azd init
Дополнительные сведения о команде
azd init
смотрите в разделе azd init.Выберите Использовать код в текущем каталоге, когда
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
После сканирования каталога
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
Введите имя среды, которое будет использоваться для именования подготовленных ресурсов в 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.
Начальное развертывание
Чтобы развернуть проект .NET Aspire, выполните проверку подлинности в Azure AD для вызова API управления ресурсами Azure.
azd auth login
Предыдущая команда запустит браузер для проверки подлинности сеанса командной строки.
После прохождения аутентификации выполните следующую команду из каталога проекта AppHost для подготовки и развертывания приложения.
azd up
Важный
Чтобы отправить образы контейнеров в реестр контейнеров Azure (ACR), необходимо иметь доступ к
Microsoft.Authorization/roleAssignments/write
. Это можно сделать, включив пользователя администратора в реестре. Откройте портал Azure, перейдите к ресурсу ACR, затем в раздел Настройки / Ключи доступа, и установите флажок ("Пользователь-администратор"). Дополнительные сведения см. в разделе Включение администратора.При появлении запроса выберите подписку и местоположение, в которые должны быть развернуты ресурсы. После выбора этих параметров будет развернут проект .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 ресурсы:
В этом приложении развертываются три контейнера:
-
webfrontend
: содержит код из веб-проекта в начальном шаблоне. -
apiservice
: содержит код из проекта службы API в начальном шаблоне. -
cache
: образ контейнера Redis для предоставления кэша интерфейсу.
Как и в локальной разработке, конфигурация строк подключения обрабатывается автоматически. В этом случае azd
несет ответственность за интерпретацию модели приложения и перевод ее на соответствующие шаги развертывания. Например, рассмотрим строку подключения и переменные обнаружения служб, внедренные в контейнер webfrontend
, чтобы он знал, как подключиться к кэшу Redis и apiservice
.
Дополнительные сведения о том, как проекты .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
После выполнения этой команды в примере начального шаблона, используемого в этом руководстве, в каталоге проекта
- 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 в
@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.
.NET Aspire