microsoft / microsoft/aspire

AddHelmChart should support running before the application Helm chart (not only after)

Open
#18,647 0 comments 0 reactions 0 assignees View on GitHub
area-deployment kubernetes
Dominant language
C#
Stars
6.3k
Forks
991
Avg merge
2d 15h
Merged PRs (30d)
196

Description

Problem

When calling AddHelmChart() to install cluster-wide infrastructure (e.g. Envoy Gateway, HAProxy Unified
Gateway, cert-manager), the Helm install step is hardcoded as a post-deploy pipeline step — it runs after
the main application Helm chart is deployed.

This means:

1. Gateway API CRDs (installed by the gateway controller) don't exist when kubectl apply creates
Gateway/HTTPRoute resources from the application chart.
2. The first aspire deploy always fails because Gateway resources reference a GatewayClass whose
controller isn't running yet.
3. A second deploy works, but that's a bad experience — and breaks CI/GitOps flows that expect idempotent
single-pass deployment.

Concrete example — our ClusterInfraExtension:

k8s.WithHelm(helm =>
{
helm.WithNamespace("datanex-master");
helm.WithReleaseName("datanext-master-v1");
});

// This runs AFTER the app chart — too late for Gateway resources
k8s.AddHelmChart("haproxy-unified-gateway", "...", "1.0.6")
.WithNamespace("haproxy-gateway-system");

// Application Gateway references gatewayClassName: "haproxy"
// → fails because the HAProxy GatewayClass/controller doesn't exist yet
var gateway = k8s.AddGateway("public")
.WithGatewayClass("haproxy");

Current behavior

The docs (https://aspire.dev/deployment/kubernetes/helm-charts/) confirm external charts are "post-deploy
pipeline steps" — application chart goes first, external charts follow.

Proposed solution

An option to control ordering. A few possible APIs:

Option A — Enum parameter on AddHelmChart:
k8s.AddHelmChart("haproxy-unified-gateway", "...", "1.0.6",
installOrder: HelmChartInstallOrder.BeforeApplication) // AfterApplication (default)
.WithNamespace("haproxy-gateway-system");

Option B — Separate method:
k8s.AddPreDeployHelmChart("haproxy-unified-gateway", "...", "1.0.6")
.WithNamespace("haproxy-gateway-system");

Option C — Let WithPipelineStepFactory override the default DAG wiring:
k8s.AddHelmChart(...)
.WithPipelineStepOverrides(dependsOn: null, requiredBy: [WellKnownPipelineSteps.Deploy]);

Option A or B would be simplest for the common case.

Affected scenario

Any infrastructure chart that provides CRDs, controllers, or webhooks that the application chart's
resources depend on:

- Gateway API controllers (Envoy Gateway, HAProxy Unified Gateway, NGINX Gateway Fabric, Istio)
- cert-manager (application chart includes Certificate resources)
- External secrets operators
- Service mesh control planes

Workaround (painful)

Currently we have to deploy infrastructure charts manually before running aspire deploy:

helm install haproxy-unified-gateway haproxytech/haproxy-unified-gateway \
--version 1.0.6 --namespace haproxy-gateway-system --create-namespace
aspire deploy ...

This defeats the purpose of having AddHelmChart for infrastructure.

Contributor guide

Open the contributing guide

Research direction

Start by tracing the AddHelmChart entry point and its post-deploy pipeline-step wiring, using the Kubernetes Helm charts documentation as context. Compare the proposed ordering APIs and verify that infrastructure charts can run before the application chart while the current after-application behavior remains the default; done should include a single deploy that handles dependent CRDs and controllers.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, helm, kubernetes
Domain
devops, infrastructure
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.