Общие сведения об интеграции .NET AspireAzure
Azure является самой популярной облачной платформой для создания и развертывания .NET приложений. Пакет SDK Azure для .NET позволяет легко управлять и использовать службы Azure. .NET Aspire предоставляет набор интеграции с службами Azure, где можно добавлять новые ресурсы или подключаться к существующим. В этой статье подробно описаны некоторые распространенные аспекты всех интеграций Azure в .NET Aspire и которая поможет вам понять, как ими пользоваться.
Добавьте ресурсы Azure
Все .NET AspireAzure хостинг-интеграции предоставляют Azure ресурсы и по общепринятому соглашению добавляются с помощью AddAzure*
API. При добавлении данных ресурсов в хост приложения .NET Aspire, они выступают в качестве службы Azure. API AddAzure*
возвращает IResourceBuilder<T>, где T
является типом ресурса Azure. Эти интерфейсы IResourceBuilder<T>
(построителя) предоставляют гибкий API, который позволяет настроить базовый ресурс Azure в модели приложения. Существуют API-интерфейсы для добавления новых Azure ресурсов, маркировки ресурсов как существующих и настройки поведения ресурсов в различных контекстах выполнения.
Типичный интерфейс разработчика
Если узел приложения .NET Aspire содержит Azure ресурсы, и вы запускаете его локально (опыт типичного разработчика F5 или dotnet run
), Azure ресурсы подготавливаются в подписке Azure. Это позволяет вам, разработчику, проводить отладку локально в рамках хоста вашего приложения.
.NET .NET Aspire стремится свести к минимуму затраты, используя по умолчанию базовую или стандартнуюединицу складского учета (SKU) для своих интеграций Azure. Хотя эти разумные значения по умолчанию предоставляются, вы можете настроить ресурсы Azure в соответствии с вашими потребностями. Кроме того, некоторые интеграции поддерживают эмуляторы или контейнеров, которые полезны для локальной разработки, тестирования и отладки. По умолчанию при локальном запуске приложения ресурсы Azure используют фактическую службу Azure. Однако их можно настроить для использования локальных эмуляторов или контейнеров, избегая затрат, связанных с фактической службой Azure во время локальной разработки.
Локальные эмуляторы
Некоторые Azure службы можно эмулировать для локального запуска. В настоящее время .NET Aspire поддерживает следующие эмуляторы Azure:
Интеграция хостинга | Описание |
---|---|
Azure Cosmos DB | Вызовите AzureCosmosExtensions.RunAsEmulator на IResourceBuilder<AzureCosmosDBResource> , чтобы настроить ресурс Cosmos DB для эмуляции с использованием API NoSQL. |
Azure Event Hubs | Вызовите AzureEventHubsExtensions.RunAsEmulator на IResourceBuilder<AzureEventHubsResource> , чтобы настроить ресурс Центров событий в режиме эмуляции. |
Azure Service Bus | Вызовите AzureServiceBusExtensions.RunAsEmulator на IResourceBuilder<AzureServiceBusResource> , чтобы настроить ресурс служебной шины для эмуляции с помощью эмулятора служебной шины. |
Azure SignalR Service | Вызовите AzureSignalRExtensions.RunAsEmulator на IResourceBuilder<AzureSignalRResource> , чтобы настроить ресурс SignalR так, чтобы он эмулировался с помощью AzureSignalR эмулятора. |
Azure хранилище | Вызовите AzureStorageExtensions.RunAsEmulator на IResourceBuilder<AzureStorageResource> , чтобы настроить ресурс хранилища для того, чтобы он был эмулирован с помощью Azurite. |
Чтобы ресурсы Azure использовали локальные эмуляторы, выполните цепочку вызова метода RunAsEmulator
в построителе ресурсов Azure. Этот метод настраивает ресурс Azure для использования локального эмулятора вместо фактической службы Azure.
Важный
Вызов любого из доступных API RunAsEmulator
на построителе ресурсов Azure не оказывает воздействия на манифест публикации . При публикации приложения созданный файл Bicep отражает фактическую службу Azure, а не локальный эмулятор.
Локальные контейнеры
Некоторые Azure ресурсы можно заменить локально с помощью открытых или локальных контейнеров. Чтобы заменить ресурс Azure локально в контейнере, выполните цепочку вызова метода RunAsContainer
в построителе ресурсов Azure. Этот метод настраивает ресурс Azure для использования контейнерной версии службы для локальной разработки и тестирования, а не фактической службы Azure.
В настоящее время .NET Aspire поддерживает следующие службы Azure в виде контейнеров:
Интеграция хостинга | Подробности |
---|---|
Azure Cache for Redis | Вызовите AzureRedisExtensions.RunAsContainer на IResourceBuilder<AzureRedisCacheResource> , чтобы настроить его для локального запуска в контейнере на основе образа docker.io/library/redis . |
Azure PostgreSQL гибкий Server | Вызовите AzurePostgresExtensions.RunAsContainer в IResourceBuilder<AzurePostgresFlexibleServerResource> , чтобы настроить его для локального запуска в контейнере, используя образ docker.io/library/postgres . |
Azure SQL Server | Вызовите AzureSqlExtensions.RunAsContainer на IResourceBuilder<AzureSqlServerResource> , чтобы настроить его для локального запуска в контейнере на основе образа mcr.microsoft.com/mssql/server . |
Заметка
Как и эмуляторы, вызов RunAsContainer
в построителе ресурсов Azure не влияет на манифест публикации. При публикации приложения созданный файл Bicep отражает реальную службу Azure, а не локальный контейнер.
Общие сведения об API интеграции Azure
.NETсила.NET Aspireзаключается в его способности обеспечить удивительный внутренний цикл разработки для разработчиков. Интеграции Azure ничем не отличаются от других. Они предоставляют набор общих API и шаблонов, общих для всех Azure ресурсов. Эти API и шаблоны предназначены для упрощения работы с Azure ресурсами в согласованном режиме.
В предыдущем разделе контейнеров вы узнали, как выполнять службы Azure локально в контейнерах. Если вы знакомы с .NET.NET Aspire, вы можете задаться вопросом, чем отличается вызов AddAzureRedis("redis").RunAsContainer()
для получения локального контейнера docker.io/library/redis
от вызова AddRedis("redis")
, поскольку оба приводят к одному и тому же локальному контейнеру.
Ответ заключается в том, что при локальной работе нет никакой разницы. Однако при публикации вы получаете разные ресурсы:
интерфейс прикладного программирования (API) | Режим выполнения | Режим публикации |
---|---|---|
AddAzureRedis("redis").RunAsContainer() | Локальный контейнер Redis | Azure Cache for Redis |
AddRedis("redis") | Локальный контейнер Redis | Контейнерное приложение Azure с образом Redis |
То же самое верно для служб SQL и PostgreSQL:
интерфейс прикладного программирования (API) | Режим выполнения | Режим публикации |
---|---|---|
AddAzurePostgresFlexibleServer("postgres").RunAsContainer() | Локальный контейнер PostgreSQL | Azure PostgreSQL гибкие Server |
AddPostgres("postgres") | Локальный контейнер PostgreSQL | Контейнерное приложение Azure с образом контейнера PostgreSQL |
AddAzureSqlServer("sql").RunAsContainer() | Локальный контейнер SQL Server | Azure SQL Server |
AddSqlServer("sql") | Локальный контейнер SQL Server | Контейнерное приложение Azure с образом SQL Server |
Дополнительные сведения о различиях между режимами выполнения и публикации см. в .NET.NET Aspire узле приложения: контекст выполнения.
API для представления ресурсов Azure в разных режимах
Построитель распределенных приложений, часть узла приложения, использует шаблон построителя для AddAzure*
ресурсов в модели приложений. Разработчики могут настроить эти ресурсы и определить их поведение в разных контекстах выполнения.
Azure интеграции хостинга предоставляют API-интерфейсы, чтобы указать, как эти ресурсы должны быть "опубликованы" и "запущены".
При выполнении хоста приложения контекст выполнения используется для определения того, находится ли хост приложения в режиме Run или Publish. Принципы наименования этих API указывают на предполагаемое действие для ресурсов.
В следующей таблице приведены соглашения об именовании, используемые для обозначения ресурсов Azure.
Заметка
Не все API доступны во всех Azure ресурсах. Например, некоторые Azure ресурсы могут быть контейнеризованы или эмулированы, а другие не могут.
Дополнительные сведения о режимах выполнения см. в контексте выполнения.
Общие варианты использования API режима выполнения
Используйте RunAsExisting, если необходимо динамически взаимодействовать с существующим ресурсом во время выполнения без необходимости развертывать или обновлять его. Используйте PublishAsExisting при объявлении существующих ресурсов в рамках конфигурации развертывания, обеспечивая применение правильных областей и разрешений. Наконец, используйте AsExisting<T>(IResourceBuilder<T>, IResourceBuilder<ParameterResource>, IResourceBuilder<ParameterResource>) при объявлении существующих ресурсов в обеих конфигурациях с требованием параметризировать ссылки.
Вы можете запросить, помечен ли ресурс как существующий ресурс, вызвав метод расширения IsExisting(IResource) в IResource. Дополнительные сведения см. в статье Использование существующих ресурсов Azure.
Использование существующих ресурсов Azure
.NET Aspire предоставляет поддержку ссылки на существующие ресурсы Azure. Вы помечаете существующий ресурс с помощью API PublishAsExisting
, RunAsExisting
и AsExisting
. Эти API позволяют разработчикам ссылаться на уже развернутые ресурсы Azure, настраивать их и создавать соответствующие манифесты развертывания с помощью шаблонов Bicep.
Существующие ресурсы, на которые ссылаются эти API, можно улучшить с помощью назначений ролей и других настроек, доступных с .NET.NET Aspireинфраструктурой в качестве возможностей кода. Эти API ограничены Azure ресурсами, которые можно развертывать, используя шаблоны Bicep.
Настройка существующих ресурсов Azure для режима выполнения
Метод RunAsExisting используется при выполнении распределенного приложения в режиме выполнения. В этом режиме предполагается, что указанный Azure ресурс уже существует и интегрируется с ним во время выполнения без подготовки ресурса. Чтобы пометить ресурс Azure как существующий, вызовите метод RunAsExisting
в построителе ресурсов. Рассмотрим следующий пример:
var builder = DistributedApplication.CreateBuilder();
var existingServiceBusName = builder.AddParameter("existingServiceBusName");
var existingServiceBusResourceGroup = builder.AddParameter("existingServiceBusResourceGroup");
var serviceBus = builder.AddAzureServiceBus("messaging")
.RunAsExisting(existingServiceBusName, existingServiceBusResourceGroup);
serviceBus.AddServiceBusQueue("queue");
Предыдущий код:
- Создает новый экземпляр
builder
. - Добавляет параметр с именем
existingServiceBusName
в конструктор. - Добавляет ресурс Azure Service Bus с именем
messaging
в конструктор. - Вызывает метод
RunAsExisting
в построителе ресурсовserviceBus
, передав параметрexistingServiceBusName
. Кроме того, можно использовать перегрузку параметраstring
. - Добавляет очередь с именем
queue
в ресурсserviceBus
.
По умолчанию предполагается, что ссылка на параметр служебной шины находится в той же Azure группе ресурсов. Однако если она находится в другой группе ресурсов, можно явно передать группу ресурсов в качестве параметра, чтобы правильно указать соответствующую группу ресурсов.
Настройка существующих ресурсов Azure для режима публикации
Метод PublishAsExisting используется в режиме публикации, когда необходимо объявить и сделать ссылку на уже существующий ресурс Azure. Этот API упрощает создание манифестов и шаблонов, которые включают определения ресурсов, сопоставляющие их с существующими ресурсами в Bicep.
Чтобы пометить ресурс Azure как существующий в режиме публикации, вызовите метод PublishAsExisting
в построителе ресурсов. Рассмотрим следующий пример:
var builder = DistributedApplication.CreateBuilder();
var existingServiceBusName = builder.AddParameter("existingServiceBusName");
var existingServiceBusResourceGroup = builder.AddParameter("existingServiceBusResourceGroup");
var serviceBus = builder.AddAzureServiceBus("messaging")
.PublishAsExisting(existingServiceBusName, existingServiceBusResourceGroup);
serviceBus.AddServiceBusQueue("queue");
Предыдущий код:
- Создает новый экземпляр
builder
. - Добавляет параметр с именем
existingServiceBusName
в конструктор. - Добавляет ресурс Azure Service Bus с именем
messaging
в конструктор. - Вызывает метод
PublishAsExisting
в построителе ресурсовserviceBus
, передав параметрexistingServiceBusName
. Кроме того, можно использовать перегрузку параметраstring
. - Добавляет очередь с именем
queue
в ресурсserviceBus
.
После выполнения узла приложения в режиме публикации созданный файл манифеста будет включать параметр existingResourceName
, который можно использовать для ссылки на существующий ресурс Azure. Рассмотрим следующий созданный частичный фрагмент файла манифеста:
"messaging": {
"type": "azure.bicep.v0",
"connectionString": "{messaging.outputs.serviceBusEndpoint}",
"path": "messaging.module.bicep",
"params": {
"existingServiceBusName": "{existingServiceBusName.value}",
"principalType": "",
"principalId": ""
}
},
"queue": {
"type": "value.v0",
"connectionString": "{messaging.outputs.serviceBusEndpoint}"
}
Дополнительные сведения о файле манифеста см. в .NET.NET Aspire формате манифеста для разработчиков инструментов развертывания.
Кроме того, созданный шаблон Bicep включает параметр existingResourceName
, который можно использовать для ссылки на существующий ресурс Azure. Рассмотрим следующий сгенерированный шаблон Bicep:
@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location
param existingServiceBusName string
param principalType string
param principalId string
resource messaging 'Microsoft.ServiceBus/namespaces@2024-01-01' existing = {
name: existingServiceBusName
}
resource messaging_AzureServiceBusDataOwner 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(messaging.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419'))
properties: {
principalId: principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419')
principalType: principalType
}
scope: messaging
}
resource queue 'Microsoft.ServiceBus/namespaces/queues@2024-01-01' = {
name: 'queue'
parent: messaging
}
output serviceBusEndpoint string = messaging.properties.serviceBusEndpoint
Дополнительные сведения о созданных шаблонах Bicep см. в статье «Инфраструктура как код» и ознакомьтесь с другими API публикации .
Предупреждение
При взаимодействии с существующими ресурсами, требующими проверки подлинности, убедитесь, что стратегия проверки подлинности, настроенная в модели приложения .NET.NET Aspire, соответствует стратегии проверки подлинности, разрешенной существующим ресурсом. Например, невозможно использовать управляемое удостоверение для существующего ресурса AzurePostgreSQL, который не настроен для поддержки управляемого удостоверения. Аналогичным образом, если существующий ресурс AzureRedis отключил ключи доступа, невозможно использовать проверку подлинности ключа доступа.
Настройка существующих ресурсов Azure во всех режимах
Метод AsExisting<T>(IResourceBuilder<T>, IResourceBuilder<ParameterResource>, IResourceBuilder<ParameterResource>) используется при запуске распределенного приложения в режиме запуска или публикации. Так как метод AsExisting
работает в обоих сценариях, он поддерживает только параметризованную ссылку на имя ресурса или имя группы ресурсов. Этот подход помогает предотвратить использование одного и того же ресурса в средах тестирования и рабочей среды.
Чтобы пометить ресурс Azure как существующий, вызовите метод AsExisting
в построителе ресурсов. Рассмотрим следующий пример:
var builder = DistributedApplication.CreateBuilder();
var existingServiceBusName = builder.AddParameter("existingServiceBusName");
var existingServiceBusResourceGroup = builder.AddParameter("existingServiceBusResourceGroup");
var serviceBus = builder.AddAzureServiceBus("messaging")
.AsExisting(existingServiceBusName, existingServiceBusResourceGroup);
serviceBus.AddServiceBusQueue("queue");
Предыдущий код:
- Создает новый экземпляр
builder
. - Добавляет параметр с именем
existingServiceBusName
в конструктор. - Добавляет ресурс Azure Service Bus с именем
messaging
в конструктор. - Вызывает метод
AsExisting
в построителе ресурсовserviceBus
, передав параметрexistingServiceBusName
. - Добавляет очередь с именем
queue
в ресурсserviceBus
.
Добавьте существующие ресурсы Azure со строками подключения
.NET .NET Aspire предоставляет возможность подключаться к уже существующим ресурсам, включая Azure. Использование строк подключения полезно, когда у вас есть существующие Azure ресурсы, которые вы хотите использовать в приложении .NET Aspire. API AddConnectionString используется с контекстом выполнения узла приложения для условного добавления строки подключения в модель приложения.
Заметка
Строки подключения используются для представления широкого диапазона сведений о подключении, включая подключения к базе данных, брокеры сообщений, URI конечной точки и другие службы. В .NET.NET Aspire номенклатуре термин "строка подключения" используется для представления любой информации о подключении.
Рассмотрим следующий пример: в режиме публикации вы добавляете ресурс хранилища Azure, а в режиме выполнения вы добавляете строку подключения к существующему хранилищу Azure.
var builder = DistributedApplication.CreateBuilder(args);
var storage = builder.ExecutionContext.IsPublishMode
? builder.AddAzureStorage("storage")
: builder.AddConnectionString("storage");
builder.AddProject<Projects.Api>("api")
.WithReference(storage);
// After adding all resources, run the app...
Предыдущий код:
- Создает новый экземпляр
builder
. - Добавляет ресурс хранилища Azure с именем
storage
в режиме публикации. - Добавляет строку подключения к существующему хранилищу Azure с именем
storage
в режиме выполнения. - Добавляет проект с именем
api
в конструктор. - Проект
api
ссылается на ресурсstorage
независимо от режима.
В проекте API для потребления используется информация о строке подключения без информации о том, как она была настроена хостом приложения. В режиме публикации код добавляет новый ресурс хранилища ConnectionStrings__storage
(или ConnectionStrings:storage
). Эти значения конфигурации можно просмотреть при запуске приложения. Для получения дополнительной информации см. сведения о ресурсе.
В отличие от существующих ресурсов, смоделированных с использованием API AsExisting
первого класса ,, ресурсы, модели которых заданы в виде строк подключения, нельзя улучшить добавлением дополнительных назначений ролей или настройками инфраструктуры.
Опубликовать как контейнерное приложение Azure
.NET .NET Aspire позволяет публиковать базовые ресурсы как Azure Container Apps, бессерверную платформу, которая уменьшает необходимость в управлении инфраструктурой. Поддерживаемые типы ресурсов включают:
- ContainerResource: представляет указанный контейнер.
- ExecutableResource: представляет указанный исполняемый процесс.
- ProjectResource: представляет указанный проект .NET.
Чтобы опубликовать эти ресурсы, используйте следующие API:
- AzureContainerAppContainerExtensions.PublishAsAzureContainerApp<T>(IResourceBuilder<T>, Action<AzureResourceInfrastructure,ContainerApp>)
- AzureContainerAppExecutableExtensions.PublishAsAzureContainerApp<T>(IResourceBuilder<T>, Action<AzureResourceInfrastructure,ContainerApp>)
- AzureContainerAppProjectExtensions.PublishAsAzureContainerApp<T>(IResourceBuilder<T>, Action<AzureResourceInfrastructure,ContainerApp>)
Эти API настраивают ресурс для публикации в качестве контейнерного приложения Azure и автоматически вызывают AddAzureContainerAppsInfrastructure(IDistributedApplicationBuilder), чтобы добавить необходимую инфраструктуру и файлы Bicep в среду размещения вашего приложения. В качестве примера рассмотрим следующий код:
var builder = DistributedApplication.CreateBuilder();
var env = builder.AddParameter("env");
var api = builder.AddProject<Projects.AspireApi>("api")
.PublishAsAzureContainerApp<Projects.AspireApi>((infra, app) =>
{
app.Template.Containers[0].Value!.Env.Add(new ContainerAppEnvironmentVariable
{
Name = "Hello",
Value = env.AsProvisioningParameter(infra)
});
});
Предыдущий код:
- Создает новый экземпляр
builder
. - Добавляет параметр с именем
env
в конструктор. - Добавляет проект с именем
api
в конструктор. - Вызывает метод
PublishAsAzureContainerApp
в построителе ресурсовapi
, передав лямбда-выражение, которое настраивает инфраструктуру приложений контейнеров Azure, гдеinfra
является AzureResourceInfrastructure иapp
является ContainerApp.- Добавляет переменную среды с именем
Hello
в приложение контейнера с помощью параметраenv
. - Метод
AsProvisioningParameter
используется для обработкиenv
либо как нового ProvisioningParameter в инфраструктуре, либо для повторного использования существующего параметра Bicep, если параметр с таким же именем уже существует.
- Добавляет переменную среды с именем
Дополнительные сведения см. в разделах ContainerApp и AsProvisioningParameter.
Инфраструктура как код
Пакет SDK Azure для .NET предоставляет пакет NuGet 📦Azure.Provisioning и набор специализированных пакетов для настройки служб Azure. Эти библиотеки управления ресурсами Azure упрощают декларативное специфицирование инфраструктуры Azure непосредственно в .NET. Их API позволяют создавать объектно-ориентированную инфраструктуру в C#, что приводит к Bicep. Bicep — это предметно-ориентированный язык (DSL) для декларативного развертывания Azure ресурсов.
Хотя можно вручную подготовить ресурсы Azure, .NET Aspire упрощает процесс, предоставляя набор API для выражения Azure ресурсов. Эти API-интерфейсы доступны как методы расширения в хостинг-библиотеках .NET AspireAzure, расширяющих интерфейс IDistributedApplicationBuilder. При добавлении Azure ресурсов в хост приложения они неявно добавляют соответствующие функции обеспечения. Другими словами, вам не нужно напрямую вызывать API для настройки.
Поскольку модели .NET Aspire учитывают ресурсы Azure в рамках интеграций хостинга Azure, для предоставления этих ресурсов используется SDK Azure. Создаются файлы Bicep, которые содержат описание необходимых ресурсов Azure. Созданные файлы Bicep выводятся вместе с файлом манифеста при публикации приложения.
Существует несколько способов влияния на созданные файлы Bicep:
-
Azure: Настройка обеспечения:
- Настройка инфраструктуры: кастомизация инфраструктуры ресурсов Azure.
- Добавьте инфраструктуру Azure: вручную добавьте инфраструктуру Azure в хост вашего приложения.
-
Использовать пользовательские шаблоны Bicep:
- справочные файлы Bicep: добавьте ссылку на файл Bicep, находящийся на диске.
- Добавить инлайн-ссылку Bicep: добавьте встроенный шаблон Bicep.
Локальная настройка и Azure.Provisioning
Чтобы избежать объединения терминов и помочь разъяснить "подготовку", важно понимать разграничение между локальной подготовкой и Azure подготовкой:
Локальное обеспечение:
По умолчанию при вызове любого из API интеграции размещения Azure для добавления ресурсов Azure, автоматически вызывается API AddAzureProvisioning(IDistributedApplicationBuilder). Данный API регистрирует сервисы в контейнере внедрения зависимостей (DI), используемом для управления ресурсами Azure во время запуска хоста приложения. Эта концепция называется локальной подготовкой. Дополнительные сведения см. в локальном Azure обеспечении.
Azure.Provisioning
:Azure.Provisioning
относится к пакету NuGet и представляет собой набор библиотек, которые позволяют использовать C# для создания Bicep. Интеграции для размещения Azure в .NET Aspire используют эти библиотеки в фоновом режиме для генерации файлов Bicep, которые определяют ресурсы Azure, необходимые вам. Дополнительные сведения см. в разделеAzure.Provisioning
настройки.
кастомизация Azure.Provisioning
Все хостинг-интеграции .NET AspireAzure предоставляют различные ресурсы Azure, и все они являются подклассами типа AzureProvisioningResource, который наследует от AzureBicepResource. Это позволяет расширениям, ограниченным данным типом, использовать гибкий API для настройки инфраструктуры по вашему усмотрению. Хотя .NET.NET Aspire предоставляет значения по умолчанию, вы можете повлиять на созданный Bicep с помощью этих API.
Настройка инфраструктуры
Независимо от того, с каким ресурсом Azure вы работаете, для настройки базовой инфраструктуры вы вызываете метод расширения ConfigureInfrastructure. Этот метод позволяет настроить инфраструктуру ресурса Azure путем передачи делегата configure
типа Action<AzureResourceInfrastructure>
. Тип AzureResourceInfrastructure является подклассом Azure.Provisioning.Infrastructure. Этот тип предоставляет массивную область поверхности API для настройки базовой инфраструктуры ресурса Azure.
Рассмотрим следующий пример:
var sku = builder.AddParameter("storage-sku");
var storage = builder.AddAzureStorage("storage")
.ConfigureInfrastructure(infra =>
{
var resources = infra.GetProvisionableResources();
var storageAccount = resources.OfType<StorageAccount>().Single();
storageAccount.Sku = new StorageSku
{
Name = sku.AsProvisioningParameter(infra)
};
});
Предыдущий код:
- Добавляет параметр с именем
storage-sku
. - Добавляет хранилище Azure с помощью API AddAzureStorage с именем
storage
. - Состыковывает вызов
ConfigureInfrastructure
для кастомизации инфраструктуры хранилища Azure:- Возвращает предоставляемые ресурсы.
- Фильтрует до одного StorageAccount.
- Назначает параметр
storage-sku
свойству StorageAccount.Sku:- Новый экземпляр StorageSku имеет свое свойство
Name
, назначенное из результата API AsProvisioningParameter.
- Новый экземпляр StorageSku имеет свое свойство
Этот пример перенаправляет внешний параметр в инфраструктуру Azure хранилища, что приводит к созданию файла Bicep, отражающего требуемую конфигурацию.
Добавление инфраструктуры Azure
Не все службы Azure представлены в виде интеграций .NET Aspire. Хотя они могут быть предоставлены позже, вы по-прежнему можете предоставить службы, доступные в библиотеках Azure.Provisioning.*
. Представьте себе сценарий, в котором у вас есть рабочая служба, которая отвечает за управление реестром контейнеров Azure. Теперь представьте, что проект размещения приложения имеет зависимость от пакета NuGet 📦Azure.Provisioning.ContainerRegistry.
API AddAzureInfrastructure
можно использовать для добавления инфраструктуры реестра контейнеров Azure в хост приложения:
var acr = builder.AddAzureInfrastructure("acr", infra =>
{
var registry = new ContainerRegistryService("acr")
{
Sku = new()
{
Name = ContainerRegistrySkuName.Standard
},
};
infra.Add(registry);
var output = new ProvisioningOutput("registryName", typeof(string))
{
Value = registry.Name
};
infra.Add(output);
});
builder.AddProject<Projects.WorkerService>("worker")
.WithEnvironment(
"ACR_REGISTRY_NAME",
new BicepOutputReference("registryName", acr.Resource));
Предыдущий код:
- Вызывает AddAzureInfrastructure с именем
acr
. - Предоставляет возможность настройки делегата
configureInfrastructure
для инфраструктуры реестра контейнеров Azure.- Создает экземпляр ContainerRegistryService с именем
acr
и стандартным номером SKU. - Добавляет службу реестра контейнеров Azure в переменную
infra
. - Создает экземпляр ProvisioningOutput с именем
registryName
, типомstring
и значением, которое соответствует названию реестра контейнеров Azure. - Добавляет выходные данные в переменную
infra
.
- Создает экземпляр ContainerRegistryService с именем
- Добавляет проект с именем
worker
в конструктор. - Создает цепочку вызова WithEnvironment, чтобы задать переменную среды
ACR_REGISTRY_NAME
в проекте значению результатаregistryName
.
Функциональность демонстрирует, как добавить инфраструктуру Azure в хост-проект приложения, даже если служба Azure не представлена как интеграция .NET Aspire. Далее показано, как передавать выходные данные реестра контейнеров Azure в среду зависимого проекта.
Рассмотрим полученный файл Bicep:
@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location
resource acr 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
name: take('acr${uniqueString(resourceGroup().id)}', 50)
location: location
sku: {
name: 'Standard'
}
}
output registryName string = acr.name
Файл Bicep отражает нужную конфигурацию реестра контейнеров Azure, как определено API AddAzureInfrastructure
.
Используйте пользовательские шаблоны Bicep
При выборе Azure в качестве целевого поставщика облачных сервисов можно использовать Bicep для описания инфраструктуры в виде кода. Она направлена на резкое упрощение процесса разработки с более чистым синтаксисом и более эффективной поддержкой модульности и повторного использования кода.
Хотя .NET.NET Aspire предоставляет набор предварительно созданных шаблонов Bicep, могут возникнуть моменты, когда вы хотите настроить шаблоны или создать собственные. В этом разделе описываются понятия и соответствующие API, которые можно использовать для настройки шаблонов Bicep.
Важный
Этот раздел не предназначен для обучения Bicep, а скорее для предоставления рекомендаций по созданию пользовательских шаблонов Bicep для использования с .NET.NET Aspire.
В рамках истории развертывания Azure для .NET Aspire, Azure Developer CLI (azd
) обеспечивает понимание вашего проекта .NET Aspire и возможность его развертывания на Azure. Интерфейс командной строки azd
использует шаблоны Bicep для развертывания приложения в Azure.
Установка пакета Aspire.Hosting.Azure
Если вы хотите ссылаться на файлы Bicep, возможно, что вы не используете ни одну из интеграций хостинга Azure. В этом случае вы по-прежнему можете ссылаться на файлы Bicep, установив пакет Aspire.Hosting.Azure
. Этот пакет предоставляет необходимый API для обращения к файлам Bicep и настройки ресурсов Azure.
Совет
Если вы используете любую из интеграции размещения Azure, вам не нужно устанавливать пакет Aspire.Hosting.Azure
, так как это транзитивная зависимость.
Для использования любой из этих функций необходимо установить пакет NuGet 📦Aspire.Hosting.Azure:
dotnet add package Aspire.Hosting.Azure
Дополнительные сведения см. в статье dotnet add package или Управление зависимостями пакетов в .NET приложениях.
Что ожидать от примеров
Все примеры в этом разделе предполагают, что вы используете пространство имен Aspire.Hosting.Azure. Кроме того, в примерах предполагается, что у вас есть экземпляр IDistributedApplicationBuilder:
using Aspire.Hosting.Azure;
var builder = DistributedApplication.CreateBuilder(args);
// Examples go here...
builder.Build().Run();
По умолчанию при вызове любого из API-интерфейсов, связанных с Bicep, вызов также выполняется для AddAzureProvisioning, который добавляет поддержку создания ресурсов Azure динамически во время запуска приложения. Дополнительные сведения см. в разделе Локальная подготовка и Azure.Provisioning
.
Ссылки на файлы Bicep
Представьте, что у вас есть шаблон Bicep в файле с именем storage.bicep
, который подготавливает учетную запись хранения Azure:
param location string = resourceGroup().location
param storageAccountName string = 'toylaunch${uniqueString(resourceGroup().id)}'
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' = {
name: storageAccountName
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
properties: {
accessTier: 'Hot'
}
}
Чтобы добавить ссылку на файл Bicep на диске, вызовите метод AddBicepTemplate. Рассмотрим следующий пример:
builder.AddBicepTemplate(
name: "storage",
bicepFile: "../infra/storage.bicep");
Приведенный выше код добавляет ссылку на файл Bicep, расположенный в ../infra/storage.bicep
. Пути к файлам должны быть относительными к проекту хоста приложения. Эта ссылка приводит к добавлению AzureBicepResource в коллекцию ресурсов приложения с именем "storage"
, а API возвращает экземпляр IResourceBuilder<AzureBicepResource>
, который можно использовать для дальнейшей настройки ресурса.
Ссылка на Bicep в онлайн-коде
Хотя файл Bicep на диске является наиболее распространенным вариантом, вы также можете добавить встроенные шаблоны Bicep. Встроенные шаблоны могут быть полезными, если вы хотите определить шаблон в коде или при динамическом создании шаблона. Чтобы добавить встроенный шаблон Bicep, вызовите метод AddBicepTemplateString с шаблоном Bicep в качестве string
. Рассмотрим следующий пример:
builder.AddBicepTemplateString(
name: "ai",
bicepContent: """
@description('That name is the name of our application.')
param cognitiveServiceName string = 'CognitiveService-${uniqueString(resourceGroup().id)}'
@description('Location for all resources.')
param location string = resourceGroup().location
@allowed([
'S0'
])
param sku string = 'S0'
resource cognitiveService 'Microsoft.CognitiveServices/accounts@2021-10-01' = {
name: cognitiveServiceName
location: location
sku: {
name: sku
}
kind: 'CognitiveServices'
properties: {
apiProperties: {
statisticsEnabled: false
}
}
}
"""
);
В этом примере шаблон Bicep указывается в качестве встроенного string
и добавляется в коллекцию ресурсов приложения под именем "ai"
. В этом примере подготавливается ресурс Azure для ИИ.
Передача параметров в шаблоны Bicep
Bicep поддерживает прием параметров, которые можно использовать для настройки поведения шаблона. Чтобы передать параметры в шаблон Bicep из .NET.NET Aspire, используйте цепочку вызовов метода WithParameter, как показано в следующем примере:
var region = builder.AddParameter("region");
builder.AddBicepTemplate("storage", "../infra/storage.bicep")
.WithParameter("region", region)
.WithParameter("storageName", "app-storage")
.WithParameter("tags", ["latest","dev"]);
Предыдущий код:
- Добавляет параметр с именем
"region"
в экземплярbuilder
. - Добавляет ссылку на файл Bicep, расположенный в
../infra/storage.bicep
. - Передает параметр
"region"
шаблону Bicep, который обрабатывается с использованием стандартной процедуры разрешения параметров. - Передает параметр
шаблону Bicep с жестко заданным значением . - Выполняется передача параметра
"tags"
в шаблон Bicep в виде массива строк.
Дополнительные сведения см. в разделе Внешние параметры.
Известные параметры
.NET .NET Aspire предоставляет набор известных параметров, которые можно передать в шаблоны Bicep. Эти параметры используются для предоставления сведений о приложении и окружении шаблонам Bicep. Доступны следующие известные параметры:
Поле | Описание | Ценность |
---|---|---|
AzureBicepResource.KnownParameters.KeyVaultName | Название ресурса хранилища ключей, используемого для хранения секретных выходных данных. | "keyVaultName" |
AzureBicepResource.KnownParameters.Location | Расположение ресурса. Это необходимо для всех ресурсов. | "location" |
AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId | Идентификатор ресурса рабочей области Log Analytics. | "logAnalyticsWorkspaceId" |
AzureBicepResource.KnownParameters.PrincipalId | Основной идентификатор текущего пользователя или управляемой идентичности. | "principalId" |
AzureBicepResource.KnownParameters.PrincipalName | Основное имя текущего пользователя или управляемого системного удостоверения. | "principalName" |
AzureBicepResource.KnownParameters.PrincipalType | Основной тип текущего пользователя или управляемой идентификации. Либо User , либо ServicePrincipal . |
"principalType" |
Чтобы использовать известный параметр, передайте имя параметра в метод WithParameter, например WithParameter(AzureBicepResource.KnownParameters.KeyVaultName)
. Вы не передаете значения для известных параметров, так как .NET.NET Aspire обрабатывает их от вашего имени.
Рассмотрим пример, где вы хотите настроить веб-хук для Event Grid Azure. Вы можете определить шаблон Bicep следующим образом:
param topicName string
param webHookEndpoint string
param principalId string
param principalType string
param location string = resourceGroup().location
// The topic name must be unique because it's represented by a DNS entry.
// must be between 3-50 characters and contain only values a-z, A-Z, 0-9, and "-".
resource topic 'Microsoft.EventGrid/topics@2023-12-15-preview' = {
name: toLower(take('${topicName}${uniqueString(resourceGroup().id)}', 50))
location: location
resource eventSubscription 'eventSubscriptions' = {
name: 'customSub'
properties: {
destination: {
endpointType: 'WebHook'
properties: {
endpointUrl: webHookEndpoint
}
}
}
}
}
resource EventGridRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(topic.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7'))
scope: topic
properties: {
principalId: principalId
principalType: principalType
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7')
}
}
output endpoint string = topic.properties.endpoint
Этот шаблон Bicep определяет несколько параметров, включая topicName
, webHookEndpoint
, principalId
, principalType
и необязательный location
. Чтобы передать эти параметры в шаблон Bicep, можно использовать следующий фрагмент кода:
var webHookApi = builder.AddProject<Projects.WebHook_Api>("webhook-api");
var webHookEndpointExpression = ReferenceExpression.Create(
$"{webHookApi.GetEndpoint("https")}/hook");
builder.AddBicepTemplate("event-grid-webhook", "../infra/event-grid-webhook.bicep")
.WithParameter("topicName", "events")
.WithParameter(AzureBicepResource.KnownParameters.PrincipalId)
.WithParameter(AzureBicepResource.KnownParameters.PrincipalType)
.WithParameter("webHookEndpoint", () => webHookEndpointExpression);
- Проект
webHookApi
добавляется в качестве ссылки наbuilder
. - Параметру
topicName
передается заранее заданное значение имени. - Параметр
webHookEndpoint
передается как выражение, которое преобразуется в URL-адрес по ссылке на 'https'-конечную точку ссылки проектаapi
с маршрутом/hook
. - Параметры
principalId
иprincipalType
передаются как известные параметры.
Известные параметры основаны на соглашениях и не должны сопровождаться соответствующим значением при передаче с помощью API WithParameter
. Известные параметры упрощают некоторые распространенные функции, такие как назначения ролей, при добавлении в шаблоны Bicep, как это видно на предыдущем примере. Для отправки событий в указанную конечную точку через веб-перехватчик Event Grid требуются назначения ролей. Дополнительные сведения см. в разделе «Роль отправителя данных в сетке событий».
Получение выходных данных из ссылок Bicep
Помимо передачи параметров в шаблоны Bicep, вы также можете получить выходные данные из шаблонов Bicep. Рассмотрим следующий шаблон Bicep, так как он определяет output
с именем endpoint
:
param storageName string
param location string = resourceGroup().location
resource myStorageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
name: storageName
location: location
kind: 'StorageV2'
sku:{
name:'Standard_LRS'
tier: 'Standard'
}
properties: {
accessTier: 'Hot'
}
}
output endpoint string = myStorageAccount.properties.primaryEndpoints.blob
Bicep определяет выходные данные с именем endpoint
. Чтобы получить выходные данные из шаблона Bicep, вызовите метод GetOutput для экземпляра IResourceBuilder<AzureBicepResource>
, как показано в следующем фрагменте кода C#:
var storage = builder.AddBicepTemplate(
name: "storage",
bicepFile: "../infra/storage.bicep"
);
var endpoint = storage.GetOutput("endpoint");
В этом примере выходные данные из шаблона Bicep извлекаются и хранятся в переменной endpoint
. Как правило, вы передаете эти выходные данные в качестве переменной среды другому ресурсу, который использует его. Например, если у вас был проект ASP.NET Core минимального API, который зависит от этой конечной точки, можно передать выходные данные в качестве переменной среды в проект с помощью следующего фрагмента кода:
var storage = builder.AddBicepTemplate(
name: "storage",
bicepFile: "../infra/storage.bicep"
);
var endpoint = storage.GetOutput("endpoint");
var apiService = builder.AddProject<Projects.AspireSample_ApiService>(
name: "apiservice"
)
.WithEnvironment("STORAGE_ENDPOINT", endpoint);
Дополнительные сведения см. в результатах "Bicep".
Получите секретные выходные данные из ссылок Bicep
Важно избегать вывода секретов при работе с Bicep. Если выходные данные считаются секретом, то есть его не следует раскрывать в журналах или других местах, можно обращаться с ним соответствующим образом. Это можно сделать, сохраняя секрет в Azure Key Vault и ссылаясь на него в шаблоне Bicep. Интеграция .NET Aspire и Azure предоставляет шаблон для надежного хранения выходных данных из шаблона Bicep, позволяя ресурсам использовать параметр keyVaultName
для хранения секретов в Azure Key Vault.
Рассмотрим следующий шаблон Bicep в качестве примера, который помогает продемонстрировать эту концепцию защиты секретных выходных данных:
param databaseAccountName string
param keyVaultName string
param databases array = []
@description('Tags that will be applied to all resources')
param tags object = {}
param location string = resourceGroup().location
var resourceToken = uniqueString(resourceGroup().id)
resource cosmosDb 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' = {
name: replace('${databaseAccountName}-${resourceToken}', '-', '')
location: location
kind: 'GlobalDocumentDB'
tags: tags
properties: {
consistencyPolicy: { defaultConsistencyLevel: 'Session' }
locations: [
{
locationName: location
failoverPriority: 0
}
]
databaseAccountOfferType: 'Standard'
}
resource db 'sqlDatabases@2023-04-15' = [for name in databases: {
name: '${name}'
location: location
tags: tags
properties: {
resource: {
id: '${name}'
}
}
}]
}
var primaryMasterKey = cosmosDb.listKeys(cosmosDb.apiVersion).primaryMasterKey
resource vault 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
name: keyVaultName
resource secret 'secrets@2023-07-01' = {
name: 'connectionString'
properties: {
value: 'AccountEndpoint=${cosmosDb.properties.documentEndpoint};AccountKey=${primaryMasterKey}'
}
}
}
Предыдущий шаблон Bicep ожидает параметр keyVaultName
среди нескольких других параметров. Затем он создаёт ресурс Azure Cosmos DB и сохраняет секретную информацию в Azure Key Vault с именем connectionString
, которое представляет собой полную строку подключения к экземпляру Cosmos DB. Чтобы получить доступ к значению строки секретного подключения, можно использовать следующий фрагмент кода:
var cosmos = builder.AddBicepTemplate("cosmos", "../infra/cosmosdb.bicep")
.WithParameter("databaseAccountName", "fallout-db")
.WithParameter(AzureBicepResource.KnownParameters.KeyVaultName)
.WithParameter("databases", ["vault-33", "vault-111"]);
var connectionString =
cosmos.GetSecretOutput("connectionString");
builder.AddProject<Projects.WebHook_Api>("api")
.WithEnvironment(
"ConnectionStrings__cosmos",
connectionString);
В предыдущем фрагменте кода шаблон Bicep cosmos
добавляется в качестве ссылки на builder
. Вывод секретного значения connectionString
извлекается из шаблона Bicep и сохраняется в переменной. Затем секретные данные передаются как переменная среды (ConnectionStrings__cosmos
) в проект api
. Эта переменная среды используется для подключения к экземпляру Cosmos DB.
При развертывании этого ресурса базовый механизм развертывания автоматически включит ссылки на секреты из Azure Key Vault. Чтобы гарантировать изоляцию секретов, .NET.NET Aspire создает Key Vault для каждого источника.
Заметка
В режиме локальной подготовки секрет извлекается из Key Vault и устанавливается в переменную среды. Дополнительные сведения см. в локальном Azure обеспечении.
Издательство
При публикации приложения Azure параметры, подготовленные Bicep, используются Azure Developer CLI для создания ресурсов Azure в подписке Azure. .NET .NET Aspire выводит манифест публикации, который также является жизненно важной частью процесса публикации. Azure Developer CLI — это средство командной строки, которое предоставляет набор команд для управления Azure ресурсами.
Дополнительные сведения о публикации и развертывании см. в Развертывание проекта .NET Aspire в Azure Container Apps с помощью Azure Developer CLI (подробное руководство).
.NET Aspire