Skip to content

外部参数与机密 ​

更新: 2026-10-16 15:20:09   字数: 0 字   时长: 0 分钟

分布式应用总有一些运行时才能确定的值:数据库密码、API Key、容器仓库地址、外部服务的连接字符串。Aspire 用**外部参数(External parameters)**统一表达这类值。

把它理解成「参数资源」

外部参数本质上也是一种资源。它同样参与应用模型,同样可以在仪表板中看到,也同样会在部署时被翻译成目标平台的输入项(例如 Azure Container Apps 的 secret 参数)。

定义一个参数 ​

csharp
var builder = DistributedApplication.CreateBuilder(args);

// 添加一个名为 example-parameter-name 的参数
var parameter = builder.AddParameter("example-parameter-name");

builder.AddProject<Projects.ApiService>("api")
    .WithEnvironment("ENVIRONMENT_VARIABLE_NAME", parameter);

上面的代码做两件事:

  1. 向 AppHost 添加名为 example-parameter-name 的参数资源。
  2. 把该参数作为环境变量 ENVIRONMENT_VARIABLE_NAME 传给 ApiService 项目。

在本地配置参数值 ​

参数值从 AppHost 配置的 Parameters 节读取:

json
{
  "Parameters": {
    "example-parameter-name": "local-value"
  }
}

对应的配置键是 Parameters:example-parameter-name:

csharp
var key = "Parameters:example-parameter-name";
var value = builder.Configuration[key];

通常不需要手动读取

在 AppHost 中不必自己读取参数值。把 ParameterResource 传给依赖资源(通常是作为环境变量)才是正确用法。

用环境变量提供参数值 ​

部署或 CI 场景中,可以用环境变量覆盖参数值(: 写作 __):

text
Parameters__registry_endpoint   = ghcr.io
Parameters__registry_repository = my-org/my-app
csharp
var endpoint = builder.AddParameter("registry-endpoint");
var repository = builder.AddParameter("registry-repository");

builder.AddContainerRegistry("container-registry", endpoint, repository);

机密参数 ​

把参数标记为机密后,它的值不会出现在部署产物中,而是走目标平台的机密机制:

csharp
var apiKey = builder.AddParameter("api-key", secret: true);

builder.AddProject<Projects.Api>("api")
    .WithEnvironment("API_KEY", apiKey);

机密不要写进 appsettings.json

secret: true 的参数值应通过 aspire secret set 或部署环境的机密存储提供。写入 appsettings.json 会让它进入版本库。

用用户机密保存参数值 ​

bash
aspire secret set Parameters:sql-password "your-password"

查看与管理:

bash
aspire secret list                 # 列出所有机密
aspire secret get Parameters:sql-password
aspire secret delete Parameters:sql-password
aspire secret path                 # 显示机密文件路径

参数与资源密码 ​

许多「服务器型」资源在未显式提供密码时,Aspire 会自动生成一个随机密码。请注意:

自动生成的密码不是持久的

每次运行 AppHost 时生成的密码都不同。如果同时使用了数据卷(数据持久化),旧数据会因为密码变化而无法访问。

解决方法有两种。

方案一:覆盖生成的密码 ​

用约定的键名把密码固定到用户机密中:

资源类型托管包示例资源名覆盖键
MySQLAspire.Hosting.MySqlmysqlParameters:mysql-password
OracleAspire.Hosting.OracleoracleParameters:oracle-password
PostgreSQLAspire.Hosting.PostgreSQLpostgresqlParameters:postgresql-password
RabbitMQAspire.Hosting.RabbitMqrabbitmqParameters:rabbitmq-password
SQL ServerAspire.Hosting.SqlServersqlParameters:sql-password
bash
aspire secret set Parameters:sql-password "P@ssw0rd"

命名规则是 Parameters:{资源名}-password。

方案二:显式创建参数并传入 ​

csharp
var sqlPassword = builder.AddParameter("sql-password", secret: true);

var sql = builder.AddSqlServer("sql", password: sqlPassword)
    .WithDataVolume();

var sqldb = sql.AddDatabase("sqldb");

这种方式把密码的来源显式写进了应用模型,更利于部署时映射到平台机密。

参数 vs 连接字符串 ​

需求使用
需要用户/环境提供具体值(含机密)AddParameter("name", secret: true)
本地跑容器、发布时连外部服务builder.ExecutionContext.IsRunMode ? ... : AddConnectionString("db")
csharp
IResourceBuilder<IResourceWithConnectionString> db = builder.ExecutionContext.IsRunMode
    ? builder.AddSqlServer("sql").AddDatabase("db")
    : builder.AddConnectionString("db");

var insertionRows = builder.AddParameter("insertionRows");

builder.AddProject<Projects.Api>("api")
    .WithEnvironment("InsertionRows", insertionRows)
    .WithReference(db);

这段代码:

  1. Run 模式下添加名为 sql 的 SQL Server 资源与名为 db 的数据库;Publish 模式下改用名为 db 的外部连接字符串。
  2. 添加名为 insertionRows 的参数。
  3. 把 insertionRows 作为环境变量传给 api。
  4. 引用 db。

对应配置:

json
{
  "Parameters": {
    "insertionRows": "1"
  }
}

服务端读取:

csharp
int insertionRows = builder.Configuration.GetValue<int>("InsertionRows", 1);
python
insertion_rows = int(os.getenv("InsertionRows", "1"))

部署时的取值行为 ​

运行或发布应用时,如果某个参数没有配置值,Aspire 会交互式提示您输入。在自动化环境中请配合 --non-interactive 并提前通过环境变量或机密存储注入,避免流水线卡在提示上。

下一步 ​

你觉得这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度