Skip to content

docs: fix inaccurate Customize Azure resources page#946

Draft
IEvangelist wants to merge 1 commit into
mainfrom
dapine/fix-customize-azure-resources-246
Draft

docs: fix inaccurate Customize Azure resources page#946
IEvangelist wants to merge 1 commit into
mainfrom
dapine/fix-customize-azure-resources-246

Conversation

@IEvangelist
Copy link
Copy Markdown
Member

@IEvangelist IEvangelist commented May 14, 2026

Fixes #246

Problem

The page at https://aspire.dev/integrations/cloud/azure/customize-resources/ contains three concrete API inaccuracies that mislead readers building custom Bicep workflows. Verified each claim against the microsoft/aspire main source tree and against the live page on aspire.dev (see Evidence below).

Changes

All edits are scoped to src/frontend/src/content/docs/integrations/cloud/azure/customize-resources.mdx plus one allowlist entry pair in src/frontend/tests/unit/twoslash-blocks-audit.ts (see Twoslash note below).

  • AddBicepTemplate instead of AddAzureBicepResource in the C# Use custom Bicep files sample. AddAzureBicepResource is not a public API; the real APIs are AddBicepTemplate(name, bicepFile) and AddBicepTemplateString(name, bicepContent). The TypeScript sample was already using the correct addBicepTemplate name.
  • Replaced .WithReference(storage) on the bicep resource with .WithEnvironment("STORAGE_CONNECTION_STRING", storage.GetOutput("connectionString")). AzureBicepResource does not implement IResourceWithConnectionString, so the original snippet did not compile. Showing GetOutput here also addresses one of the reporter's wishlist items (consuming outputs from a custom Bicep template).
  • Rewrote Inspect generated Bicep. Running the AppHost locally (aspire run) does not write Bicep into the project — local provisioning compiles each module into a Directory.CreateTempSubdirectory("aspire") location (see AzureProvisioningResource.cs and AzureBicepResource.cs). Updated the steps to use aspire publish (or aspire deploy) and to look in the aspire-output folder (the publish/deploy default per PublishCommandStrings.resx — "Defaults to the AppHost directory's 'aspire-output' folder if not specified"). Added a note callout calling out the difference and a tip callout pointing to the Azure Portal Export template trick.
  • Replaced the hallucinated SubnetReference example in Add Azure resources to the infrastructure with the idiomatic Aspire pattern using AzurePrivateEndpointExtensions.AddPrivateEndpoint (from Aspire.Hosting.Azure.Network). Added a TypeScript note that the high-level builders are C#-only today, plus a fallback paragraph pointing readers at ConfigureInfrastructure + Azure.Provisioning for advanced needs not covered by Aspire-native builders.
  • New Pass parameters and read outputs subsection under Custom Bicep templates with C# and TypeScript samples for AddParameter(name, secret: true), WithParameter(name, parameterResource), and GetOutput(name). Added a bulleted list of the supported WithParameter value types (ParameterResource, BicepOutputReference, ReferenceExpression, IResourceWithConnectionString, EndpointReference) and a LearnMore link to the playground/bicep sample for end-to-end scenarios — closes the wishlist items in the issue.
  • Added a tip about AddBicepTemplateString / addBicepTemplateString for inline Bicep snippets.
  • See also: added the playground/bicep sample link.

Evidence

Confirmed the issue still reproduces on the live aspire.dev page today via Playwright + DOM probe:

hasAddAzureBicepResource:    true  // "Use custom Bicep files" C# tab
hasInfraDir:                 true  // "Inspect generated Bicep" steps
hasPrivateEndpointConstructor: true // "Add Azure resources to the infrastructure"
hasSubnetReference:          true  // ...same section
hasAddBicepTemplate:         false // C# tab uses the wrong name

Quoted before/after for each section:

