Skip to content

docs: fix inaccurate APIs and instructions on Customize Azure resources#942

Open
IEvangelist wants to merge 1 commit into
mainfrom
dapine/fix-customize-azure-docs-246
Open

docs: fix inaccurate APIs and instructions on Customize Azure resources#942
IEvangelist wants to merge 1 commit into
mainfrom
dapine/fix-customize-azure-docs-246

Conversation

@IEvangelist
Copy link
Copy Markdown
Member

Fixes #246

Summary

The Customize Azure resources page contained three documented APIs / behaviors that don't match the current product. New users following the page can't compile the samples and can't find the files the page says will appear. This PR replaces those samples with ones that match the current Aspire.Hosting.Azure, Aspire.Hosting.Azure.Network, and Azure.Provisioning APIs.

Changes

  • "Use custom Bicep files" (C# tab) — Replaced the non-existent builder.AddAzureBicepResource(name: "storage", bicepFilePath: "./custom-storage.bicep") with the actual method, builder.AddBicepTemplate("storage", "./custom-storage.bicep"). Added a one-liner pointing readers at AddBicepTemplateString for inline templates.
  • "Add Azure resources to the infrastructure" — Rewrote the PrivateEndpoint C# sample to use real types from Azure.Provisioning.Network: dropped the fake SubnetReference initializer, set privateEndpoint.Subnet.Id via an Azure.Provisioning.ProvisioningParameter, and added the missing PrivateLinkServiceConnections.Add(new NetworkPrivateLinkServiceConnection { ... }) so the emitted Bicep is actually valid. Added a tip <Aside> pointing readers at the higher-level AddPrivateEndpoint extension in the Azure Virtual Network integration, which is the idiomatic API for most users. Added a short sentence explaining which namespaces the types come from.
  • "Inspect generated Bicep" — Replaced the inaccurate "run AppHost locally → open ./infra" instructions with the aspire publish -o ./infra workflow. Added a <Aside type="note"> explaining that aspire run writes Bicep to a temp directory used by the local provisioner — it does not populate ./infra in the AppHost project. Updated the directory-walkthrough to describe the actual emitted layout (main.bicep plus one module per resource).

Evidence the issue still reproduces on the live site

Verified before editing by browsing https://aspire.dev/integrations/cloud/azure/customize-resources/ with playwright-cli on 2026-05-13:

  • The C# sample for "Use custom Bicep files" still shows builder.AddAzureBicepResource(name: "storage", bicepFilePath: "./custom-storage.bicep") — that method does not exist in Aspire.Hosting.Azure. The only public surface is AddBicepTemplate(name, bicepFile) / AddBicepTemplateString(name, bicepContent) defined in AzureBicepResourceExtensions.cs.
  • The PrivateEndpoint sample assigns Subnet = new SubnetReference { Id = "..." }SubnetReference is not a real type in Azure.Provisioning.Network. In Aspire's own code (AzurePrivateEndpointExtensions.cs) the Subnet.Id property is set directly. The sample is also missing the PrivateLinkServiceConnections collection, which means the Bicep it produces would be incomplete.
  • The "Inspect generated Bicep" steps say "Run your AppHost locally" and "Open the ./infra directory inside your AppHost project". Running aspire run does not populate a project-local ./infraAzureProvisioningResource.GetBicepTemplateFile writes to Directory.CreateTempSubdirectory("aspire"). Bicep only lands on disk in a stable location when you run aspire publish -o <path>.

What doc-tester validated

  • Code samples cross-checked against the matching product APIs in microsoft/aspire:
    • AddBicepTemplate / AddBicepTemplateStringAspire.Hosting.Azure/AzureBicepResourceExtensions.cs
    • PrivateEndpoint.Subnet.Id + PrivateLinkServiceConnections.Add(new NetworkPrivateLinkServiceConnection { … })Aspire.Hosting.Azure.Network/AzurePrivateEndpointExtensions.cs
    • aspire publish -o <path> emission layout — Aspire.Hosting.Azure/AzurePublishingContext.cs
  • Internal link to AddPrivateEndpoint follows the doc link conventions: site-relative (/integrations/...), trailing slash on the page, and #add-private-endpoints matches the rendered heading id on the target page.
  • pnpm exec astro sync — passes.
  • Local Astro dev server render: all three edited sections render without raw fence artifacts, the new anchor link resolves to the right heading, the old strings (AddAzureBicepResource, SubnetReference) are no longer present, and the new strings (AddBicepTemplate(, NetworkPrivateLinkServiceConnection, new ProvisioningParameter, aspire publish -o ./infra) are present.

How I verified

  1. cd D:\GitHub\aspire.dev\src\frontend
  2. pnpm exec astro sync — succeeds.
  3. pnpm dev and browse to http://localhost:<port>/integrations/cloud/azure/customize-resources/:
    • Confirm the rewritten "Add Azure resources to the infrastructure" code block reads cleanly.
    • Click the AddPrivateEndpoint link — it should jump to the Add private endpoints heading on the Azure Virtual Network page.
    • Confirm the C# tab of "Use custom Bicep files" shows AddBicepTemplate(...) (not AddAzureBicepResource).
    • Confirm "Inspect generated Bicep" now describes aspire publish -o ./infra and notes that aspire run uses a temp directory.

Out of scope (deferring to a follow-up)

The reporter listed three additional wishlist items in the issue body that are orthogonal to the inaccuracies above and would meaningfully grow the page. I've kept this PR focused on the broken/inaccurate content so it stays easy to review. Tracking these as a follow-up:

  • Passing ParameterResource (or other resource expressions) through to a custom Bicep template.
  • Reading outputs from an AddBicepTemplate resource and using them elsewhere in the AppHost.
  • Using the Bicep existing keyword in a custom template.

The Customize Azure resources page documented APIs that don't exist and described run-time behavior that doesn't match the product:

- `AddAzureBicepResource(name, bicepFilePath)` is not a real method. Replaced with the actual `AddBicepTemplate(name, bicepFile)`, and mentioned `AddBicepTemplateString` for inline templates.

- The `PrivateEndpoint` sample used a non-existent `SubnetReference` type and was missing `PrivateLinkServiceConnections`. Rewrote the sample to set `Subnet.Id` via a `ProvisioningParameter` and to add a `NetworkPrivateLinkServiceConnection`, matching the pattern Aspire uses internally. Added a tip pointing users at the higher-level `AddPrivateEndpoint` extension for the common case.

- `Inspect generated Bicep` told users to `Run your AppHost locally` and open `./infra`. At run time Aspire emits Bicep to a temp subdirectory; `./infra` is only populated by `aspire publish -o ./infra`. Replaced the steps with the publish workflow and noted the run-time behavior in an Aside.

Fixes #246

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@IEvangelist IEvangelist marked this pull request as ready for review May 13, 2026 21:19
Copilot AI review requested due to automatic review settings May 13, 2026 21:19
@IEvangelist IEvangelist requested a review from eerhardt as a code owner May 13, 2026 21:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Updates the Customize Azure resources documentation to match current Aspire/Azure Provisioning APIs and the actual Bicep generation workflow, so readers can compile samples and find the expected output files.

Changes:

  • Replaced a non-existent AddAzureBicepResource doc sample with AddBicepTemplate (and referenced AddBicepTemplateString for inline templates).
  • Rewrote the PrivateEndpoint ConfigureInfrastructure sample to use real Azure.Provisioning.Network types and produce valid Bicep.
  • Corrected “Inspect generated Bicep” instructions to use aspire publish -o ... and documented the emitted layout.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +409 to +411
var account = infra.GetProvisionableResources()
.OfType<StorageAccount>()
.Single();
});
```

`PrivateEndpoint` and `NetworkPrivateLinkServiceConnection` come from the `Azure.Provisioning.Network` namespace, and `ProvisioningParameter` comes from `Azure.Provisioning`. Adding a `ProvisioningParameter` lets you pass the subnet ID into the generated Bicep at deployment time.
Comment on lines +409 to +411
var account = infra.GetProvisionableResources()
.OfType<StorageAccount>()
.Single();
var subnetId = new ProvisioningParameter("subnetId", typeof(string));
infra.Add(subnetId);

var privateEndpoint = new PrivateEndpoint("storagepe");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a contrived example - especially since our Aside even says "don't do this". Is there a better scenario we could illustrate here? Setting some other properties on the Storage account?

One idea is to enable an Microsoft.Storage/storageAccounts/inventoryPolicies

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

3 participants