[docs] Troubleshoot skipped Gateways and Ingresses in TLS deploys - #1470
[docs] Troubleshoot skipped Gateways and Ingresses in TLS deploys#1470aspire-repo-bot[bot] wants to merge 1 commit into
Conversation
Documents the warnings emitted when a route-less Gateway or path-less Ingress is skipped during deployment, per microsoft/aspire#19220. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Frontend HTML artifact readyThe latest frontend build uploaded the This comment updates automatically when a new frontend build artifact is uploaded. |
There was a problem hiding this comment.
Pull request overview
Adds troubleshooting guidance to the AKS Kubernetes deployment docs to explain why Aspire intentionally skips materializing route-less Gateways and path-less/default-backend-less Ingresses (and what to change in AppHost configuration to ensure they deploy), aligning the docs with behavior introduced in microsoft/aspire#19220.
Changes:
- Added a new troubleshooting subsection for skipped Ingresses when no paths/default backend are configured.
- Added a new troubleshooting subsection for skipped Gateways when no routes are configured, including the new warning messages and remediation guidance.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/frontend/src/content/docs/deployment/kubernetes-ingress-aks.mdx | Documents that an Ingress with no paths and no default backend is skipped and won’t create TLS/cert resources. |
| src/frontend/src/content/docs/deployment/kubernetes-gateway-aks.mdx | Documents that a Gateway with no WithRoute(...) is skipped, adds warning examples, and explains the cert-manager HTTP-01 implications. |
Suppressed comments (1)
src/frontend/src/content/docs/deployment/kubernetes-gateway-aks.mdx:838
- This recommendation suggests calling
WithTls(issuer), but the rest of the page’s configuration usesWithTls()with aclusterIssuerparameter. Rewording this to “uses TLS with the same ClusterIssuer” avoids implying a single required API shape.
This means the `ClusterIssuer`'s HTTP-01 solver has no eligible Gateway to
attach to. Add `WithRoute(...)` to a Gateway that also calls `WithTls(issuer)`
with the same cluster issuer to resolve this.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| If the Gateway is also annotated with a `clusterIssuer` via `WithTls(issuer)`, | ||
| you may additionally see: | ||
|
|
David Pine (IEvangelist)
left a comment
There was a problem hiding this comment.
Docs-accuracy review — automated (Phase A: claims vs. source · Phase B: doc-tester)
Phase A source of truth: microsoft/aspire @ release/13.5 · SHA 8ab6999850d96e0023670799edbd4bdc245ad63c (PR targets release/13.5; documents microsoft/aspire#19220).
Claims extracted: 10 → verified: 9 · verified-with-nuance: 1 · unverifiable: 0 · contradicted: 0
Phase B (doc-tester): 2 pages exercised (/deployment/kubernetes-gateway-aks/, /deployment/kubernetes-ingress-aks/) · 0 critical · 1 warning · 1 knowledge gap.
Verdict: COMMENT. No claim was contradicted or unverifiable and the doc-tester found no critical issues, so nothing here blocks merge. Two minor items are worth a look: one Phase A wording nuance (kubectl get gateway shorthand) and one Phase B warning/knowledge gap about the WithTls(issuer) call in the new Gateway subsection. Both are optional polish.
Phase A — Claim verification
Every non-narrative claim was located in microsoft/aspire @ release/13.5. No contradicted or unverifiable claims, so there are no inline blocking comments. One claim is verified-with-nuance (A4) — called out below.
⚠️ Nuance worth a look — Claim A4 (kubernetes-gateway-aks.mdx, "Gateway has no routes configured")
earlier versions of Aspire re-selected these Gateways at several points in the deployment pipeline, which caused
aspire deployto pollkubectl get gatewayfor up to 15 minutes waiting for an address that would never appear.
Substance verified. DiscoverGatewayFqdnAsync polls with a Polly retry pipeline of 180 attempts × 5s ≈ ~15 minutes, and its doc comment states "a Gateway that is never created consumes the entire budget before failing" (src/Aspire.Hosting.Kubernetes/KubernetesEnvironmentResource.cs:1556-1593). Nuance: the actual command in code is kubectl get gateway {name} --namespace {ns} -o json; the doc's kubectl get gateway is a readable shorthand. This is accurate as written — noted only for transparency, no change required.
✅ Verified claims (9 verified + 1 verified-with-nuance) — evidence
Evidence paths are in microsoft/aspire @ 8ab6999850d96e0023670799edbd4bdc245ad63c.
kubernetes-gateway-aks.mdx — "Gateway has no routes configured"
- A1 (api-behavior) — a route-less Gateway (no
WithRoute(...)) is skipped entirely; Gateway/routes/TLS cert/load-balancer frontend never created. verified —KubernetesGatewayResource.ShouldMaterialize => Routes.Count > 0(KubernetesGatewayResource.cs:91);ProcessGatewayResourcesdoesif (!ShouldMaterialize) { LogWarning(...); continue; }(KubernetesEnvironmentResource.cs:895-902). - A2 (api-behavior / log output) — warning
Gateway 'public' has no routes configured. The Gateway, routes, TLS certificate, and load-balancer frontend will not be created.verified — exact log template atKubernetesEnvironmentResource.cs:900({GatewayName}→public). - A3 (api-shape) —
WithRoute(...)exists on the Gateway builder. verified —KubernetesGatewayExtensions.cs:103,140; public API surfaceapi/Aspire.Hosting.Kubernetes.cs:105,108. - A4 (api-behavior / historical) — ~15-minute
kubectl get gatewaypolling for an address that never appears. verified-with-nuance — see note above (KubernetesEnvironmentResource.cs:1556-1593). - A5 (api-behavior / log output) — the multi-line
ClusterIssuer 'letsencrypt' has an HTTP-01 solver ...warning. verified — matches exactly atCertManagerExtensions.cs:637-641(issuerletsencrypt, envenv, annotationcert-manager.io/cluster-issuer). - A6 (config-key) — annotation
cert-manager.io/cluster-issuer=letsencrypt. verified —internal const string ClusterIssuerAnnotationKey = "cert-manager.io/cluster-issuer";(CertManagerExtensions.cs:37). - A7 (api-shape) —
WithTls(issuer)exists on the Gateway builder taking a cluster issuer. verified —WithTls(this IResourceBuilder<KubernetesGatewayResource>, IResourceBuilder<CertManagerIssuerResource> issuer)(api/Aspire.Hosting.Kubernetes.cs:41; implCertManagerExtensions.cs:331). - A8 (api-behavior) — the HTTP-01 warning fires when no annotated and routed Gateway adopts the issuer; resolved by
WithRoute(...)on a Gateway that also callsWithTls(issuer). verified —parentGatewaysfilter requiresg.ShouldMaterialize && annotation == issuer.Name; warns when the filtered set is empty (CertManagerExtensions.cs:615-643).
kubernetes-ingress-aks.mdx — "Ingress has no paths configured"
- B1 (api-behavior) — an Ingress with no paths and no default backend is skipped; Ingress + TLS cert never created; no deployment steps run. verified —
KubernetesIngressResource.ShouldMaterialize => Paths.Count > 0 || DefaultBackend is not null(KubernetesIngressResource.cs:94); skip+warnIngress '{IngressName}' has no path rules or default backend configured. The Ingress and its TLS certificate will not be created.(KubernetesEnvironmentResource.cs:685-690). PR's "no paths and no default backend" ≡ source "no path rules or default backend". - B2 (guidance) — add at least one path or a default backend so Aspire materializes it. verified — same
ShouldMaterializecondition (KubernetesIngressResource.cs:94).
Phase B — Doc-tester results (blind new-user perspective, no source code consulted)
Served the PR head (4eff486f2c8b553665512eea19ec5eb6173f3401) locally via pnpm dev at http://localhost:4321/ and navigated with Playwright. Report reproduced verbatim:
Documentation Test Report
Focus Area: PR #1470 troubleshooting subsections for Kubernetes Gateway/Ingress AKS deployment pages
Date: 2026-08-14
Tester: doc-tester agent
Served Base URL:http://localhost:4321/
Served Head SHA:4eff486f2c8b553665512eea19ec5eb6173f3401
Routes Exercised:
http://localhost:4321/deployment/kubernetes-gateway-aks/http://localhost:4321/deployment/kubernetes-gateway-aks/#gateway-has-no-routes-configuredhttp://localhost:4321/deployment/kubernetes-ingress-aks/http://localhost:4321/deployment/kubernetes-ingress-aks/#ingress-has-no-paths-configuredScreenshots:
gateway-no-routes.pngingress-no-paths.pngSummary
Category Passed Failed Warnings Content Accuracy 2 0 1 Code Examples 0 0 0 CLI Commands 0 0 0 Links 2 0 0 Critical Issues
None.
Warnings
Warning 1:
WithTls(issuer)is not explained in the new Gateway troubleshooting subsectionLocation:
http://localhost:4321/deployment/kubernetes-gateway-aks/#gateway-has-no-routes-configured
Issue: The subsection tells readers to resolve the ClusterIssuer warning by usingWithRoute(...)andWithTls(issuer), but the page's earlier AppHost example shows.WithTls()with no argument. As a new user, I could infer thatissuerrelates to theclusterIssuerparameter, but the subsection itself does not show the exact corrected AppHost shape.
Suggestion: Add a one-line example or clarify that readers should use the same cluster issuer value already configured for TLS.Passed Checks
- The PR head loaded locally at
http://localhost:4321/.- Both changed routes loaded successfully and did not render 404 pages.
- The Gateway page's "On this page" navigation includes "Gateway has no routes configured."
- Clicking the Gateway subsection link navigated to
#gateway-has-no-routes-configured.- The Gateway subsection clearly states that a Gateway with no
WithRoute(...)calls is skipped and shows the warning text.- The Gateway subsection explains that adding at least one route causes Aspire to materialize the Gateway.
- The Ingress page's "On this page" navigation includes "Ingress has no paths configured."
- Clicking the Ingress subsection link navigated to
#ingress-has-no-paths-configured.- The Ingress subsection clearly states that an Ingress with no paths and no default backend is skipped.
- The Ingress subsection's guidance to add at least one path or default backend is followable from the surrounding page context, which shows
.WithDefaultBackend(...).Recommendations
- Priority fixes: No critical fixes required.
- Documentation gaps: Clarify the
WithTls(issuer)wording in the Gateway troubleshooting subsection with a concrete AppHost snippet or a cross-reference to the earlier TLS configuration.- Product issues: None discovered from blind documentation testing.
Knowledge Gap: Meaning of
WithTls(issuer)What I needed to know: Whether
issueris a literal variable, theclusterIssuerparameter from earlier on the page, or an overload different from the displayed.WithTls()example.
Source of my knowledge: Inferred from surrounding documentation, not from product source code.
User impact: A new user troubleshooting the warning may know they need a route, but may hesitate over the exact TLS call to use.
Automated docs-accuracy review. Phase A reads microsoft/aspire source (read-only); Phase B runs the doc-tester skill blind to source code against a local render of this PR.
Documents changes from microsoft/aspire#19220
@mitchdennyTargeting
release/13.5— the latest release branch onmicrosoft/aspire.dev— becauserelease/13.6(from the source PR milestone13.6) does not exist there.Why this PR is needed
microsoft/aspire#19220 fixes a class of bugs where a route-less Gateway (no
WithRoute(...)) or a path-less Ingress (no paths and no default backend) — both intentionally skipped during materialization — were still re-selected at several deployment sites. This causedaspire deployto hang for ~15 minutes polling for a Gateway address that would never appear, and could leave cert-managerClusterIssuerHTTP-01 solvers pointing at a Gateway that never exists (certificates stuckPendingwith no warning).After the fix, these resources are consistently skipped everywhere, deployment does not stall, and new warnings name what was omitted:
What changed
src/frontend/src/content/docs/deployment/kubernetes-gateway-aks.mdx: Added a "Gateway has no routes configured" troubleshooting subsection explaining both new warnings and how to resolve them (addWithRoute(...)).src/frontend/src/content/docs/deployment/kubernetes-ingress-aks.mdx: Added an "Ingress has no paths configured" troubleshooting subsection explaining that a path-less/backend-less Ingress is skipped entirely.Both changes update existing pages (no new pages created), inserted into the existing "Troubleshooting" sections following the surrounding doc's conventions.