.NET AspireAzure 集成概述

Azure 是最常用的云平台,用于构建和部署 .NET 应用程序Azure 用于 .NET 的 SDK 允许轻松管理和使用 Azure 服务。 .NET Aspire 提供了一组与 Azure 服务的集成,你可以在其中免费添加新资源或连接到现有资源。 本文详细介绍了 Azure 中所有 .NET Aspire 集成的某些常见方面,旨在帮助你了解如何使用这些集成。

添加 Azure 资源

所有 .NET AspireAzure 托管集成都公开 Azure 资源,并按约定使用 AddAzure* API 添加。 将这些资源添加到 .NET Aspire 应用主机时,它们表示 Azure 服务。 AddAzure* API 返回一个 IResourceBuilder<T>,其中 T 是 Azure 资源的类型。 这些 IResourceBuilder<T>(生成器)接口提供了一个流畅的 API,可用于在 Azure中配置基础 资源。 有一些 API 可用于添加新 Azure 资源、将资源标记为现有资源,以及配置资源在各种执行上下文中的行为方式。

典型的开发人员体验

当您的 .NET Aspire 应用主机包含 Azure 资源,并且你在本地运行该资源时(典型的开发人员 F5dotnet run 体验),会在您的 Azure 订阅中进行 Azure 资源预配。 这允许你作为开发人员在应用主机的上下文中对它们进行本地调试。

.NET .NET Aspire 旨在通过对其 Azure 集成默认为基本标准库存单位 (SKU) 来尽量降低成本。 虽然提供了这些合理的默认值,但你可以 自定义 Azure 资源 以满足你的需求。 此外,某些集成还支持 模拟器容器,这对于本地开发、测试和调试非常有用。 默认情况下,在本地运行应用时,Azure 资源使用实际的 Azure 服务。 但是,可以将它们配置为使用本地模拟器或容器,从而避免在本地开发期间与实际 Azure 服务相关的成本。

本地模拟器

可以模拟某些 Azure 服务在本地运行。 目前,.NET Aspire 支持以下 Azure 模拟器:

托管集成 描述
Azure Cosmos DB IResourceBuilder<AzureCosmosDBResource> 调用 AzureCosmosExtensions.RunAsEmulator,以将 Cosmos DB 资源配置为通过 NoSQL API 进行模拟
Azure Event Hubs AzureEventHubsExtensions.RunAsEmulator 上调用 IResourceBuilder<AzureEventHubsResource>,将事件中心资源配置为 模拟
Azure Service Bus IResourceBuilder<AzureServiceBusResource> 调用 AzureServiceBusExtensions.RunAsEmulator,以将服务总线资源配置为通过服务总线模拟器进行模拟
Azure SignalR Service IResourceBuilder<AzureSignalRResource> 调用 AzureSignalRExtensions.RunAsEmulator,以将 SignalR 资源配置为使用 AzureSignalR 模拟器进行模拟
Azure 存储 IResourceBuilder<AzureStorageResource> 调用 AzureStorageExtensions.RunAsEmulator,经将存储资源配置为使用 Azurite 进行模拟

若要让 Azure 资源使用本地模拟器,请对 Azure 资源生成器调用 RunAsEmulator 方法。 此方法将 Azure 资源配置为使用本地模拟器,而不是实际的 Azure 服务。

重要

RunAsEmulator 资源生成器调用任何可用的 Azure API 不会影响 发布清单。 发布应用时, 生成的 Bicep 文件 反映实际 Azure 服务,而不是本地模拟器。

本地容器

某些 Azure 资源可以使用开放源代码或本地容器在本地替代。 若要在容器中本地替换 Azure 资源,请在 RunAsContainer 资源生成器上链接对 Azure 方法的调用。 此方法将 Azure 资源配置为使用服务的容器化版本进行本地开发和测试,而不是实际的 Azure 服务。

目前,.NET Aspire 支持以下 Azure 服务作为容器:

托管集成 详细信息
Azure Cache for Redis AzureRedisExtensions.RunAsContainer 上调用 IResourceBuilder<AzureRedisCacheResource>,以基于 docker.io/library/redis 映像配置其在容器中本地运行。
AzurePostgreSQL 灵活 Server AzurePostgresExtensions.RunAsContainer 上调用 IResourceBuilder<AzurePostgresFlexibleServerResource>,以基于 docker.io/library/postgres 映像配置其在容器中本地运行。
Azure SQL Server AzureSqlExtensions.RunAsContainer 上调用 IResourceBuilder<AzureSqlServerResource>,以基于 mcr.microsoft.com/mssql/server 映像配置其在容器中本地运行。

