部署工具生成器的 .NET.NET Aspire 清单格式
在本文中,你将了解 .NET.NET Aspire 清单格式。 本文作为部署工具生成器的参考指南,有助于创建工具,以便在特定的托管平台上部署 .NET.NET Aspire 项目,无论是在本地还是在云中。
.NET .NET Aspire 通过帮助管理应用程序集成之间的相互依赖性,简化了本地开发体验。 为了帮助简化应用程序的部署,.NET Aspire 项目可以生成定义为 JSON 格式化文件的所有资源的清单。
生成清单
生成清单需要有效的 .NET.NET Aspire 项目。 若要开始,请使用 .NET.NET Aspire 模板创建 aspire-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
生成的文件是 .NET.NET 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"
}
}
}
基本清单格式
从 .NET 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}",
"services__apiservice__0": "{apiservice.bindings.http.url}",
"services__apiservice__1": "{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}",
"services__apiservice__0": "{apiservice.bindings.http.url}",
"services__apiservice__1": "{apiservice.bindings.https.url}"
},
apiservice
资源通过使用应用主机 webfrontend
文件中的调用 WithReference(apiservice)
Program.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 会导致注入连接字符串。
若要详细了解应用模型中的资源及其之间的引用的工作原理,请参阅 .NET.NET Aspire 业务流程概述。
占位符字符串结构
占位符字符串引用 .NET.NET Aspire 清单的结构:
占位符字符串的最后一段(在本例中url
)由处理清单的工具生成。 可以在占位符字符串上使用几个后缀:
-
connectionString
:对于已知资源类型,如 Redis。 部署工具在最适合目标云环境的基础结构中转换资源,然后生成 .NET.NET Aspire 兼容的连接字符串,供使用的应用程序使用。 在container.v0
资源上,connectionString
字段可能存在并显式指定。 这是为了支持使用 WithReference 扩展引用容器资源类型的方案,但需要以容器的形式显式托管。 -
url
:对于需要格式正确的 URL 的服务到服务引用。 部署工具根据清单中定义的方案、协议和传输以及已部署的基础计算/网络拓扑生成url
。 -
host
:URL 的主机段。 -
port
:URL 的端口段。
资源类型
每个资源都有一个 type
字段。 当部署工具读取清单时,它应读取类型以验证它是否可以正确处理清单。 在 .NET.NET Aspire 预览期间,所有资源类型都有一个 v0
后缀,以指示它们可能会更改。 随着 .NET.NET Aspire 方法发布 v1
后缀将用于表示该资源类型的清单的结构应被视为稳定(后续更新相应地递增版本号)。
常见资源字段
type
字段是所有资源类型中通用的唯一字段,但是,project.v0
、container.v0
和 executable.v0
资源类型也共享 env
和 bindings
字段。
注意
executable.v0
资源类型未在清单中完全实现,因为它在部署方案中缺乏实用工具。 有关容器化可执行文件的详细信息,请参阅 Dockerfile 资源类型。
绑定在 bindings
字段中指定,每个绑定都包含在 bindings
JSON 对象下自己的字段内。
.NET 节点中 .NET Aspirebindings
清单省略的字段包括:
-
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
字段生成默认值,其长度为最小随机字符串。
内置资源
下表列出了由 .NET Aspire 团队开发的 .NET 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)是一种工具,可用于将 .NET 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
资源类型。 有关详细信息,请参阅 Azure Container Apps将 Azure Developer CLI 项目部署到 。