Aspire Azure 集成概述

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

添加 Azure 资源

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

典型的开发人员体验

Aspire当 AppHost 包含Azure资源,并且在本地运行它时(典型的开发人员 F5dotnet run体验),这些资源会在Azure订阅中被预配。 这样,开发人员就可以在 AppHost 的上下文中在本地对其进行调试。

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

本地模拟器

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

托管集成 Description
Azure 应用配置 调用RunAsEmulatorIResourceBuilder<AzureAppConfigurationResource>上配置Azure应用配置资源,以便使用Azure应用配置模拟器进行模拟
Azure Cosmos DB AzureCosmosExtensions.RunAsEmulator 调用 IResourceBuilder<AzureCosmosDBResource>,以将 Cosmos DB 资源配置为通过 NoSQL API 进行模拟
Azure AI Foundry 调用 上的 配置资源以在 Foundry Local 上模拟
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 服务。

Important

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

本地容器

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

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

托管集成 Details
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 映像配置其在容器中本地运行。

Note

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

了解 Azure 集成 API 接口

Aspire其实力在于提供惊人的开发人员内部循环的能力。 Azure 的集成并没有什么不同。 它们提供一组通用 API 和模式,这些 API 和模式在所有 Azure 资源之间共享。 这些 API 和模式旨在以一致的方式轻松处理 Azure 资源。

在前面的容器部分中,你了解了如何在容器中本地运行 Azure 服务。 如果你熟悉 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 容器应用

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

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

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

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

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

Operation API Description
Publish PublishAsConnectionString<T>(IResourceBuilder<T>) 将资源更改为在清单中发布为连接字符串引用。
Publish PublishAsExisting 部署应用程序时使用现有的 Azure 资源,而不是创建新的资源。
Run AzureSqlExtensions.RunAsContainer(IResourceBuilder<AzureSqlServerResource>, Action<IResourceBuilder<SqlServerServerResource>>)
AzureRedisExtensions.RunAsContainer(IResourceBuilder<AzureRedisCacheResource>, Action<IResourceBuilder<RedisResource>>)
RunAsContainer(IResourceBuilder<AzurePostgresFlexibleServerResource>, Action<IResourceBuilder<PostgresServerResource>>)
将等效容器配置为在本地运行。 有关详细信息,请参阅 本地容器
Run 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 资源。 有关详细信息,请参阅 本地模拟器
Run RunAsExisting 在应用程序运行时使用现有资源,而不是创建新资源。
发布和运行 AsExisting<T>(IResourceBuilder<T>, IResourceBuilder<ParameterResource>, IResourceBuilder<ParameterResource>) 无论操作如何,都使用现有资源。

Note

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

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

常规运行模式 API 用例

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

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

使用现有 Azure 资源

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

Important

调用RunAsExistingPublishAsExistingAsExisting方法来处理您Azure订阅中已存在的资源时,您必须将某些配置值添加到AppHost,以确保Aspire能够找到这些资源。 必要的配置值包括 SubscriptionIdAllowResourceGroupCreationResourceGroupLocation。 如果您不设置它们,仪表板中就会出现“缺少配置”错误 Aspire。 有关如何设置它们的详细信息,请参阅 “配置”。

可以通过使用角色分配和其他自定义功能来增强这些API引用的现有资源,这些自定义项可用于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 资源。

在发布模式下执行 AppHost 后,生成的清单文件将包含 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}"
}

有关清单文件的详细信息,请参阅 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

Warning

与需要身份验证的现有资源交互时,请确保在应用程序模型中配置的 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 资源

Aspire 提供 连接到现有资源(包括 Azure 资源)的功能。 表达连接字符串很有用,当您希望在 Azure 应用中使用现有的 Aspire 资源时。 API AddConnectionString 与 AppHost 的执行上下文 一起使用,以有条件地将连接字符串添加到应用模型。

Note

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

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

发布为 Azure 容器应用

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

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

这些 API 将资源配置为作为 Azure 容器应用发布,并隐式调用 AddAzureContainerAppsInfrastructure(IDistributedApplicationBuilder) 以将必要的基础结构和 Bicep 文件添加到 AppHost。 例如,请考虑以下代码:

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 环境”。 有关将资源发布为 Azure 容器应用作业的详细信息,请参阅 Azure 容器应用作业。 有关详细信息,请参阅 ContainerAppAsProvisioningParameter

Tip

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

Publishing

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

有关发布和部署的详细信息,请参阅使用Azure Developer CLI将Aspire项目部署到Azure Container Apps(详细指南)