在本文中,你将了解 .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
资源类型。 有关详细信息,请参阅 .NET Aspire将 Azure Container Apps 项目部署到 Azure Developer CLI。