注意

与模拟器相似,对 Azure 资源生成器调用 RunAsContainer 不会影响发布清单。 发布应用时,生成的 Bicep 文件 反映实际 Azure 服务,而不是本地容器。

了解 Azure 集成 API 接口

.NET.NET Aspire的强项在于其能够提供卓越的开发人员内部工作循环。 Azure 的集成并没有什么不同。 它们提供一组通用 API 和模式,这些 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 容器 Redis 映像的 Azure 容器应用

SQL 和 PostgreSQL 服务也是如此:

API(应用程序编程接口) 运行模式 发布模式
AddAzurePostgresFlexibleServer(“postgres”)。RunAsContainer() 本地 PostgreSQL 容器 AzurePostgreSQL 灵活 Server
AddPostgres(“postgres”) 本地 PostgreSQL 容器 PostgreSQL 映像的 Azure 容器应用
AddAzureSqlServer(“sql”)。RunAsContainer() 本地 SQL Server 容器 Azure SQL Server
AddSqlServer(“sql”) 本地 SQL Server 容器 SQL Server 映像的 Azure 容器应用

有关运行模式和发布模式之间的差异的详细信息,请参阅 .NET.NET Aspire 应用主机:执行上下文

用于以不同模式表达 Azure 资源的 API

分布式应用程序生成器是 应用主机的一部分,它利用生成器模式将资源 AddAzure* 分配到 应用模型。 开发人员可以在不同的执行上下文中配置这些资源并定义其行为。 Azure 托管集成提供 API,用于指定应如何“发布”和“运行”这些资源。

应用主机执行时,执行上下文 用于确定应用主机是处于 Run 还是 Publish 模式。 这些 API 的命名约定指示资源的预期作。

下表汇总了用于表达 Azure 资源的命名约定:

操作 API(应用程序编程接口) 描述
发布 PublishAsConnectionString<T>(IResourceBuilder<T>) 将资源更改为在清单中发布为连接字符串引用。
发布 PublishAsExisting 部署应用程序时使用现有的 Azure 资源,而不是创建新的资源。
运行 AzureSqlExtensions.RunAsContainer(IResourceBuilder<AzureSqlServerResource>, Action<IResourceBuilder<SqlServerServerResource>>)
AzureRedisExtensions.RunAsContainer(IResourceBuilder<AzureRedisCacheResource>, Action<IResourceBuilder<RedisResource>>)
RunAsContainer(IResourceBuilder<AzurePostgresFlexibleServerResource>, Action<IResourceBuilder<PostgresServerResource>>)
将等效容器配置为在本地运行。 有关详细信息,请参阅 本地容器
运行 AzureCosmosExtensions.RunAsEmulator(IResourceBuilder<AzureCosmosDBResource>, Action<IResourceBuilder<AzureCosmosDBEmulatorResource>>)
AzureSignalRExtensions.RunAsEmulator(IResourceBuilder<AzureSignalRResource>, Action<IResourceBuilder<AzureSignalREmulatorResource>>)
AzureStorageExtensions.RunAsEmulator(IResourceBuilder<AzureStorageResource>, Action<IResourceBuilder<AzureStorageEmulatorResource>>)
AzureEventHubsExtensions.RunAsEmulator(IResourceBuilder<AzureEventHubsResource>, Action<IResourceBuilder<AzureEventHubsEmulatorResource>>)
AzureServiceBusExtensions.RunAsEmulator(IResourceBuilder<AzureServiceBusResource>, Action<IResourceBuilder<AzureServiceBusEmulatorResource>>)
配置要模拟的 Azure 资源。 有关详细信息,请参阅 本地模拟器
运行 RunAsExisting 在应用程序运行时使用现有资源,而不是创建新资源。
发布和运行 AsExisting<T>(IResourceBuilder<T>, IResourceBuilder<ParameterResource>, IResourceBuilder<ParameterResource>) 无论操作如何,都使用现有资源。

注意

