Skip to content

Refactor “Publisher” Concept into Dual-Publisher + Compute-Environment Model #9089

@davidfowl

Description

@davidfowl

Summary

We’re simplifying the pipeline but expanding the number of scenarios we can support:

Old World New World
One purpose-built publisher per compute target Two core publishers
1. ManifestPublisher (legacy, AZD-compatible)
2. Publisher (walks the resource graph and lets each environment resource emit its own files)
Publishers own every artifact Environment resources generate their own artifacts with an EmitToDisk callback
CLI asks which publisher to run CLI just runs the graph once; all environments present in the model are emitted

Environment Resources & Responsibilities

Resource Replaces EmitToDisk Output
KubernetesEnvironmentResource KubernetesPublisher Standard K8s YAML / Helm (logic moved 1-for-1)
DockerComposeEnvironmentResource DockerComposePublisher docker-compose.yaml, .env, etc.
AzureEnvironmentResource (new) AzurePublisher main.bicep (and may mutate the resource-group definition)

Workflow

  1. GraphPublisher traverses the app graph, discovers the three environment resources above, and calls Emit(outputCtx) on each.

  2. ManifestPublisher still runs (unless suppressed) to keep AZD workflows working.

  3. CLI: aspire publish emits all environments present; no “select publisher” prompt.


Tasks

  • Define Publisher annotation/interface and plumbing.
  • Build Publisher (iterate graph ➜ invoke Emit).
  • Port logic into KubernetesEnvironmentResource and DockerComposeEnvironmentResource.
  • Docs / migration guide (“Manifest vs Graph publishing”).

Open Question

Annotation vs Interface for EmitToDisk—annotation is easiest to retrofit; interface offers compile-time safety.

Side bar

📝 Current Architecture in 9.3

1. Who “owns” publishing today?

Environment Publisher How compute resources attach What it writes
DockerComposePublisher Resource calls PublishAsDockerComposeService() docker-compose.yaml, .env, build contexts
KubernetesPublisher Resource calls PublishAsKubernetesDeployment() (no ingress abstraction yet) deployment.yaml, service.yaml, basic K8s objects
AzurePublisher Any resource whose class inherits AzureBicepResource main.bicep + parameter files
  • In 9.3 the environment is the publisher.
  • Each publisher walks only its own set† of compute resources and emits artifacts for them.
    † “Compute resources” = projects, containers, executables, etc.

2. Why this is limiting

  • You can run only one compute environment per resource.

    • Want a front-end in App Service, a back-end in Azure Container Apps, and a worker in AKS? You can’t model that today.
  • There’s no way to emit artifacts for multiple environments in one pass; each publisher thinks it owns “everything.”


3. Direction we’re heading

  • Compute environments own compute resources, but resources can declare zero or one explicit environment:

    • If unspecified, the resource is emitted into all defined environments.
    • This lets a single aspire publish generate Compose and K8s and Azure artifacts side-by-side.
  • Composite setups become possible:

    • e.g. AKS by re-using AzureEnvironmentResource (RG + infra), adding a future AzureKubernetesClusterResource, and plugging in the existing KubernetesEnvironmentResource.

This sets the stage for the dual-publisher model (Manifest + Graph) and the new EmitToDisk-based environment resources described above.


Sub-issues

Metadata

Metadata

Assignees

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions