Aspire 集成 Azure App Configuration:配置、预置与本地模拟器实战指南
【免费下载链接】aspireAspire is the tool for code-first, extensible, observable dev and deploy.项目地址: https://gitcode.com/GitHub_Trending/as/aspire
本指南以 Aspire 开源仓库中的 Aspire.Hosting.Azure.AppConfiguration 集成文档 为核心,完整讲解如何在 Aspire AppHost 中建模、配置并编排 Azure App Configuration 资源,包括添加集成、配置本地开发期 Azure 预置、C#/TypeScript 双语言引用方式,并深入源码剖析资源模型、默认角色分配、私有终结点与本地模拟器(Emulator)等底层机制。读完本文,你将能在自己的 Aspire 解决方案中端到端接入 Azure App Configuration,并掌握本地开发与云端部署两套完整工作流。
集成概览:在 Aspire 中建模 Azure App Configuration
Aspire.Hosting.Azure.AppConfiguration是 Aspire 的托管集成之一,作用是在 Aspire 的应用模型中"建模、配置并编排"Azure App Configuration 资源。它位于仓库 src/Aspire.Hosting.Azure.AppConfiguration 目录,从项目文件 Aspire.Hosting.Azure.AppConfiguration.csproj 可以看到,它依赖Aspire.Hosting.Azure(Azure 托管基础)以及Azure.Provisioning、Azure.Provisioning.AppConfiguration两个预置(Provisioning)库,说明该集成不仅负责资源建模,还承担了从代码生成 Bicep 基础设施的职责。
集成对外暴露的核心 API 均收敛在 AzureAppConfigurationExtensions.cs 中,包括:
AddAzureAppConfiguration(name):向应用模型添加 Azure App Configuration 资源;RunAsEmulator(configureEmulator):在本地以容器模拟器运行该资源;WithRoleAssignments(...):为资源分配 App Configuration 内置角色;WithDataBindMount/WithDataVolume/WithHostPort:模拟器数据持久化与端口配置。
对应的资源类型定义在 AzureAppConfigurationResource.cs,它实现了IResourceWithConnectionString、IResourceWithEndpoints与IAzurePrivateEndpointTarget等接口,意味着它天然支持连接字符串注入、终结点暴露以及 Azure 私有终结点(Private Endpoint)能力。
快速开始:添加集成
前置条件
使用该集成的前提是拥有一个Azure 订阅。本地开发期若要让 Aspire 自动完成 Azure 资源预置,开发者还需要对目标订阅具备Owner 权限——原因是预置过程会为资源配置角色分配(Role Assignments),这需要较高权限级别,原文档中对此有明确提醒。
使用 Aspire CLI 添加集成
在 AppHost 项目目录下执行以下命令,即可将Aspire.Hosting.Azure.AppConfiguration集成添加到当前解决方案:
aspire add Aspire.Hosting.Azure.AppConfiguration该命令会为 AppHost 项目添加对应的包引用,之后便可在Program.cs(C#)或apphost.mts(TypeScript)中调用集成提供的 API。
配置 Azure 预置:为本地开发做准备
将 Azure 资源加入 AppHost 模型后,Aspire 会自动启用**开发期 Azure 预置(development-time provisioning)**能力——即无需手动在 Azure 门户创建资源,Aspire 会在本地开发运行时按需为你预置。这一机制对应源码中AddAzureAppConfiguration第一行调用的builder.AddAzureProvisioning()(见 AzureAppConfigurationExtensions.cs)。
预置过程需要从 AppHost 配置中读取若干设置,使用aspire secret set在 AppHost 目录下写入即可:
aspire secret set Azure:SubscriptionId "<your subscription id>" aspire secret set Azure:ResourceGroupPrefix "<prefix for the resource group>" aspire secret set Azure:Location "<azure location>"三个配置项的作用分别是:
| 配置键 | 含义 | 建议 |
|---|---|---|
Azure:SubscriptionId | 目标 Azure 订阅 ID | 填入订阅 GUID |
Azure:ResourceGroupPrefix | 预置资源组的名称前缀 | 预置时会基于前缀生成资源组 |
Azure:Location | Azure 区域 | 如eastus、westeurope等 |
注意:开发者必须对目标订阅拥有Owner访问权限,这样预置出来的资源才能成功配置角色分配(Role Assignments)。这是原文档明确强调的硬性前提。
使用示例:C# 与 TypeScript 双语言接入
C# AppHost
在 C# AppHost 中,通过AddAzureAppConfiguration创建连接,再通过WithReference注入到其他资源:
var appConfig = builder.AddAzureAppConfiguration("config"); var myService = builder.AddProject<Projects.MyService>() .WithReference(appConfig);WithReference会把连接信息(连接字符串)以环境变量的形式注入MyService,服务即可通过标准配置读取方式消费 App Configuration。
TypeScript AppHost
在 TypeScript AppHost(Aspire 的多语言应用宿主)中,写法是对应的异步 API:
const appConfig = await builder.addAzureAppConfiguration("config"); const myService = await builder.addNodeApp("myService", "../my-service", "server.js") .withReference(appConfig);TypeScript 侧的能力清单可以查看集成生成的 Aspire Type System 描述文件 Aspire.Hosting.Azure.AppConfiguration.ats.txt,其中列出了addAzureAppConfiguration、runAsEmulator、withAppConfigurationRoleAssignments、withDataBindMount、withDataVolume、withHostPort等全部可调用能力,以及AzureAppConfigurationRole枚举(AppConfigurationDataOwner、AppConfigurationDataReader)。
仓库 tests/PolyglotAppHosts/Aspire.Hosting.Azure.AppConfiguration/TypeScript/apphost.mts 给出了一个完整的 TypeScript 用法:创建资源后调用withAppConfigurationRoleAssignments分配角色,再通过runAsEmulator的configureEmulator回调配置数据绑定挂载、数据卷与宿主机端口。
资源命名注意事项
建议将资源名称设置为 "config"、"appconfig" 之外的名称。尽管部署时 Aspire 会自动追加随机后缀,但仍有发生名称冲突的可能。
这一提示背后有真实的工程考量:从 AzureAppConfigurationExtensionsTests.cs 生成的 Bicep 可以看到,实际部署名称形如take('appConfig-${uniqueString(resourceGroup().id)}', 50)——即"资源名 + uniqueString 后缀",并被截断到 50 个字符,因此短小通用的名称更易撞车。
云端预置的底层原理:资源模型与 Bicep 生成
预置资源的结构
AddAzureAppConfiguration在 AzureAppConfigurationExtensions.cs 中通过configureInfrastructure回调完成云资源的建模,核心配置包括:
- SKU:固定为
standard; - 本地认证:默认
DisableLocalAuth = true(禁用本地访问密钥认证,强制走托管标识/Entra ID); - 标签:写入
aspire-resource-name标签以标识资源归属; - 私有终结点:若资源带有
PrivateEndpointTargetAnnotation注解,则自动设置PublicNetworkAccess = Disabled,仅允许私有网络访问。
预置完成后,集成会输出三个 Provisioning 输出,供下游引用:
| 输出名 | 内容 | 用途 |
|---|---|---|
appConfigEndpoint | 配置存储终结点 URL | 作为连接字符串主体注入 |
name | 实际部署的资源名称 | 用于外部化角色分配 |
id | 资源 Azure 资源 ID | 用于私有终结点支持 |
测试验证的 Bicep 形态
单元测试 AzureAppConfigurationExtensionsTests.cs 锁定了生成 Bicep 的形态,可直接对照理解云端部署产物:
@description('The location for the resource(s) to be deployed.') param location string = resourceGroup().location resource appConfig 'Microsoft.AppConfiguration/configurationStores@2024-06-01' = { name: take('appConfig-${uniqueString(resourceGroup().id)}', 50) location: location properties: { disableLocalAuth: true } sku: { name: 'standard' } tags: { 'aspire-resource-name': 'appConfig' } } output appConfigEndpoint string = appConfig.properties.endpoint output name string = appConfig.name output id string = appConfig.id同时,生成的清单(manifest)为azure.bicep.v0类型,连接字符串取自{appConfig.outputs.appConfigEndpoint}——这解释了WithReference注入的最终连接字符串是如何在运行时被解析的。
默认角色分配
默认情况下,引用该 App Configuration 资源的资源会被分配AppConfigurationDataOwner内置角色。测试中的角色 Bicep 展示了实际的角色定义 ID5ae67dd6-50cb-40e7-96ff-dc2bfa4b606b(对应 App Configuration Data Owner)。若想改为只读访问,可通过WithRoleAssignments替换默认分配:
var builder = DistributedApplication.CreateBuilder(args); var appStore = builder.AddAzureAppConfiguration("appStore"); var api = builder.AddProject<Projects.Api>("api") .WithRoleAssignments(appStore, AppConfigurationBuiltInRole.AppConfigurationDataReader) .WithReference(appStore);说明:
AppConfigurationBuiltInRole属于Azure.Provisioning类型,不能直接用于多语言(polyglot)AppHost;TypeScript 等场景请使用基于 AzureAppConfigurationRole 枚举的withAppConfigurationRoleAssignments重载(见 Aspire.Hosting.Azure.AppConfiguration.ats.txt)。
本地开发:使用模拟器(Emulator)
启用模拟器
与真实云端资源不同,本地开发时可通过RunAsEmulator()将资源切换为容器化的本地模拟器,避免依赖 Azure 云端。调用后会做以下几件事(见 AzureAppConfigurationExtensions.cs):
- 暴露名为
emulator的 HTTP 终结点,容器目标端口为8483; - 注册针对
/health路径的 HTTP 健康检查(测试RunAsEmulatorRegistersHealthCheck验证了appconfig_emulator_/health_200_check注解); - 绑定官方模拟器镜像:
mcr.microsoft.com/azure-app-configuration/app-configuration-emulator:1.2.0(版本常量见 AppConfigurationEmulatorContainerImageTags.cs); - 默认开启匿名访问(Anonymous Auth),匿名用户角色为
Owner(对应环境变量Tenant:AnonymousAuthEnabled=true与Authentication:Anonymous:AnonymousUserRole=Owner,见WithAnonymousAccess内部实现)。
从 AzureAppConfigurationResource.cs 可以确认,模拟器模式下的连接字符串会被自动改写为本地模拟器形态:
Endpoint={emulator endpoint url};Id=anonymous;Secret=abcdefghijklmnopqrstuvwxyz1234567890;Anonymous=True即本地开发时注入给下游服务的连接字符串自动指向模拟器,而IsEmulator => this.IsContainer()则用于运行时区分当前是模拟器还是云端资源,部署(Publish)模式下RunAsEmulator会被直接跳过(见ExecutionContext.IsPublishMode判断)。
数据持久化与端口配置
模拟器资源还提供三类常用配置:
1. 数据绑定挂载——将模拟器数据持久化到宿主机目录:
builder.AddAzureAppConfiguration("config") .RunAsEmulator(emulator => emulator.WithDataBindMount());默认挂载路径为 AppHost 目录下的.aace/{资源名},映射到容器内/app/.aace;也可显式指定路径:WithDataBindMount("./my-data")。
2. 命名数据卷——改用 Docker 命名卷持久化:
.RunAsEmulator(emulator => emulator.WithDataVolume());未指定名称时,卷名由VolumeNameGenerator.Generate基于应用名与资源名自动生成,挂载点为容器内/app。
3. 固定宿主机端口——默认端口是随机分配的,需要固定时可调用:
.RunAsEmulator(emulator => emulator.WithHostPort(8483));传null则继续使用随机端口。
TypeScript 下三者对应withDataBindMount({ path })、withDataVolume({ name })、withHostPort({ port }),完整可运行示例见 PolyglotAppHosts 的 apphost.mts。
私有终结点与既有资源接入
私有终结点支持
AzureAppConfigurationResource.cs 中实现了IAzurePrivateEndpointTarget接口,声明了:
- Private Link 组 ID:
configurationStores; - 私有 DNS 区域:
privatelink.azconfig.io。
配合AddAzureAppConfiguration中的PrivateEndpointTargetAnnotation检查,一旦在应用中配置了私有终结点,预置的存储会自动关闭公网访问(PublicNetworkAccess = Disabled),从而构建出完全私有化的配置访问链路。
接入既有 App Configuration
AzureAppConfigurationResource.AddAsExistingResource(见 AzureAppConfigurationResource.cs)支持将应用模型中已存在的配置存储以"既有资源"方式引用:先检查 Bicep 标识符是否已注册以避免重复,再以AppConfigurationStore.FromExisting建立引用;若附加了ExistingAzureResourceAnnotation(对应.AsExisting(name, resourceGroup)API),则直接沿用注解中的名称与资源组。对应测试AddAsExistingResource_ShouldBeIdempotent_ForAzureAppConfigurationResource与AddAsExistingResource_RespectsExistingAzureResourceAnnotation_ForAzureAppConfigurationResource分别验证了幂等性与注解行为。
更多参考
- 集成完整的 ATS API 能力清单:Aspire.Hosting.Azure.AppConfiguration.ats.txt
- 托管扩展实现:AzureAppConfigurationExtensions.cs
- 资源类型定义:AzureAppConfigurationResource.cs
- 单元测试:AzureAppConfigurationExtensionsTests.cs
- TypeScript 端到端示例:PolyglotAppHosts 的 apphost.mts
本集成遵循 Apache/MIT 开源协议,贡献与反馈可参考仓库根目录的 CONTRIBUTING 相关文档 与 AGENTS.md。
【免费下载链接】aspireAspire is the tool for code-first, extensible, observable dev and deploy.项目地址: https://gitcode.com/GitHub_Trending/as/aspire
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考