并非所有 API 都可用于所有 Azure 资源。 例如,某些 Azure 资源可以容器化或模拟,而另一些资源则不能。

有关执行模式的详细信息,请参阅 执行上下文

常规运行模式 API 用例

如果需要在运行时动态与现有资源交互,而无需部署或更新资源,请使用 RunAsExisting。 将现有资源声明为部署配置的一部分时,请使用 PublishAsExisting,确保应用正确的范围和权限。 最后,在两种配置中声明现有资源时使用 AsExisting<T>(IResourceBuilder<T>, IResourceBuilder<ParameterResource>, IResourceBuilder<ParameterResource>),并要求参数化引用。

可以通过对 IsExisting(IResource)调用 IResource 扩展方法来查询资源是否标记为现有资源。 有关详细信息,请参阅 使用现有 Azure 资源

使用现有 Azure 资源

.NET Aspire 支持引用现有 Azure 资源。 通过 PublishAsExistingRunAsExistingAsExisting API 标记现有资源。 通过这些 API,开发人员可以使用 Bicep 模板引用已部署 Azure 资源、对其进行配置和生成适当的部署清单。

这些 API 引用的现有资源可以通过角色分配和 .NET.NET Aspire 的基础设施即代码功能提供的其他自定义项进行增强。 这些 API 仅限于通过 Bicep 模板部署的 Azure 资源。

为运行模式配置现有 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 模板的详细信息,请参阅 自定义 Azure 资源考虑其他发布 API

警告

与需要身份验证的现有资源交互时,请确保在 .NET.NET Aspire 应用程序模型中配置的身份验证策略与现有资源允许的身份验证策略保持一致。 例如,不能对未配置为允许托管标识的现有 AzurePostgreSQL 资源使用托管标识。 同样,如果现有 AzureRedis 资源禁用了访问密钥,则无法使用访问密钥身份验证。

在所有模式中配置现有的 Azure 资源

当分布式应用程序在“run”或“publish”模式下运行时,将使用 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 资源时。 AddConnectionString API 与应用主机的 执行上下文一起使用, 有条件地将连接字符串添加到应用模型。

注意

连接字符串用于表示各种连接信息,包括数据库连接、消息代理、终结点 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 项目使用连接字符串信息,但对应用主机如何配置它一无所知。 在“发布”模式下,代码会添加一个新的 Azure 存储资源,该资源将相应地反映在 部署清单 中。 在“运行”模式下,连接字符串对应于对应用主机可见的配置值。 可以假设目标资源的所有角色分配已配置完毕。 这意味着,可能会配置环境变量或用户机密来存储连接字符串。 配置是从 ConnectionStrings__storage(或 ConnectionStrings:storage)配置密钥解析的。 可以在应用运行时查看这些配置值。 有关详细信息,请参阅 资源详细信息

与使用 一流 AsExisting API建模的现有资源不同,建模为连接字符串的现有资源无法通过额外的角色分配或基础结构自定义进行增强。

发布为 Azure 容器应用

.NET.NET Aspire 允许将基元资源发布为 Azure Container Apps,这是一个可减少基础结构管理的无服务器平台。 支持的资源类型包括:

若要发布这些资源,请使用以下 API:

这些 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 容器应用基础结构的 lambda 表达式,其中 infraAzureResourceInfrastructureappContainerApp
    • 使用 Hello 参数将名为 env 的环境变量添加到容器应用。
    • AsProvisioningParameter 方法用于将 env 视为基础结构中的新 ProvisioningParameter,或者在已存在同名 bicep 参数时重用该参数。

若要配置 Azure 容器应用环境,请参阅 “配置 Azure Container Apps 环境”。 有关详细信息,请参阅 ContainerAppAsProvisioningParameter

提示

如果您正在使用 Azure Container Apps,您可能还会对 .NET AspireAzure 容器注册表集成感兴趣。

发布

发布应用时,Azure Developer CLI 会使用 Azure 预配生成的 Bicep 在 Azure 订阅中创建 Azure 资源。 .NET.NET Aspire 输出 发布清单,这也是发布过程的重要组成部分。 Azure Developer CLI 是一种命令行工具,提供一组用于管理 Azure 资源的命令。

有关发布和部署的详细信息,请参阅 .NET Aspire将 Azure Container Apps 项目部署到 Azure Developer CLI。