在本文中,你将了解 Aspire 清单格式。 本文作为部署工具生成器的参考指南,有助于创建工具,以便在特定的托管平台上部署 Aspire 项目,无论是在本地还是在云中。
Aspire通过帮助管理应用程序集成之间的相互依赖关系,简化了本地开发体验。 为了帮助简化应用程序的部署,Aspire 项目可以生成定义为 JSON 格式化文件的所有资源的清单。
生成清单
生成清单需要有效的 Aspire 项目。 若要开始,请使用Aspireaspire-starter模板创建项目.NET:
dotnet new aspire-starter --use-redis-cache `
-o AspireApp && `
cd AspireApp
通过运行具有特殊目标的 dotnet build 来实现清单生成:
dotnet run --project AspireApp.AppHost\AspireApp.AppHost.csproj `
--publisher manifest `
--output-path ../aspire-manifest.json
提示
--output-path 支持相对路径。 上一个命令使用 ../aspire-manifest.json 将清单文件放置在项目目录的根目录中。
有关详细信息,请参阅 dotnet run。 上一个命令生成以下输出:
Building...
info: Aspire.Hosting.Publishing.ManifestPublisher[0]
Published manifest to: .\AspireApp.AppHost\aspire-manifest.json
生成的文件是清单, Aspire 由工具用来支持部署到目标云环境。
注意
还可以在启动配置文件中生成清单。 请考虑以下 launchSettings.json:
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"generate-manifest": {
"commandName": "Project",
"launchBrowser": false,
"dotnetRunMessages": true,
"commandLineArgs": "--publisher manifest --output-path aspire-manifest.json"
}
}
}
基本清单格式
从 Aspire 的默认初学者模板发布清单将生成以下 JSON 输出:
{
"resources": {
"cache": {
"type": "container.v0",
"connectionString": "{cache.bindings.tcp.host}:{cache.bindings.tcp.port}",
"image": "redis:7.2.4",
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"containerPort": 6379
}
}
},
"apiservice": {
"type": "project.v0",
"path": "../AspireApp.ApiService/AspireApp.ApiService.csproj",
"env": {
"OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true",
"OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true"
},
"bindings": {
"http": {
"scheme": "http",
"protocol": "tcp",
"transport": "http"
},
"https": {
"scheme": "https",
"protocol": "tcp",
"transport": "http"
}
}
},
"webfrontend": {
"type": "project.v0",
"path": "../AspireApp.Web/AspireApp.Web.csproj",
"env": {
"OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true",
"OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true",
"ConnectionStrings__cache": "{cache.connectionString}",
"APISERVICE_HTTP": "{apiservice.bindings.http.url}",
"APISERVICE_HTTPS": "{apiservice.bindings.https.url}",
"services__apiservice__http__0": "{apiservice.bindings.http.url}",
"services__apiservice__https__0": "{apiservice.bindings.https.url}"
},
"bindings": {
"http": {
"scheme": "http",
"protocol": "tcp",
"transport": "http"
},
"https": {
"scheme": "https",
"protocol": "tcp",
"transport": "http"
}
}
}
}
}
清单格式 JSON 由一个名为 resources的单个对象组成,该对象包含 Program.cs 中指定的每个资源的属性(每个名称的 name 参数用作 JSON中每个子资源对象的属性)。
连接字符串和绑定引用
在前面的示例中,有两个项目资源和一个 Redis 缓存资源。 webfrontend 取决于 apiservice(project)和 缓存(Redis)资源。
此依赖项已知,因为 webfrontend 的环境变量包含引用其他两个资源的占位符:
"env": {
// ... other environment variables omitted for clarity
"ConnectionStrings__cache": "{cache.connectionString}",
"APISERVICE_HTTP": "{apiservice.bindings.http.url}",
"APISERVICE_HTTPS": "{apiservice.bindings.https.url}",
"services__apiservice__http__0": "{apiservice.bindings.http.url}",
"services__apiservice__https__0": "{apiservice.bindings.https.url}"
},
该apiservice资源通过使用 webfrontend AppHost WithReference(apiservice) 文件中的调用AppHost.cs进行引用,并使用redis调用WithReference(cache)进行引用:
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
var apiService = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");
builder.AddProject<Projects.AspireApp_Web>("webfrontend")
.WithReference(cache)
.WithReference(apiService);
builder.Build().Run();
项目资源类型之间的引用会导致 服务发现 变量注入到引用项目中。 引用已知引用类型(如 Redis 会导致注入连接字符串。
有关应用模型中的资源及其之间引用的工作原理的详细信息,请参阅 Aspire 业务流程概述。
占位符字符串结构
占位符字符串引用清单的结构 Aspire :
占位符字符串的最后一段(在本例中url)由处理清单的工具生成。 可以在占位符字符串上使用几个后缀:
-
connectionString:对于已知资源类型,如 Redis。 部署工具将资源转换到最适合目标云环境的基础结构中,然后为要使用的应用程序生成 Aspire 兼容的连接字符串。 在container.v0资源上,connectionString字段可能存在并显式指定。 这是为了支持使用 WithReference 扩展引用容器资源类型的方案,但需要以容器的形式显式托管。 -
url:对于需要格式正确的 URL 的服务到服务引用。 部署工具根据清单中定义的方案、协议和传输以及已部署的基础计算/网络拓扑生成url。 -
host:URL 的主机段。 -
port:URL 的端口段。
资源类型
每个资源都有一个 type 字段。 当部署工具读取清单时,它应读取类型以验证它是否可以正确处理清单。 在 Aspire 预览期间,所有资源类型都有一个 v0 后缀,指示它们可能会更改。 随着 Aspire 方法的发布, v1 后缀将用于表示该资源类型的清单的结构应被视为稳定(后续更新相应地递增版本号)。
常见资源字段
type 字段是所有资源类型中通用的唯一字段,但是,project.v0、container.v0和 executable.v0 资源类型也共享 env 和 bindings 字段。
注意
executable.v0 资源类型未在清单中完全实现,因为它在部署方案中缺乏实用工具。 有关容器化可执行文件的详细信息,请参阅 Dockerfile 资源类型。
绑定在 bindings 字段中指定,每个绑定都包含在 bindingsJSON 对象下自己的字段内。 节点中清单省略 Aspire 的 bindings 字段包括:
-
scheme:以下值之一tcp、udp、http或https。 -
protocol:以下值之一tcp或udp -
transport:与scheme相同,但用于消除http和http2之间的歧义。 -
containerPort:可选,如果省略端口 80。
inputs 字段
某些资源生成 inputs 字段。 此字段用于指定资源的输入参数。
inputs 字段是一个 JSON 对象,其中每个属性都是占位符结构解析中使用的输入参数。 例如,具有 connectionString的资源可能使用 inputs 字段为连接字符串指定 password:
"connectionString": "Host={<resourceName>.bindings.tcp.host};Port={<resourceName>.bindings.tcp.port};Username=admin;Password={<resourceName>.inputs.password};"
连接字符串占位符从 password 字段中引用 inputs 输入参数:
"inputs": {
"password": {
"type": "string",
"secret": true,
"default": {
"generate": {
"minLength": 10
}
}
}
}
前面的 JSON 代码片段显示了具有 inputs 字段的资源的 connectionString 字段。
password 输入参数是字符串类型,并标记为机密。
default 字段用于指定输入参数的默认值。 在这种情况下,将使用 generate 字段生成默认值,其长度为最小随机字符串。
内置资源
下表列出了由 Aspire 团队开发的 Aspire 和扩展显式生成的资源类型:
与云无关的资源类型
这些资源在 📦Aspire中可用。托管 NuGet 包。
| 应用模型使用情况 | 清单资源类型 | 标题链接 |
|---|---|---|
| AddContainer | container.v0 |
容器资源类型 |
PublishAsDockerFile |
dockerfile.v0 |
|
| AddDatabase | value.v0 |
|
| AddMongoDB | container.v0 |
|
| AddDatabase | value.v0 |
|
| AddMySql | container.v0 |
|
| AddDatabase | value.v0 |
|
| AddPostgres | container.v0 |
|
| AddProject | project.v0 |
Project 资源类型 |
| AddRabbitMQ | container.v0 |
|
| AddRedis | container.v0 |
Redis 资源类型 |
| AddDatabase | value.v0 |
|
| AddSqlServer | container.v0 |
|
项目资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");
示例清单:
"apiservice": {
"type": "project.v0",
"path": "../AspireApp.ApiService/AspireApp.ApiService.csproj",
"env": {
"OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true",
"OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true"
},
"bindings": {
"http": {
"scheme": "http",
"protocol": "tcp",
"transport": "http"
},
"https": {
"scheme": "https",
"protocol": "tcp",
"transport": "http"
}
}
}
容器资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddContainer("mycontainer", "myimage")
.WithEnvironment("LOG_LEVEL", "WARN")
.WithHttpEndpoint(3000);
示例清单:
{
"resources": {
"mycontainer": {
"type": "container.v0",
"image": "myimage:latest",
"env": {
"LOG_LEVEL": "WARN"
},
"bindings": {
"http": {
"scheme": "http",
"protocol": "tcp",
"transport": "http",
"containerPort": 3000
}
}
}
}
}
Dockerfile 资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddNodeApp("nodeapp", "../nodeapp/app.js")
.WithHttpEndpoint(hostPort: 5031, env: "PORT")
.PublishAsDockerFile();
提示
需要 PublishAsDockerFile 调用才能在清单中生成 Dockerfile 资源类型,并且此扩展方法仅在 ExecutableResource 类型上可用。
示例清单:
{
"resources": {
"nodeapp": {
"type": "dockerfile.v0",
"path": "../nodeapp/Dockerfile",
"context": "../nodeapp",
"env": {
"NODE_ENV": "development",
"PORT": "{nodeapp.bindings.http.port}"
},
"bindings": {
"http": {
"scheme": "http",
"protocol": "tcp",
"transport": "http",
"containerPort": 5031
}
}
}
}
}
Postgres 资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddPostgres("postgres1")
.AddDatabase("shipping");
示例清单:
{
"resources": {
"postgres1": {
"type": "container.v0",
"connectionString": "Host={postgres1.bindings.tcp.host};Port={postgres1.bindings.tcp.port};Username=postgres;Password={postgres1.inputs.password}",
"image": "postgres:16.2",
"env": {
"POSTGRES_HOST_AUTH_METHOD": "scram-sha-256",
"POSTGRES_INITDB_ARGS": "--auth-host=scram-sha-256 --auth-local=scram-sha-256",
"POSTGRES_PASSWORD": "{postgres1.inputs.password}"
},
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"containerPort": 5432
}
},
"inputs": {
"password": {
"type": "string",
"secret": true,
"default": {
"generate": {
"minLength": 10
}
}
}
}
},
"shipping": {
"type": "value.v0",
"connectionString": "{postgres1.connectionString};Database=shipping"
}
}
}
RabbitMQ 资源类型
RabbitMQ 建模为容器资源 container.v0。 以下示例演示如何将其添加到应用模型。
var builder = DistributedApplication.CreateBuilder(args);
builder.AddRabbitMQ("rabbitmq1");
前面的代码生成以下清单:
{
"resources": {
"rabbitmq1": {
"type": "container.v0",
"connectionString": "amqp://guest:{rabbitmq1.inputs.password}@{rabbitmq1.bindings.tcp.host}:{rabbitmq1.bindings.tcp.port}",
"image": "rabbitmq:3",
"env": {
"RABBITMQ_DEFAULT_USER": "guest",
"RABBITMQ_DEFAULT_PASS": "{rabbitmq1.inputs.password}"
},
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"containerPort": 5672
}
},
"inputs": {
"password": {
"type": "string",
"secret": true,
"default": {
"generate": {
"minLength": 10
}
}
}
}
}
}
}
Redis 资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddRedis("redis1");
示例清单:
{
"resources": {
"redis1": {
"type": "container.v0",
"connectionString": "{redis1.bindings.tcp.host}:{redis1.bindings.tcp.port}",
"image": "redis:7.2.4",
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"containerPort": 6379
}
}
}
}
}
SQL Server 资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddSqlServer("sql1")
.AddDatabase("shipping");
示例清单:
{
"resources": {
"sql1": {
"type": "container.v0",
"connectionString": "Server={sql1.bindings.tcp.host},{sql1.bindings.tcp.port};User ID=sa;Password={sql1.inputs.password};TrustServerCertificate=true",
"image": "mcr.microsoft.com/mssql/server:2022-latest",
"env": {
"ACCEPT_EULA": "Y",
"MSSQL_SA_PASSWORD": "{sql1.inputs.password}"
},
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"containerPort": 1433
}
},
"inputs": {
"password": {
"type": "string",
"secret": true,
"default": {
"generate": {
"minLength": 10
}
}
}
}
},
"shipping": {
"type": "value.v0",
"connectionString": "{sql1.connectionString};Database=shipping"
}
}
}
MongoDB 资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddMongoDB("mongodb1")
.AddDatabase("shipping");
示例清单:
{
"resources": {
"mongodb1": {
"type": "container.v0",
"connectionString": "mongodb://{mongodb1.bindings.tcp.host}:{mongodb1.bindings.tcp.port}",
"image": "mongo:7.0.5",
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"containerPort": 27017
}
}
},
"shipping": {
"type": "value.v0",
"connectionString": "{mongodb1.connectionString}/shipping"
}
}
}
MySQL 资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddMySql("mysql1")
.AddDatabase("shipping");
示例清单:
{
"resources": {
"mysql1": {
"type": "container.v0",
"connectionString": "Server={mysql1.bindings.tcp.host};Port={mysql1.bindings.tcp.port};User ID=root;Password={mysql1.inputs.password}",
"image": "mysql:8.3.0",
"env": {
"MYSQL_ROOT_PASSWORD": "{mysql1.inputs.password}"
},
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"containerPort": 3306
}
},
"inputs": {
"password": {
"type": "string",
"secret": true,
"default": {
"generate": {
"minLength": 10
}
}
}
}
},
"shipping": {
"type": "value.v0",
"connectionString": "{mysql1.connectionString};Database=shipping"
}
}
}
Azure-specific 资源类型
📦 Aspire中提供了以下资源。好客。Azure NuGet 包。
| 应用模型用法 | 清单资源类型 | 标题链接 |
|---|---|---|
| AddAzureAppConfiguration | azure.bicep.v0 |
Azure 应用配置资源类型 |
| AddAzureKeyVault | azure.bicep.v0 |
Azure Key Vault 资源类型 |
AddAzureRedis |
azure.bicep.v0 |
|
| AddAzureServiceBus | azure.bicep.v0 |
Azure Service Bus 资源类型 |
AddAzureSqlServer(...) |
azure.bicep.v0 |
Azure SQL 资源类型 |
AddAzureSqlServer(...).AddDatabase(...) |
value.v0 |
Azure SQL 资源类型 |
AddAzurePostgresFlexibleServer(...) |
azure.bicep.v0 |
|
AddAzurePostgresFlexibleServer(...).AddDatabase(...) |
value.v0 |
|
| AddAzureStorage | azure.storage.v0 |
Azure 存储资源类型 |
| AddBlobs | value.v0 |
Azure 存储资源类型 |
| AddQueues | value.v0 |
Azure 存储资源类型 |
| AddTables | value.v0 |
Azure 存储资源类型 |
Azure Key Vault 资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureKeyVault("keyvault1");
示例清单:
{
"resources": {
"keyvault1": {
"type": "azure.bicep.v0",
"connectionString": "{keyvault1.outputs.vaultUri}",
"path": "aspire.hosting.azure.bicep.keyvault.bicep",
"params": {
"principalId": "",
"principalType": "",
"vaultName": "keyvault1"
}
}
}
}
Azure Service Bus 资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureServiceBus("sb1")
.AddTopic("topic1", [])
.AddTopic("topic2", [])
.AddQueue("queue1")
.AddQueue("queue2");
示例清单:
{
"resources": {
"sb1": {
"type": "azure.bicep.v0",
"connectionString": "{sb1.outputs.serviceBusEndpoint}",
"path": "aspire.hosting.azure.bicep.servicebus.bicep",
"params": {
"serviceBusNamespaceName": "sb1",
"principalId": "",
"principalType": "",
"queues": [
"queue1",
"queue2"
],
"topics": [
{
"name": "topic1",
"subscriptions": []
},
{
"name": "topic2",
"subscriptions": []
}
]
}
}
}
}
Azure 存储资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
var storage = builder.AddAzureStorage("images");
storage.AddBlobs("blobs");
storage.AddQueues("queues");
storage.AddTables("tables");
示例清单:
{
"resources": {
"images": {
"type": "azure.bicep.v0",
"path": "aspire.hosting.azure.bicep.storage.bicep",
"params": {
"principalId": "",
"principalType": "",
"storageName": "images"
}
},
"blobs": {
"type": "value.v0",
"connectionString": "{images.outputs.blobEndpoint}"
},
"queues": {
"type": "value.v0",
"connectionString": "{images.outputs.queueEndpoint}"
},
"tables": {
"type": "value.v0",
"connectionString": "{images.outputs.tableEndpoint}"
}
}
}
Azure Redis 资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureRedis("azredis1");
示例清单:
{
"resources": {
"azredis": {
"type": "azure.bicep.v0",
"connectionString": "{azredis.outputs.connectionString}",
"path": "azredis.module.bicep",
"params": {
"principalId": "",
"principalName": ""
}
}
}
}
Azure 应用配置资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureAppConfiguration("appconfig1");
示例清单:
{
"resources": {
"appconfig1": {
"type": "azure.bicep.v0",
"connectionString": "{appconfig1.outputs.appConfigEndpoint}",
"path": "aspire.hosting.azure.bicep.appconfig.bicep",
"params": {
"configName": "appconfig1",
"principalId": "",
"principalType": ""
}
}
}
}
Azure SQL 资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureSqlServer("sql")
.AddDatabase("inventory");
示例清单:
{
"resources": {
"sql": {
"type": "azure.bicep.v0",
"connectionString": "Server=tcp:{sql.outputs.sqlServerFqdn},1433;Encrypt=True;Authentication=\u0022Active Directory Default\u0022",
"path": "sql.module.bicep",
"params": {
"principalId": "",
"principalName": ""
}
},
"inventory": {
"type": "value.v0",
"connectionString": "{sql.connectionString};Database=inventory"
}
}
}
Azure Postgres 资源类型
示例代码:
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzurePostgresFlexibleServer("postgres")
.AddDatabase("db");
示例清单:
{
"resources": {
"postgres": {
"type": "azure.bicep.v0",
"connectionString": "{postgres.outputs.connectionString}",
"path": "postgres.module.bicep",
"params": {
"principalId": "",
"principalType": "",
"principalName": ""
}
},
"db": {
"type": "value.v0",
"connectionString": "{postgres.connectionString};Database=db"
}
}
}
Azure Developer CLI 中支持的资源类型
Azure Developer CLI(azd)是一种工具,可用于将 Aspire 项目部署到 Azure Container Apps。 使用 azure.bicep.v0 资源类型,云不可知的资源容器类型可以映射到特定于 Azure的资源。 下表列出了 Azure Developer CLI中支持的资源类型:
| 名字 | 与云无关的 API | Azure API(应用程序接口) |
|---|---|---|
| Redis | AddRedis | AddAzureRedis |
| Postgres | AddPostgres | AddAzurePostgresFlexibleServer |
| SQL Server | AddSqlServer | AddAzureSqlServer |
将资源配置为 Azure 资源时,会在清单中生成 azure.bicep.v0 资源类型。 有关详细信息,请参阅部署Aspire项目以Azure Container Apps使用Azure Developer CLI(深入指南)。