Pular para o conteúdo

Deployment manifest format

Este conteúdo não está disponível em sua língua ainda.

The deployment manifest is a JSON-formatted document generated by Aspire to describe your app’s resources and their relationships. This manifest is consumed by deployment tools to provision and configure infrastructure in target cloud environments.

Create a new Aspire project using the following command:

Create new Aspire project
aspire new --name AspireApp --output AspireApp

Navigate to the newly created project directory:

Navigate to project directory
cd ./AspireApp

Manifest generation is achieved by running the Aspire CLI with the publish command:

Generate manifest
aspire do publish-manifest --output-path ./aspire-manifest.json'

The previous command produces the following output:

11:55:09 (pipeline execution) → Starting pipeline execution...
11:55:09 (publish-manifest) → Starting publish-manifest...
11:55:09 (publish-manifest) i [INF] Published manifest to: ./AspireApp/aspire-manifest.json
11:55:09 (publish-manifest) ✓ publish-manifest completed successfully
11:55:09 (pipeline execution) ✓ Completed successfully
------------------------------------------------------------
✓ 2/2 steps succeeded • Total time: 0.0s
Steps Summary:
0.0 s ✓ pipeline execution
0.0 s ✓ publish-manifest
✓ PIPELINE SUCCEEDED
------------------------------------------------------------

The file generated is the Aspire manifest and is used by tools to support deploying into target cloud environments.

Publishing the manifest from the default starter template for Aspire produces the following JSON output:

aspire-manifest.json
{
"resources": {
"cache": {
"type": "container.v0",
"connectionString": "{cache.bindings.tcp.host}:{cache.bindings.tcp.port}",
"image": "redis:7.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"
}
}
}
}
}

The manifest format JSON consists of a single object called resources, which contains a property for each resource specified in Program.cs (the name argument for each name is used as the property for each of the child resource objects in JSON).

In the previous example, there are two project resources and one Redis cache resource. The webfrontend depends on both the apiservice (project) and cache (Redis) resources.

This dependency is known because the environment variables for the webfrontend contain placeholders that reference the two other resources:

Environment variables with placeholders
"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}"
},

The apiservice resource is referenced by webfrontend using the call WithReference(apiservice) in the AppHost Program.cs file and redis is referenced using the call WithReference(cache):

AppHost.cs
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();

References between project resource types result in service discovery variables being injected into the referencing project. References to well known reference types such as Redis result in connection strings being injected.

A diagram showing which resources contribute to which corresponding placeholder strings.

For more information on how resources in the app model and references between them work, see, Aspire orchestration overview.

Placeholder strings reference the structure of the Aspire manifest:

A diagram showing how the manifest JSON structure maps to placeholder strings.

The final segment of the placeholder string (url in this case) is generated by the tool processing the manifest. There are several suffixes that could be used on the placeholder string:

  • connectionString: For well-known resource types such as Redis. Deployment tools translate the resource in the most appropriate infrastructure for the target cloud environment and then produce an Aspire compatible connection string for the consuming application to use. On container.v0 resources the connectionString field may be present and specified explicitly. This is to support scenarios where a container resource type is referenced using the WithReference extension but is desired to be hosted explicitly as a container.
  • url: For service-to-service references where a well-formed URL is required. The deployment tool produces the url based on the scheme, protocol, and transport defined in the manifest and the underlying compute/networking topology that was deployed.
  • host: The host segment of the URL.
  • port: The port segment of the URL.

Each resource has a type field. When a deployment tool reads the manifest, it should read the type to verify whether it can correctly process the manifest. During the Aspire preview period, all resource types have a v0 suffix to indicate that they’re subject to change. As Aspire approaches release a v1 suffix will be used to signify that the structure of the manifest for that resource type should be considered stable (subsequent updates increment the version number accordingly).

The type field is the only field that is common across all resource types, however, the project.v0, container.v0, and executable.v0 resource types also share the env and bindings fields.

The env field type is a basic key/value mapping where the values might contain placeholder strings.

Bindings are specified in the bindings field with each binding contained within its own field under the bindings JSON object. The fields omitted by the Aspire manifest in the bindings node include:

  • scheme: One of the following values tcp, udp, http, or https.
  • protocol: One of the following values tcp or udp
  • transport: Same as scheme, but used to disambiguate between http and http2.
  • containerPort: Optional, if omitted defaults to port 80.