Use custom Bicep files (C#):

- var storage = builder.AddAzureBicepResource(
-     name: "storage",
-     bicepFilePath: "./custom-storage.bicep")
+ var storage = builder.AddBicepTemplate("storage", "./custom-storage.bicep")
      .WithParameter("storageAccountName", "mystorageaccount");

  builder.AddProject<Projects.WebApp>("webapp")
-        .WithReference(storage);
+        .WithEnvironment("STORAGE_CONNECTION_STRING", storage.GetOutput("connectionString"));

Add Azure resources to the infrastructure (C#):

- storage.ConfigureInfrastructure(infra =>
- {
-     var privateEndpoint = new PrivateEndpoint("storagepe")
-     {
-         Location = "eastus",
-         Subnet = new SubnetReference
-         {
-             Id = "/subscriptions/.../subnets/mysubnet"
-         }
-     };
-     infra.Add(privateEndpoint);
- });
+ var vnet = builder.AddAzureVirtualNetwork("vnet");
+ var peSubnet = vnet.AddSubnet("pe-subnet", "10.0.1.0/24");
+
+ var storage = builder.AddAzureStorage("storage");
+ var blobs = storage.AddBlobs("blobs");
+
+ peSubnet.AddPrivateEndpoint(blobs);

Inspect generated Bicep:

- 1. Run your AppHost locally.
- 2. Open the `./infra` directory inside your AppHost project.
- 3. Review the generated `.bicep` files to verify your customizations.
+ 1. From the AppHost directory, run `aspire publish` (or `aspire deploy`).
+ 2. Open the `aspire-output` folder next to your AppHost project. To write somewhere else, pass `--output-path` to the publish or deploy command.
+ 3. Review the generated `.bicep` files to verify your customizations.

How I verified

  1. Fast-forwarded microsoft/aspire.dev:main and microsoft/aspire:main, then rebased dapine/fix-customize-azure-resources-246 onto the new tip so the PR diff is exactly two files.
  2. For each claim in the issue, located the implementing C# file in microsoft/aspire and the matching polyglot TypeScript usage in tests/PolyglotAppHosts/ to confirm the real API surface (signatures and call patterns).
  3. Loaded https://aspire.dev/integrations/cloud/azure/customize-resources/ via Playwright and confirmed all three inaccuracies are still present today (DOM probe above).
  4. Ran the repo's twoslash + lint validation against the change:
    • pnpm --dir src/frontend test:unit:twoslash-blocksPASS (the two KNOWN_TYPE_BUGS entries cleanly cover the generator's collapsed-overload bug).
    • pnpm --dir src/frontend test:unit:llms-txtPASS.
    • pnpm --dir src/frontend lintPASS for the two changed files (pre-existing repo-wide warnings unrelated to this branch).

Twoslash note

The two new TypeScript twoslash blocks call withParameter(name, { value }) with a string and a ParameterResource. The polyglot test tests/PolyglotAppHosts/Aspire.Hosting.Azure/TypeScript/apphost.ts uses this exact pattern, so the runtime API supports it. However, the current aspire.d.ts generator only emits the last withParameter overload ({ value?: EndpointReference }), so twoslash reports ts(2769) — No overload matches this call. Added two KNOWN_TYPE_BUGS entries with a clear label so the regression gate stays precise; the entries fall out automatically once the generator emits all overloads (separate, pre-existing concern in scripts/generate-twoslash-types.ts).

Out of scope

  • The deeper type-shape gap in the twoslash type generator — only the last overload of withParameter is emitted to aspire.d.ts. Worth a follow-up issue against scripts/generate-twoslash-types.ts, but outside the scope of this docs fix.
  • A dedicated walkthrough of the existing Bicep keyword (one of the reporter's wishlist items) — the LearnMore here points readers at the playground/bicep sample, and a full guide can land as a follow-up.

Reported in #246 by @kamranayub. Verified each claim against
microsoft/aspire main and against the live page on aspire.dev.

Three concrete inaccuracies fixed:

* "Use custom Bicep files" called `builder.AddAzureBicepResource(...)`,
  which is not a real API. Replaced with `AddBicepTemplate(name, path)`
  (and the matching `addBicepTemplate` for the TypeScript sample). The
  C# sample also called `.WithReference(storage)` on a bare
  `AzureBicepResource`, which doesn't compile because that resource
  doesn't implement `IResourceWithConnectionString`. Replaced with
  `WithEnvironment("STORAGE_CONNECTION_STRING", storage.GetOutput(...))`,
  which is the correct way to consume a Bicep output.

* "Inspect generated Bicep" said to run the AppHost locally and look in
  an `./infra` folder. Local provisioning compiles Bicep into a temp
  directory and never writes it into the project. Rewrote the steps to
  use `aspire publish` (or `aspire deploy`) and look in the
  `aspire-output` folder (the publish/deploy default).

* "Add Azure resources to the infrastructure" used a `SubnetReference`
  type that doesn't exist in `Azure.Provisioning.Network`. Replaced the
  example with the idiomatic Aspire pattern using
  `vnet.AddSubnet(...).AddPrivateEndpoint(target)` from
  `Aspire.Hosting.Azure.Network`, plus a note that authors can fall back
  to `ConfigureInfrastructure` + `Azure.Provisioning` constructs when no
  Aspire-native builder fits.

Also addressed the reporter's wishlist for "passing parameters and
consuming outputs" with a new "Pass parameters and read outputs"
subsection that demonstrates `AddParameter(name, secret: true)`,
`WithParameter(name, parameterResource)`, and `GetOutput(name)` end-to-end
in C# and TypeScript, and lists the supported `WithParameter` value types
(ParameterResource, BicepOutputReference, ReferenceExpression,
IResourceWithConnectionString, EndpointReference). Added a `LearnMore`
pointer to the `playground/bicep` sample for fuller scenarios, and a
short `Aside` about `AddBicepTemplateString` for inline Bicep.

The two new TypeScript twoslash blocks call
`withParameter(name, { value })` with a string and a `ParameterResource`,
which the polyglot tests in `tests/PolyglotAppHosts/Aspire.Hosting.Azure/TypeScript/apphost.ts`
exercise verbatim. The current `aspire.d.ts` generator only emits the
last `withParameter` overload, so twoslash sees `{ value?: EndpointReference }`
only and reports `ts(2769)`. Added two `KNOWN_TYPE_BUGS` entries with a
clear label so the regression gate stays precise; the entries will fall
out automatically once the generator emits all overloads.

Fixes #246

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@IEvangelist IEvangelist force-pushed the dapine/fix-customize-azure-resources-246 branch from 5aee9a1 to 7e21b4b Compare May 14, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: Customize Azure resources has inaccurate docs

1 participant