Some resources generate an inputs field. This field is used to specify input parameters for the resource. The inputs field is a JSON object where each property is an input parameter that’s used in placeholder structure resolution. Resources that have a connectionString, for example, might use the inputs field to specify a password for the connection string:

Connection string with input parameter
"connectionString": "Host={<resourceName>.bindings.tcp.host};Port={<resourceName>.bindings.tcp.port};Username=admin;Password={<resourceName>.inputs.password};"

The connection string placeholder references the password input parameter from the inputs field:

Input parameter definition
"inputs": {
"password": {
"type": "string",
"secret": true,
"default": {
"generate": {
"minLength": 10
}
}
}
}

The preceding JSON snippet shows the inputs field for a resource that has a connectionString field. The password input parameter is a string type and is marked as a secret. The default field is used to specify a default value for the input parameter. In this case, the default value is generated using the generate field, with random string of a minimum length.

The following table is a list of resource types that are explicitly generated by Aspire and extensions developed by the Aspire team:

These resources are available in the 📦 Aspire.Hosting NuGet package.

App model usageManifest resource typeHeading link
AddContainercontainer.v0Container resource type
PublishAsDockerFiledockerfile.v0Dockerfile resource types
AddDatabase (MongoDB)value.v0MongoDB Server resource types
AddMongoDBcontainer.v0MongoDB resource types
AddDatabase (MySQL)value.v0MySQL Server resource types
AddMySqlcontainer.v0MySQL resource types
AddDatabase (Postgres)value.v0Postgres resource types
AddPostgrescontainer.v0Postgres resource types
AddProjectproject.v0Project resource type
AddRabbitMQcontainer.v0RabbitMQ resource types
AddRediscontainer.v0Redis resource type
AddDatabase (SQL Server)value.v0SQL Server resource types
AddSqlServercontainer.v0SQL Server resource types

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");

Example manifest:

Project resource manifest
"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"
}
}
}

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddContainer("mycontainer", "myimage")
.WithEnvironment("LOG_LEVEL", "WARN")
.WithHttpEndpoint(3000);

Example manifest:

Container resource manifest
{
"resources": {
"mycontainer": {
"type": "container.v0",
"image": "myimage:latest",
"env": {
"LOG_LEVEL": "WARN"
},
"bindings": {
"http": {
"scheme": "http",
"protocol": "tcp",
"transport": "http",
"containerPort": 3000
}
}
}
}
}

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddNodeApp("nodeapp", "../nodeapp/app.js")
.WithHttpEndpoint(hostPort: 5031, env: "PORT")
.PublishAsDockerFile();

Example manifest:

Dockerfile resource manifest
{
"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
}
}
}
}
}

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddPostgres("postgres1")
.AddDatabase("shipping");

Example manifest:

Postgres resource manifest
{
"resources": {
"postgres1": {
"type": "container.v0",
"connectionString": "Host={postgres1.bindings.tcp.host};Port={postgres1.bindings.tcp.port};Username=postgres;Password={postgres1.inputs.password}",
"image": "postgres:17.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 is modeled as a container resource container.v0. The following sample shows how they’re added to the app model.

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddRabbitMQ("rabbitmq1");

The previous code produces the following manifest:

RabbitMQ resource manifest
{
"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
}
}
}
}
}
}
}

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddRedis("redis1");

Example manifest:

Redis resource manifest
{
"resources": {
"redis1": {
"type": "container.v0",
"connectionString": "{redis1.bindings.tcp.host}:{redis1.bindings.tcp.port}",
"image": "redis:7.4",
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"containerPort": 6379
}
}
}
}
}

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddSqlServer("sql1")
.AddDatabase("shipping");

Example manifest:

SQL Server resource manifest
{
"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"
}
}
}

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddMongoDB("mongodb1")
.AddDatabase("shipping");

Example manifest:

MongoDB resource manifest
{
"resources": {
"mongodb1": {
"type": "container.v0",
"connectionString": "mongodb://{mongodb1.bindings.tcp.host}:{mongodb1.bindings.tcp.port}",
"image": "mongo:8.0",
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"containerPort": 27017
}
}
},
"shipping": {
"type": "value.v0",
"connectionString": "{mongodb1.connectionString}/shipping"
}
}
}

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddMySql("mysql1")
.AddDatabase("shipping");

Example manifest:

MySQL resource manifest
{
"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:9.1",
"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"
}
}
}

The following resources are available in the 📦 Aspire.Hosting.Azure NuGet package.

App Model usageManifest resource typeHeading link
AddAzureAppConfigurationazure.bicep.v0Azure App Configuration resource types
AddAzureKeyVaultazure.bicep.v0Azure Key Vault resource type
AddAzureRedisazure.bicep.v0Azure Redis resource types
AddAzureServiceBusazure.bicep.v0Azure Service Bus resource type
AddAzureSqlServer(...)azure.bicep.v0Azure SQL resource types
AddAzureSqlServer(...).AddDatabase(...)value.v0Azure SQL resource types
AddAzurePostgresFlexibleServer(...)azure.bicep.v0Azure Postgres resource types
AddAzurePostgresFlexibleServer(...).AddDatabase(...)value.v0Azure Postgres resource types
AddAzureStorageazure.storage.v0Azure Storage resource types
AddBlobsvalue.v0Azure Storage resource types
AddQueuesvalue.v0Azure Storage resource types
AddTablesvalue.v0Azure Storage resource types

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureKeyVault("keyvault1");

Example manifest:

Azure Key Vault resource manifest
{
"resources": {
"keyvault1": {
"type": "azure.bicep.v0",
"connectionString": "{keyvault1.outputs.vaultUri}",
"path": "aspire.hosting.azure.bicep.keyvault.bicep",
"params": {
"principalId": "",
"principalType": "",
"vaultName": "keyvault1"
}
}
}
}

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureServiceBus("sb1")
.AddTopic("topic1", [])
.AddTopic("topic2", [])
.AddQueue("queue1")
.AddQueue("queue2");

Example manifest:

Azure Service Bus resource manifest
{
"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": []
}
]
}
}
}
}

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var storage = builder.AddAzureStorage("images");
storage.AddBlobs("blobs");
storage.AddQueues("queues");
storage.AddTables("tables");

Example manifest:

Azure Storage resource manifest
{
"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}"
}
}
}

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureRedis("azredis1");

Example manifest:

Azure Redis resource manifest
{
"resources": {
"azredis": {
"type": "azure.bicep.v0",
"connectionString": "{azredis.outputs.connectionString}",
"path": "azredis.module.bicep",
"params": {
"principalId": "",
"principalName": ""
}
}
}
}

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureAppConfiguration("appconfig1");

Example manifest:

Azure App Configuration resource manifest
{
"resources": {
"appconfig1": {
"type": "azure.bicep.v0",
"connectionString": "{appconfig1.outputs.appConfigEndpoint}",
"path": "aspire.hosting.azure.bicep.appconfig.bicep",
"params": {
"configName": "appconfig1",
"principalId": "",
"principalType": ""
}
}
}
}

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureSqlServer("sql")
.AddDatabase("inventory");

Example manifest:

Azure SQL resource manifest
{
"resources": {
"sql": {
"type": "azure.bicep.v0",
"connectionString": "Server=tcp:{sql.outputs.sqlServerFqdn},1433;Encrypt=True;Authentication=\"Active Directory Default\"",
"path": "sql.module.bicep",
"params": {
"principalId": "",
"principalName": ""
}
},
"inventory": {
"type": "value.v0",
"connectionString": "{sql.connectionString};Database=inventory"
}
}
}

Example code:

AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzurePostgresFlexibleServer("postgres")
.AddDatabase("db");

Example manifest:

Azure Postgres resource manifest
{
"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"
}
}
}

Resource types supported in the Azure Developer CLI

Section titled “Resource types supported in the Azure Developer CLI”

The Azure Developer CLI (azd) is a tool that can be used to deploy Aspire projects to Azure Container Apps. With the azure.bicep.v0 resource type, cloud-agnostic resource container types can be converted to Azure-specific resources for deployment. The following table shows the mapping between cloud-agnostic and Azure-specific resources:

NameCloud-agnostic APIAzure API
RedisAddRedisAddAzureRedis
PostgresAddPostgresAddAzurePostgresFlexibleServer
SQL ServerAddSqlServerAddAzureSqlServer

When resources as configured as Azure resources, the azure.bicep.v0 resource type is generated in the manifest.

Pergunta & RespondeColaboraComunidadeDiscutirVer