Skip to content

Add polyglot Azure provisioning proxy SDKs - #19675

Merged
Sébastien Ros (sebastienros) merged 25 commits into
mainfrom
sebros/polyglot-provisioning-sdks
Sep 15, 2026
Merged

Sébastien Ros (sebastienros) merged 25 commits into
mainfrom
sebros/polyglot-provisioning-sdks

Conversation

@sebastienros

@sebastienros Sébastien Ros (sebastienros) commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

Description

Polyglot AppHosts cannot currently use Azure Provisioning SDK types inside ConfigureInfrastructure because exporting each SDK wholesale would create an unbounded ATS surface. This change adds opt-in, integration-specific proxy packages so TypeScript, Python, Go, and Java AppHosts can customize generated Azure infrastructure with the same provisioning model used by C# AppHosts.

The implementation adds:

  • A standalone Azure provisioning source generator that emits bounded ATS proxies from integration-selected root types.
  • A shared Aspire.Hosting.Azure.Provisioning package for Bicep literals, expressions, secure values, declarations, resource references, and provisionable-resource handles.
  • Experimental proxy packages for Application Insights, Cognitive Services, Container Registry, Cosmos DB, Event Hubs, Key Vault, Operational Insights, Search, Service Bus, SQL, Storage, and Web PubSub.
  • A provider-neutral AspireExportProviderAttribute contract so third-party generators can satisfy export coverage without adding provider-specific behavior to the core analyzer.
  • Experimental diagnostics and preview package metadata for the new extension points.

Generated BicepValue<T> setters accept either compatible language primitives or shared Bicep expressions. Assignments use the Azure Provisioning value APIs so expression, resource-reference, output, and secure-value metadata is preserved.

User-facing usage

C# AppHost:

var vault = builder.AddAzureKeyVault("vault")
    .ConfigureInfrastructure(infrastructure =>
    {
        var service = infrastructure.GetProvisionableResources()
            .OfType<KeyVaultService>()
            .Single();

        service.Properties.EnablePurgeProtection = true;
        service.Properties.SoftDeleteRetentionInDays = 30;
        service.Properties.Sku.Name = KeyVaultSkuName.Premium;
    });

TypeScript AppHost with Aspire.Hosting.Azure.Provisioning.KeyVault:

const vault = await builder.addAzureKeyVault("vault");

await vault.configureInfrastructure(async infrastructure => {
    const service = await infrastructure.getKeyVaultService();
    const properties = await service.properties.get();
    const sku = await properties.sku.get();
    const bicep = infrastructure.bicep();
    const retention = bicep.binary(
        bicep.integer(20),
        BinaryBicepOperator.Add,
        bicep.integer(10));

    await properties.enablePurgeProtection.set(true);
    await properties.softDeleteRetentionInDays.set(retention);
    await sku.name.set(KeyVaultSkuName.Premium);
});

Validation includes focused runtime tests for literal, expression, secure, conversion, interpolation, and diagnostic behavior; analyzer coverage for generated export providers; packaging of all 14 new packages; aggregate SDK compilation for TypeScript, Go, and Java; focused cross-package enum-collision compilation for Python; and per-integration Python SDK compilation for every service package. Existing repository ConfigureInfrastructure usages were audited against the proxy model and are representable by the shared bridge and service packages.

Fixes # (issue)

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 39713d65-4058-4992-9484-65088a927bbc
Copilot AI balanced review requested due to automatic review settings August 25, 2026 19:41
@github-actions github-actions Bot added the area-integrations Issues pertaining to Aspire Integrations packages label Aug 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 19675

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 19675"

@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds bounded, opt-in Azure Provisioning proxies so polyglot AppHosts can customize generated Azure infrastructure.

Changes:

  • Adds a provisioning proxy source generator and shared Bicep value bridge.
  • Adds experimental proxy packages for 12 Azure integrations.
  • Expands analyzer and multi-language validation coverage.

Reviewed changes

Copilot reviewed 160 out of 160 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Aspire.slnx Registers new projects.
docs/list-of-diagnostics.md Documents experimental diagnostics.
src/Aspire.Hosting/Ats/AspireExportProviderAttribute.cs Adds generator-provider marker.
src/Aspire.Hosting.Integration.Analyzers/AspireExportAnalyzer.cs Recognizes generated export providers.
src/Aspire.Hosting.CodeGeneration.Java/AtsJavaCodeGenerator.cs Restricts handle bridging to known handles.
src/Aspire.Hosting.Azure.Provisioning.Generators/AspireProvisioningProxyGenerator.cs Generates bounded ATS proxies.
src/Aspire.Hosting.Azure.Provisioning.Generators/Aspire.Hosting.Azure.Provisioning.Generators.csproj Packages the generator.
src/Aspire.Hosting.Azure.Provisioning.Generators/README.md Documents generator usage.
src/Aspire.Hosting.Azure.Provisioning/Aspire.Hosting.Azure.Provisioning.csproj Defines shared proxy package.
src/Aspire.Hosting.Azure.Provisioning/AtsTypeMappings.cs Selects shared identity root.
src/Aspire.Hosting.Azure.Provisioning/BicepStringBuilderProxy.cs Bridges interpolated strings.
src/Aspire.Hosting.Azure.Provisioning/BicepValueFactory.cs Adds Bicep expression factories.
src/Aspire.Hosting.Azure.Provisioning/BicepValueProxy.cs Preserves Bicep value metadata.
src/Aspire.Hosting.Azure.Provisioning/ExperimentalAssemblyInfo.cs Marks packages experimental.
src/Aspire.Hosting.Azure.Provisioning/ProvisionableResourceProxy.cs Wraps provisionable resources.
src/Aspire.Hosting.Azure.Provisioning/ProvisioningDeclarationExtensions.cs Exposes Bicep declarations.
src/Aspire.Hosting.Azure.Provisioning/README.md Documents shared bridge.
src/Aspire.Hosting.Azure.Provisioning.ApplicationInsights/Aspire.Hosting.Azure.Provisioning.ApplicationInsights.csproj Adds Application Insights proxy package.
src/Aspire.Hosting.Azure.Provisioning.ApplicationInsights/AtsTypeMappings.cs Selects Application Insights roots.
src/Aspire.Hosting.Azure.Provisioning.ApplicationInsights/README.md Documents package usage.
src/Aspire.Hosting.Azure.Provisioning.CognitiveServices/Aspire.Hosting.Azure.Provisioning.CognitiveServices.csproj Adds Cognitive Services proxy package.
src/Aspire.Hosting.Azure.Provisioning.CognitiveServices/AtsTypeMappings.cs Selects Cognitive Services roots.
src/Aspire.Hosting.Azure.Provisioning.CognitiveServices/README.md Documents package usage.
src/Aspire.Hosting.Azure.Provisioning.ContainerRegistry/Aspire.Hosting.Azure.Provisioning.ContainerRegistry.csproj Adds Container Registry proxy package.
src/Aspire.Hosting.Azure.Provisioning.ContainerRegistry/AtsTypeMappings.cs Selects registry roots.
src/Aspire.Hosting.Azure.Provisioning.ContainerRegistry/README.md Documents package usage.
src/Aspire.Hosting.Azure.Provisioning.CosmosDB/Aspire.Hosting.Azure.Provisioning.CosmosDB.csproj Adds Cosmos DB proxy package.
src/Aspire.Hosting.Azure.Provisioning.CosmosDB/AtsTypeMappings.cs Selects Cosmos DB roots.
src/Aspire.Hosting.Azure.Provisioning.CosmosDB/README.md Documents package usage.
src/Aspire.Hosting.Azure.Provisioning.EventHubs/Aspire.Hosting.Azure.Provisioning.EventHubs.csproj Adds Event Hubs proxy package.
src/Aspire.Hosting.Azure.Provisioning.EventHubs/AtsTypeMappings.cs Selects Event Hubs roots.
src/Aspire.Hosting.Azure.Provisioning.EventHubs/README.md Documents package usage.
src/Aspire.Hosting.Azure.Provisioning.KeyVault/Aspire.Hosting.Azure.Provisioning.KeyVault.csproj Adds Key Vault proxy package.
src/Aspire.Hosting.Azure.Provisioning.KeyVault/AtsTypeMappings.cs Selects Key Vault roots.
src/Aspire.Hosting.Azure.Provisioning.KeyVault/README.md Documents package usage.
src/Aspire.Hosting.Azure.Provisioning.OperationalInsights/Aspire.Hosting.Azure.Provisioning.OperationalInsights.csproj Adds Operational Insights proxy package.
src/Aspire.Hosting.Azure.Provisioning.OperationalInsights/AtsTypeMappings.cs Selects workspace roots.
src/Aspire.Hosting.Azure.Provisioning.OperationalInsights/README.md Documents package usage.
src/Aspire.Hosting.Azure.Provisioning.Search/Aspire.Hosting.Azure.Provisioning.Search.csproj Adds Search proxy package.
src/Aspire.Hosting.Azure.Provisioning.Search/AtsTypeMappings.cs Selects Search roots.
src/Aspire.Hosting.Azure.Provisioning.Search/README.md Documents package usage.
src/Aspire.Hosting.Azure.Provisioning.ServiceBus/Aspire.Hosting.Azure.Provisioning.ServiceBus.csproj Adds Service Bus proxy package.
src/Aspire.Hosting.Azure.Provisioning.ServiceBus/AtsTypeMappings.cs Selects Service Bus roots.
src/Aspire.Hosting.Azure.Provisioning.ServiceBus/README.md Documents package usage.
src/Aspire.Hosting.Azure.Provisioning.Sql/Aspire.Hosting.Azure.Provisioning.Sql.csproj Adds SQL proxy package.
src/Aspire.Hosting.Azure.Provisioning.Sql/AtsTypeMappings.cs Selects SQL roots.
src/Aspire.Hosting.Azure.Provisioning.Sql/README.md Documents package usage.
src/Aspire.Hosting.Azure.Provisioning.Storage/Aspire.Hosting.Azure.Provisioning.Storage.csproj Adds Storage proxy package.
src/Aspire.Hosting.Azure.Provisioning.Storage/AtsTypeMappings.cs Selects Storage roots.
src/Aspire.Hosting.Azure.Provisioning.Storage/README.md Documents package usage.
src/Aspire.Hosting.Azure.Provisioning.WebPubSub/Aspire.Hosting.Azure.Provisioning.WebPubSub.csproj Adds Web PubSub proxy package.
src/Aspire.Hosting.Azure.Provisioning.WebPubSub/AtsTypeMappings.cs Selects Web PubSub roots.
src/Aspire.Hosting.Azure.Provisioning.WebPubSub/README.md Documents package usage.
tests/Aspire.Hosting.Azure.Provisioning.Tests/Aspire.Hosting.Azure.Provisioning.Tests.csproj Adds runtime proxy tests.
tests/Aspire.Hosting.Azure.Provisioning.Tests/BicepValueProxyTests.cs Tests value and security preservation.
tests/Aspire.Hosting.Analyzers.Tests/AspireExportAnalyzerTests.cs Tests provider recognition.
tests/PolyglotAppHosts/Aspire.Hosting.Azure/TypeScript/aspire.config.json Adds TypeScript proxy packages.
tests/PolyglotAppHosts/Aspire.Hosting.Azure/TypeScript/apphost.mts Exercises identity expressions.
tests/PolyglotAppHosts/Aspire.Hosting.Azure/Python/aspire.config.json Adds Python proxy packages.
tests/PolyglotAppHosts/Aspire.Hosting.Azure/Python/apphost.py Exercises identity proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure/Java/aspire.config.json Adds Java proxy packages.
tests/PolyglotAppHosts/Aspire.Hosting.Azure/Java/AppHost.java Exercises identity proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure/Go/aspire.config.json Adds Go proxy packages.
tests/PolyglotAppHosts/Aspire.Hosting.Azure/Go/apphost.go Exercises identity proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ApplicationInsights/TypeScript/aspire.config.json Adds TypeScript proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ApplicationInsights/TypeScript/apphost.mts Exercises component proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ApplicationInsights/Python/aspire.config.json Adds Python proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ApplicationInsights/Python/apphost.py Exercises component proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ApplicationInsights/Java/aspire.config.json Adds Java proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ApplicationInsights/Java/AppHost.java Exercises component proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ApplicationInsights/Go/aspire.config.json Adds Go proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ApplicationInsights/Go/apphost.go Exercises component proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CognitiveServices/TypeScript/aspire.config.json Adds TypeScript proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CognitiveServices/TypeScript/apphost.mts Exercises account proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CognitiveServices/Python/aspire.config.json Adds Python proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CognitiveServices/Python/apphost.py Exercises account proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CognitiveServices/Java/aspire.config.json Adds Java proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CognitiveServices/Java/AppHost.java Exercises account proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CognitiveServices/Go/aspire.config.json Adds Go proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CognitiveServices/Go/apphost.go Exercises account proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ContainerRegistry/TypeScript/aspire.config.json Adds TypeScript proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ContainerRegistry/TypeScript/apphost.mts Exercises registry task proxies.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ContainerRegistry/Python/aspire.config.json Adds Python proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ContainerRegistry/Python/apphost.py Exercises registry proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ContainerRegistry/Java/aspire.config.json Adds Java proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ContainerRegistry/Java/AppHost.java Exercises registry proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ContainerRegistry/Go/aspire.config.json Adds Go proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ContainerRegistry/Go/apphost.go Exercises registry proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CosmosDB/TypeScript/aspire.config.json Adds TypeScript proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CosmosDB/TypeScript/apphost.mts Exercises Cosmos proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CosmosDB/Python/aspire.config.json Adds Python proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CosmosDB/Python/apphost.py Exercises Cosmos proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CosmosDB/Java/aspire.config.json Adds Java proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CosmosDB/Java/AppHost.java Exercises Cosmos proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CosmosDB/Go/aspire.config.json Adds Go proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.CosmosDB/Go/apphost.go Exercises Cosmos proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.EventHubs/TypeScript/aspire.config.json Adds TypeScript proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.EventHubs/TypeScript/apphost.mts Exercises namespace proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.EventHubs/Python/aspire.config.json Adds Python proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.EventHubs/Python/apphost.py Exercises namespace proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.EventHubs/Java/aspire.config.json Adds Java proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.EventHubs/Java/AppHost.java Exercises namespace proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.EventHubs/Go/aspire.config.json Adds Go proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.EventHubs/Go/apphost.go Exercises namespace proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.KeyVault/TypeScript/aspire.config.json Selects Key Vault proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.KeyVault/TypeScript/apphost.mts Exercises Bicep expressions and SKU.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.KeyVault/Python/aspire.config.json Selects Python proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.KeyVault/Python/apphost.py Exercises Key Vault proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.KeyVault/Java/aspire.config.json Selects Java proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.KeyVault/Java/AppHost.java Exercises Key Vault proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.KeyVault/Go/aspire.config.json Selects Go proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.KeyVault/Go/apphost.go Exercises Key Vault proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.OperationalInsights/TypeScript/aspire.config.json Adds TypeScript proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.OperationalInsights/TypeScript/apphost.mts Exercises workspace proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.OperationalInsights/Python/aspire.config.json Adds Python proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.OperationalInsights/Python/apphost.py Exercises workspace proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.OperationalInsights/Java/aspire.config.json Adds Java proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.OperationalInsights/Java/AppHost.java Exercises workspace proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.OperationalInsights/Go/aspire.config.json Adds Go proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.OperationalInsights/Go/apphost.go Exercises workspace proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Search/TypeScript/aspire.config.json Adds TypeScript proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Search/TypeScript/apphost.mts Exercises Search proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Search/Python/aspire.config.json Adds Python proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Search/Python/apphost.py Exercises Search proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Search/Java/aspire.config.json Adds Java proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Search/Java/AppHost.java Exercises Search proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Search/Go/aspire.config.json Adds Go proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Search/Go/apphost.go Exercises Search proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ServiceBus/TypeScript/aspire.config.json Adds TypeScript proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ServiceBus/TypeScript/apphost.mts Exercises child resource proxies.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ServiceBus/Python/aspire.config.json Adds Python proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ServiceBus/Python/apphost.py Exercises namespace proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ServiceBus/Java/aspire.config.json Adds Java proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ServiceBus/Java/AppHost.java Exercises namespace proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ServiceBus/Go/aspire.config.json Adds Go proxy package.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.ServiceBus/Go/apphost.go Exercises namespace proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Sql/TypeScript/aspire.config.json Adds TypeScript SQL proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Sql/TypeScript/apphost.mts Exercises administrators and parameters.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Sql/Python/aspire.config.json Adds Python SQL proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Sql/Python/apphost.py Exercises SQL proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Sql/Java/aspire.config.json Adds Java SQL proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Sql/Java/AppHost.java Exercises SQL proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Sql/Go/aspire.config.json Adds Go SQL proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Sql/Go/apphost.go Exercises SQL proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Storage/TypeScript/aspire.config.json Adds TypeScript Storage proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Storage/TypeScript/apphost.mts Exercises declarations and expressions.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Storage/Python/aspire.config.json Adds Python Storage proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Storage/Python/apphost.py Exercises Storage proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Storage/Java/aspire.config.json Adds Java Storage proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Storage/Java/AppHost.java Exercises Storage proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Storage/Go/aspire.config.json Adds Go Storage proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.Storage/Go/apphost.go Exercises Storage proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.WebPubSub/TypeScript/aspire.config.json Adds TypeScript Web PubSub proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.WebPubSub/TypeScript/apphost.mts Exercises hubs and handlers.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.WebPubSub/Python/aspire.config.json Adds Python Web PubSub proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.WebPubSub/Python/apphost.py Exercises service proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.WebPubSub/Java/aspire.config.json Adds Java Web PubSub proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.WebPubSub/Java/AppHost.java Exercises service proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.WebPubSub/Go/aspire.config.json Adds Go Web PubSub proxy.
tests/PolyglotAppHosts/Aspire.Hosting.Azure.WebPubSub/Go/apphost.go Exercises service proxy.
Suppressed comments (1)

src/Aspire.Hosting.Azure.Provisioning.Generators/AspireProvisioningProxyGenerator.cs:1139

  • Nullable proxy types already include ? in ExposedTypeName (set in TryMapType), so this appends a second nullable marker and generates invalid declarations such as FooProxy?? parent. Any selected SDK constructor with an optional model/resource parameter will fail the consuming project’s compilation.
        if (includeDefaultValue && IsNullableFactoryProxyParameter(mappedParameter))
        {
            source.Append('?');
        }

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

Bound generated proxy discovery to selected Azure SDK namespaces, separate infrastructure roots from discovery-only child resources, and add typed Azure location literals across polyglot fixtures.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 39713d65-4058-4992-9484-65088a927bbc
Copilot AI review requested due to automatic review settings August 25, 2026 21:24
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 160 out of 160 changed files in this pull request and generated 2 comments.

Suppressed comments (4)

Previously missed (2) — in code that hasn't changed since the last review.

src/Aspire.Hosting.Azure.Provisioning.Generators/AspireProvisioningProxyGenerator.cs:1006

  • The polyglot fixtures only restore and compile the generated SDKs; no test executes these generated lookup/factory methods or compiles the resulting Bicep. Consequently the unset-parameter bug in BicepValueFactory.Parameter is not detected. Add a representative runtime test that invokes a generated infrastructure callback and verifies the final Bicep contains the configured parameter/reference and resource mutation.
        source.AppendLine("            var bicepIdentifier = global::Aspire.Hosting.AzureResourceExtensions.GetBicepIdentifier(infrastructure.AspireResource);");
        source.Append("            var value = global::System.Linq.Enumerable.Single(")
            .Append("global::System.Linq.Enumerable.OfType<").Append(underlyingTypeName)
            .Append(">(infrastructure.GetProvisionableResources()), ")
            .AppendLine("value => value.BicepIdentifier == bicepIdentifier);");

src/Aspire.Hosting.Azure.Provisioning.Generators/AspireProvisioningProxyGenerator.cs:412

  • The generator emits exported proxy types and members without XML documentation, so the generated TypeScript, Python, Go, and Java SDK surfaces have no API docs for the projected Azure properties, methods, collections, or factories. Emit language-neutral summaries (preferably from the source symbols' XML documentation, with suitable fallback text) before the generated [AspireExport] declarations.
        source.AppendLine("    [global::Aspire.Hosting.AspireExportAttribute]");
        source.Append("    internal class ").Append(proxyName);

src/Aspire.Hosting.Azure.Provisioning/BicepValueFactory.cs:111

  • As above, AsProvisioningParameter returns a declaration construct, and wrapping that construct directly leaves the proxy unset rather than referencing its Bicep identifier. Any generated property assigned from bicep.referenceExpression(...) is therefore cleared. Convert the declaration to BicepValue<object> before creating the proxy.
    src/Aspire.Hosting.Azure.Provisioning/BicepValueProxy.cs:108
  • Returning the raw literal creates a new non-secure BicepValue<T>, so secure metadata is dropped whenever generated method or collection input goes through Convert<T>. Build the converted value through AssignTo for literals as well, which preserves the proxy's forced secure state.

Comment thread src/Aspire.Hosting.Azure.Provisioning/BicepValueFactory.cs Outdated
Comment thread src/Aspire.Hosting.Azure.Provisioning/BicepValueProxy.cs
Diagnose unsupported proxy roots and member shapes, require explicit exclusions for intentional SDK omissions, and add Roslyn coverage for supported mappings and diagnostic paths.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 39713d65-4058-4992-9484-65088a927bbc
Copilot AI review requested due to automatic review settings August 25, 2026 21:47
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 163 out of 163 changed files in this pull request and generated 3 comments.

Suppressed comments (3)

src/Aspire.Hosting.Azure.Provisioning/BicepValueProxy.cs:83

  • The literal fast path bypasses GetAssignableValue() and assigns a newly created, non-secure value. A proxy whose IsSecure is forced to true therefore loses that metadata whenever its kind is Literal, contradicting the preservation guarantee. Wrap the typed literal with SecureBicepValue before assigning it when necessary.
    src/Aspire.Hosting.Azure.Provisioning/BicepValueProxy.cs:108
  • Convert<T> has a second literal fast path that returns a new BicepValue<T> without copying the proxy's secure flag. Secure literals passed to generated method or collection parameters are therefore downgraded even if AssignTo is fixed; route literal conversion through the same metadata-preserving assignment path.
    src/Aspire.Hosting.Azure.Provisioning.Generators/AspireProvisioningProxyGenerator.cs:1301
  • When a nullable proxy constructor parameter is named arguments, its declaration is renamed to args, but this null check still emits @arguments. That produces uncompilable generated code. Use GetParameterName consistently for both references.
                source.Append('@').Append(parameter.Parameter.Name)
                    .Append(" is null ? null : @").Append(GetParameterName(parameter.Parameter)).Append(".Inner");

Comment thread src/Aspire.Hosting.Azure.Provisioning/BicepValueProxy.cs
@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

Include transitively referenced Azure.Provisioning models in every service proxy package, namespace duplicated proxy handles per package, and expose resource attachment for generated declarations. Expand generator coverage and aggregate polyglot fixtures to validate composed provisioning packages and role assignments.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 39713d65-4058-4992-9484-65088a927bbc
Copilot AI review requested due to automatic review settings August 25, 2026 22:44
@github-actions

This comment has been minimized.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 39713d65-4058-4992-9484-65088a927bbc
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 39713d65-4058-4992-9484-65088a927bbc

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 162 out of 162 changed files in this pull request and generated 4 comments.

Suppressed comments (3)

src/Aspire.Hosting.Azure.Provisioning/BicepValueFactory.cs:111

  • This has the same compile-time inference failure as Parameter: the returned ProvisioningParameter does not implement IBicepValue, and T cannot be inferred through its user-defined conversion. Specify string explicitly so the conversion target is known.
    src/Aspire.Hosting.Azure.Provisioning/BicepValueProxy.cs:84
  • Reconstructing a fresh BicepValue<T> for literals drops the source value's Self/Source and secure metadata. Generated property getters can return literal-backed values that still carry resource-reference/dependency metadata, so assigning them through this path no longer preserves the metadata promised by this proxy. Convert the literal when necessary, but pass an IBicepValue retaining the original reference and security state into target.Assign.
    src/Aspire.Hosting.Azure.Provisioning/BicepValueProxy.cs:109
  • The literal conversion path also creates a new standalone BicepValue<T> via the implicit conversion, so it discards the proxy's resource-reference and secure metadata despite the documented preservation guarantee on line 95. This path is used for generated method parameters and collection mutations; retain the original IBicepValue metadata when producing the typed value.

Comment thread src/Aspire.Hosting.Azure.Provisioning/BicepValueFactory.cs Outdated
Comment thread src/Aspire.Hosting.Azure.Provisioning/README.md Outdated
Copilot AI review requested due to automatic review settings August 25, 2026 22:57
@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 39713d65-4058-4992-9484-65088a927bbc
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Secure non-string Bicep parameters can currently be created or mutated into invalid deployment declarations.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (1)

src/Aspire.Hosting.Azure.Provisioning/ProvisioningDeclarationExtensions.cs:108

  • The initial isSecure value bypasses the proxy setter and accepts true for Boolean, Integer, or Guid parameters. Those combinations cannot be represented as valid Bicep because @secure() is restricted to string/object parameters. Validate the type/value combination before constructing the declaration (and cover these rejected cases in the declaration tests).
  • Files reviewed: 202/204 changed files
  • Comments generated: 1
  • Review effort level: Balanced

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

Reject secure integer and Boolean parameters during creation and mutation, including implicit security from assigned values. Preserve secure GUID parameters because the CDK emits them as Bicep strings.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 39713d65-4058-4992-9484-65088a927bbc
@github-actions

Copy link
Copy Markdown
Contributor

Tests selector

Selects the full PR test matrix + all PR-gated jobs (ALL) — a rule matching 'Aspire.slnx' selects ALL


Selection computed for commit 1343fc4.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The large source-generation and runtime-contract change spans 204 files and four language projections, warranting final human validation.

Review details
  • Files reviewed: 202/204 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@sebastienros
Sébastien Ros (sebastienros) merged commit 8c7e5ff into main Sep 15, 2026
799 of 804 checks passed
@sebastienros
Sébastien Ros (sebastienros) deleted the sebros/polyglot-provisioning-sdks branch September 15, 2026 23:36
@github-actions github-actions Bot added this to the 13.6 milestone Sep 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ CI Failure Analysis: Possible Flaky Test(s)

The CI build failed due to test failure(s) that appear unrelated to the PR changes. These may be flaky tests.

Suspected flaky test(s):

  • Aspire Blazor browser debugger E2E hits a managed breakpoint for standalone in job Tests / Run VS Code extension E2E tests / VS Code extension E2E (Windows, browser-debugger)
    • Error: Failed to apply E2E control revision 1789516426086: Error: Timed out after 287236ms waiting for pwa-msedge child session for Blazor WASM root '6a780974-453c-4fff-b53e-0aaaa63d465d'. Last error: .
    • Stack Trace (first frames):
Error: Failed to apply E2E control revision 1789516426086: Error: Timed out after 287236ms waiting for pwa-msedge child session for Blazor WASM root '6a780974-453c-4fff-b53e-0aaaa63d465d'. Last error: <none>. State: {"debugSessions":[{"id":"aac23646-395b-4f90-b67a-e80dc625762a","type":"monovsdbg_wasm","name":"Wasm Managed Debugger", ...}]}
  • Why likely flaky: Matches known recurring timeout waiting for the pwa-msedge child debug session to attach to a Blazor WASM root, tracked under issue [CI Failure] VS Code extension E2E tests fail with unavailable logs and generic exit code 1, unrelated to PR changes #19618 with 14 prior occurrences. Not related to PR changes (Azure provisioning proxy SDKs, unrelated to VS Code extension debugger).
  • Aspire Blazor browser debugger E2E hits a managed breakpoint for hosted-global in job Tests / Run VS Code extension E2E tests / VS Code extension E2E (Windows, browser-debugger)
    • Error: Failed to apply E2E control revision 1789516426089: Error: Timed out after 299230ms waiting for Blazor WASM root session for resource 'hosted-global'. Last error: .
    • Stack Trace (first frames):
Error: Failed to apply E2E control revision 1789516426089: Error: Timed out after 299230ms waiting for Blazor WASM root session for resource 'hosted-global'. Last error: <none>. State: {"debugSessions":[{"id":"794aa564-62a9-4425-a218-3973b7502a00","type":"monovsdbg_wasm","name":"Wasm Managed Debugger", ...}]}
  • Why likely flaky: Same timeout pattern waiting for the Blazor WASM debug root session as the standalone test failure above; part of the same recurring flaky failure cause tracked under issue [CI Failure] VS Code extension E2E tests fail with unavailable logs and generic exit code 1, unrelated to PR changes #19618.
  • Aspire Blazor browser debugger E2E hits a managed breakpoint for hosted-per-page in job Tests / Run VS Code extension E2E tests / VS Code extension E2E (Windows, browser-debugger)
    • Error: Failed to apply E2E control revision 1789516426092: Error: Timed out after 299326ms waiting for Blazor WASM root session for resource 'hosted-per-page'. Last error: .
    • Stack Trace (first frames):
Error: Failed to apply E2E control revision 1789516426092: Error: Timed out after 299326ms waiting for Blazor WASM root session for resource 'hosted-per-page'. Last error: <none>. State: {"debugSessions":[{"id":"bccd3400-9103-45e4-a26c-e0466f56fe9e","type":"monovsdbg_wasm","name":"Wasm Managed Debugger", ...}]}

Suggested actions:

  • Re-run the failed CI jobs to confirm if the failure is intermittent
  • If the test continues to fail, consider quarantining it using /quarantine-test <test name> <issue URL>
  • Search existing issues to see if this test is already known to be flaky

You can re-run the failed jobs from the workflow run page.

Sébastien Ros (sebastienros) added a commit that referenced this pull request Sep 22, 2026
## Description

Add **12 opt-in Azure Provisioning SDK integrations** for polyglot
AppHosts, extending the bounded, experimental proxy model introduced by
#19675. That parent has merged; this PR targets `main`.

### Changes

- Add proxies for AppConfiguration, AppContainers, AppService, Cdn,
ContainerService, Kusto, Network, PrivateDns, PostgreSql, Redis,
RedisEnterprise, and SignalR, with project/packaging registration and
package documentation.
- Select no-argument lookup roots only when SDK and hosting callback
Bicep identifiers match. Container Apps environments support root
lookup; apps and jobs use identifier-based lookup. App Service plans
(`<environment>_asplan`) and sites (`webapp`) also use identifier-based
lookup.
- Reuse shared SDK mappings rather than introducing duplicate or empty
wrappers. Network/PrivateDns and Redis/RedisEnterprise remain separate
SDK opt-ins.
- Fix generator compatibility for inherited `AddTo`, nullable-oblivious
optional null parameters, and complex value-type collection elements
such as `AzureLocation`.
- Marshal union RPC results using the matching declared member,
preserving Bicep handles and rejecting unmatched values.
- Allocate distinct Java enum names after normalization while retaining
original wire values (`AAD` versus `Aad`).
- Support IP address lists using IPv4/IPv6 strings or Bicep handles.
Invalid strings fail explicitly; getters preserve
literal/expression/reference/security metadata. SDK read-only output
restrictions still apply.
- Exercise actual configuration APIs in TypeScript, Python, Go, and Java
fixtures, using conventional empty-string package references. No new
generated-code-shape unit tests, feeds, package versions, or CI jobs are
introduced.
- Correct README samples against generated SDK signatures. Keep
permanent documentation product-oriented, without completion counts,
new/existing labels, or stacked-PR history.

### Hosting-to-provisioning inventory

Hosting suffixes mean `Aspire.Hosting.Azure.<suffix>`. SDK/proxy
suffixes mean `Azure.Provisioning.<suffix>` /
`Aspire.Hosting.Azure.Provisioning.<suffix>`.

| Hosting integration | SDK/proxy mapping and rationale |
| --- | --- |
| `Aspire.Hosting.Azure` | Base `Azure.Provisioning`, shared runtime,
and KeyVault support; not a separate service SDK. |
| AppConfiguration | AppConfiguration: `AppConfigurationStore`. |
| AppContainers | AppContainers: environment root plus identifier-based
app/job lookup. Supporting ContainerRegistry, OperationalInsights,
KeyVault, Storage. |
| AppService | AppService: identifier-based plan/site lookup. Supporting
ContainerRegistry, ApplicationInsights, OperationalInsights. |
| ApplicationInsights | ApplicationInsights:
`ApplicationInsightsComponent`; OperationalInsights workspace support. |
| CognitiveServices | CognitiveServices: `CognitiveServicesAccount`,
including Azure OpenAI models. |
| ConnectorNamespace | Base provisioning with internal custom
`ConnectorGateway` models for `Microsoft.Web/connectorGateways` and
children. No standalone service SDK or SDK proxy; internal models are
not projected. |
| ContainerRegistry | ContainerRegistry: `ContainerRegistryService`. |
| CosmosDB | CosmosDB: `CosmosDBAccount`; shared KeyVault support. |
| EventHubs | EventHubs: `EventHubsNamespace`; Storage for
storage-backed scenarios. |
| FrontDoor | Cdn: `CdnProfile`, endpoints, origins, groups, and routes;
not a separate FrontDoor SDK. |
| Functions | Shared Storage and deployment-target
AppContainers/AppService proxies; no Functions SDK dependency. |
| KeyVault | KeyVault: `KeyVaultService`. |
| Kubernetes | ContainerService: `ContainerServiceManagedCluster`;
shared Network, PrivateDns, ContainerRegistry, OperationalInsights. |
| Kusto | Kusto: `KustoCluster`; identifier-addressable database
children. |
| Network | Network: `VirtualNetwork`, `NetworkSecurityGroup`,
`NatGateway`, `PublicIPAddress`, `PrivateEndpoint`,
`NetworkSecurityPerimeter`; PrivateDns: `PrivateDnsZone`. Subnets and
DNS VNet links are children. |
| OperationalInsights | OperationalInsights:
`OperationalInsightsWorkspace`. |
| PostgreSQL | PostgreSql: `PostgreSqlFlexibleServer`; SDK spelling
differs from hosting. |
| Redis | Redis: `RedisResource` for Azure Cache for Redis;
RedisEnterprise: `RedisEnterpriseCluster` for Azure Managed Redis;
KeyVault for access-key support. |
| Sandboxes | Shared ContainerRegistry and base provisioning; internal
custom `SandboxGroup`/endpoint models are not a standalone service SDK
and are not projected. |
| Search | Search: `SearchService`. |
| ServiceBus | ServiceBus: `ServiceBusNamespace`. |
| SignalR | SignalR: `SignalRService`. |
| Sql | Sql: `SqlServer`; shared Storage, Network, PrivateDns where
needed. |
| Storage | Storage: `StorageAccount`, including blob, queue, table,
file models. |
| WebPubSub | WebPubSub: `WebPubSubService`. |

The shared `Aspire.Hosting.Azure.Provisioning` runtime and private
`Aspire.Hosting.Azure.Provisioning.Generators` analyzer complete the
infrastructure portion of the inventory. The SDK proxies above account
for the SDK-specific projects; the README links each project to its
hosting dependency and lookup roots.

### Explicit exclusions

The projection is bounded, not a promise of complete Azure SDK coverage.

| Proxy | Excluded members | Reason |
| --- | --- | --- |
| ContainerService | `CustomCATrustCertificates` |
`BicepList<BinaryData>` lacks a type-safe ATS representation. |
| Network | `AdditionalProperties` | Open-ended
`BicepDictionary<BinaryData>`. |
| Redis | `AdditionalProperties` | Open-ended
`BicepDictionary<BinaryData>`. |

AppContainers `OutboundIPAddressList` and AppService `IPAddresses`,
`ExternalInboundIPAddresses`, `InternalInboundIPAddresses`,
`LinuxOutboundIPAddresses`, and `WindowsOutboundIPAddresses` are
exported through IP address collection proxies. Service output lists
retain SDK read-only restrictions.

### Usage

```bash
aspire add Aspire.Hosting.Azure.Provisioning.AppConfiguration
```

```typescript
const configuration = await builder.addAzureAppConfiguration("configuration");
await configuration.configureInfrastructure(async infrastructure => {
    const store = await infrastructure.getAppConfigurationStore();
    const tags = await store.tags.get();
    await tags.set("environment", "production");
});
```

Existing C# configuration is unchanged. These packages remain
experimental (`ASPIREAZUREPROVISIONING001`) and do not change cloud
authentication, resource lifecycles, or deployment defaults.

### Validation

- Initial integration validation: all 24 SDK proxies built, all 12 added
packages packed, 242 focused RemoteHost tests passed, and the Java
code-generation regression passed.
- Initial polyglot validation: 40 updated fixture SDKs regenerated and
compiled, 16 bounded configuration publishes passed, and eight
literal/expression union RPC cases passed across four languages.
- IP follow-up on the main-based branch: all 45 provisioning
generator/runtime tests passed; all eight AppService/AppContainers
fixtures restored and compiled/type-checked; all eight bounded publishes
produced manifests and callback-completion markers. Coverage includes
IPv4/IPv6, malformed inputs, literal/expression handle roundtrips, list
mutations, and read-only output getters.
- Review fixes: corrected mapping projects build without
warnings/errors, all 45 provisioning tests pass, and all 13 exact
TypeScript README snippets (the 12 added packages plus shared runtime)
type-check against generated SDKs. The inventory was checked against the
actual Azure projects, including ConnectorNamespace.

The unmodified full fixture runtime suite is **not** claimed passing:
fixtures contain pre-existing duplicate resource names, missing sample
projects, and Go option-merging failures. Bounded smoke AppHosts isolate
provisioning callbacks. Python smoke code normalizes the existing
combined-argv issue with `shlex.split` only in scratch; no production
workaround is included. No Azure resources were deployed.

Fixes # (issue)

## Checklist

- Is this feature complete?
  - [x] Yes. Ready to ship.
  - [ ] No. Follow-up changes expected.
- Are you including unit tests for the changes and scenario tests if
relevant?
  - [x] Yes
  - [ ] No
- Did you add public API?
  - [x] Yes
    - If yes, did you have an API Review for it?
      - [ ] Yes
      - [x] No
- Did you add `<remarks />` and `<code />` elements on your triple slash
comments?
      - [ ] Yes
      - [x] No
  - [ ] No
- Does the change make any security assumptions or guarantees?
  - [ ] Yes
    - If yes, have you done a threat model and had a security review?
      - [ ] Yes
      - [ ] No
  - [x] No

---------

Co-authored-by: Sébastien Ros <1165805+sebastienros@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@sebastienros

This comment has been minimized.

@sebastienros

Copy link
Copy Markdown
Contributor Author

Documentation has been drafted in two complementary PRs, both targeting release/13.6:

  • microsoft/aspire.dev#1747: existing integration-author guidance, projection diagnostics, and experimental capability metadata. This draft remains relevant and is unchanged.
  • microsoft/aspire.dev#1756: the separately requested infrastructure.bicep() reference, covering all 32 factory exports, companion string-builder/declaration methods, operator mappings, array/object boundaries, and secure-value semantics.

The new reference maps the Aspire API to official Azure.Provisioning 1.6.0 C# SDK APIs and Bicep syntax. Its real Storage and Key Vault examples compile against the generated 13.6 TypeScript SDK; both locally published templates exactly match their C# counterparts. No Azure deployment was performed.

The tested 13.6.0-preview.1.26473.12 TypeScript string-builder build() can wait on its enclosing infrastructure callback and time out. The reference documents this narrowly scoped limitation and uses a working concat alternative; C# interpolation is unaffected.

All 10 original signal categories are accounted for in the new PR body. The new draft's actual base, head, draft state, four-file scope and docs-from-code label were verified; the shared outcome validator passed.

Note

Human review is required before merging either documentation PR.

David Pine (IEvangelist) pushed a commit to microsoft/aspire.dev that referenced this pull request Sep 28, 2026
Documents changes from microsoft/aspire#19675:
microsoft/aspire#19675, authored by
@sebastienros.

## Scope and documentation gap

This is the explicitly requested **separate follow-up**, not a
replacement for #1747 (integration authoring/diagnostics) or #1748
(service coverage). Neither existing PR nor its branch is modified. The
release rollup #1599 is not the source PR and is untouched.

Adds a focused, user-oriented reference for `infrastructure.bicep()`:

- All **32 factory exports**, including the `resourceIdentifier` export
alias, with arguments, return/value semantics, underlying C# SDK
counterpart or AST node, and emitted Bicep.
- All **3 string-builder methods**, **3 infrastructure declaration
helpers**, **16 binary / 3 unary operators**, value/security metadata,
and explicit array/object/null constructor and declaration-type
boundaries.
- Complete TypeScript and C# Storage examples: deterministic
valid-length naming, resource-group location, parameter/deployment tags,
concatenation, and resource-ID output.
- Complete TypeScript and C# Key Vault examples: JSON object/array data,
variable/member/index access, deployment-time equality/conditional,
retention settings, purge-protection caveats, and integer output.
Existing authorization stays intact.
- Clear separation of remote handles, host-language evaluation,
deployment-time functions, GUID/URI literals versus functions, SDK
typing versus conversions, and secure metadata versus protection of
output destinations.

### Files

- Added
`src/frontend/src/content/docs/integrations/cloud/azure/bicep-helpers.mdx`.
- Added one cross-link in
`src/frontend/src/content/docs/integrations/cloud/azure/customize-resources.mdx`;
existing guidance and examples are preserved.
- Added discovery entries in
`src/frontend/config/sidebar/integrations.topics.ts` and
`deployment.topics.ts`.

## Exact target rationale and provenance

Prepared target resolution: `candidate_source=pr_milestone`,
`candidate_source_detail=13.6`, `candidate_target_branch=release/13.6`,
`target_resolution=exact_match`. The matching docs release branch
exists; this is not a latest-release or main fallback.

- Docs base: `release/13.6` at
`e20e81f100b699c4dd6adbf01a52f6fd7bad11bd`.
- Head: `sebros/bicep-helper-reference`, on the origin
`microsoft/aspire.dev`, not a fork.
- Product release source:
[`43496a2a306c81c862c947b11b4f4e5494b6fe08`](https://github.com/microsoft/aspire/tree/43496a2a306c81c862c947b11b4f4e5494b6fe08).
Factory, value wrapper, declaration and string-builder implementations
checked against this release, not 14.x main.
- Actual generated SDK and installed CLI: **13.6.0-preview.1.26473.12**,
source `a11eca9611073f7cf66fa87faac63c2119e87713`, matching this docs
branch's generated API data.
- Exact Aspire packages restored from the official public `dotnet9` feed
after the original staging darc feed returned HTTP 404. Only isolated
scratch configuration changed.

## Official Azure SDK verification

Verified Microsoft Learn and the corresponding official SDK
implementation, rather than inferring mappings from Aspire XML
summaries:

- [BicepFunction, Azure.Provisioning
1.6.0](https://learn.microsoft.com/dotnet/api/azure.provisioning.expressions.bicepfunction?view=azure-dotnet),
with [stable pinned
source](https://github.com/Azure/azure-sdk-for-net/blob/4d32854480515e716c762be7925660bce6da251a/sdk/provisioning/Azure.Provisioning/src/Expressions/BicepFunction.cs).
-
[BicepValue<T>](https://learn.microsoft.com/dotnet/api/azure.provisioning.bicepvalue-1?view=azure-dotnet),
[expression AST
namespace](https://learn.microsoft.com/dotnet/api/azure.provisioning.expressions?view=azure-dotnet),
and declaration types.
- [Stable literal serialization
implementation](https://github.com/Azure/azure-sdk-for-net/blob/4d32854480515e716c762be7925660bce6da251a/sdk/provisioning/Azure.Provisioning/src/Expressions/BicepTypeMapping.cs):
`double(1.5)` emits `json('1.5')`, whole `double(2)` emits `2`,
standalone one-hour `TimeSpan` emits `'01:00:00'`; property-specific
formats can differ.
- [StorageAccount
1.1.2](https://learn.microsoft.com/dotnet/api/azure.provisioning.storage.storageaccount?view=azure-dotnet),
[KeyVaultProperties
1.1.0](https://learn.microsoft.com/dotnet/api/azure.provisioning.keyvault.keyvaultproperties?view=azure-dotnet),
and [retention
bounds](https://learn.microsoft.com/dotnet/api/azure.provisioning.keyvault.keyvaultproperties.softdeleteretentionindays?view=azure-dotnet).
- Bicep language references for string/resource/scope functions,
operators, secure parameters and Azure resource naming; Key Vault
soft-delete documentation for immutable retention and purge protection.

## Validation

- Extracted both exact TypeScript snippets and compiled them using `tsc
-p tsconfig.apphost.json` against **genuine generated release SDK
code**, with no SDK patches, casts, diagnostics suppression or
production changes.
- Both TypeScript AppHosts successfully ran local `aspire publish` with
a nonsecret `Parameters__environment=Production` input and generated
Storage / Key Vault Bicep. Expected warning: no compute environment in
these resource-only examples.
- Compiled both exact C# counterparts with the matching Aspire packages
and generated local manifests. **Storage and Key Vault Bicep files are
each byte-for-byte identical between the C# and TypeScript versions.**
- Independently ran Azure.Provisioning 1.6.0 offline generation to
confirm literals, interpolation and all operator spellings.
- The full existing `pnpm test:unit:twoslash-blocks` gate passed (2
tests). New proxy examples intentionally use ordinary TypeScript fences,
as their operator/runtime surface is checked against genuine SDK modules
rather than the site's simplified declaration bundle.
- Frontmatter SEO checks passed (3 tests); touched sidebar files passed
ESLint; Prettier and `git diff --check` passed.
- Local Astro route returned 200; Playwright inspected desktop/mobile
tables, synchronized TypeScript/C# tabs, headings and cross-link
navigation. No page-wide mobile overflow. Unrelated dev-only
`/api/live/` and `/api/live/stream/` requests return 404 without the
static host.
- All 19 external links in the new page returned HTTP 200.
- No production site build, Azure deployment, cloud access mutation,
secret creation, billing operation, workflow dispatch, or
dependency-manifest/lockfile change in this PR.

### SME attention: tested preview string-builder limitation

The exact generated **13.6.0-preview.1.26473.12 TypeScript SDK**
implements `BicepStringBuilderProxyImpl.build()` with `await
this._client.flushPendingPromises()`
(`.aspire/modules/aspire.mts:18905-18906`). Inside
`configureInfrastructure`, this waits for the enclosing pending
callback. The fully awaited original Storage sample consistently timed
out after 120 seconds, with `Flushing 2 pending promise(s)` in the
trace.

The runnable sample now uses `concat` and publishes successfully. The
page preserves the underlying string-builder reference and narrowly
labels this exact preview limitation; it does not attribute the problem
to C# `BicepStringBuilder` or Bicep itself. Please reassess/remove this
caveat when the generated SDK is fixed. No product fix, SDK
modification, or new product issue is included.

Minimal reproduction (inside a configured callback, after obtaining
`bicep`):

```typescript
const label = await bicep.createStringBuilder();
await label.appendLiteral('storage-');
await label.appendValue(await bicep.string('example'));
await label.build();
```

## Original source signal accounting

Prepared inputs require documentation and are not excluded. This
user-requested helper follow-up narrows the original broad PR's
remaining gap; #1747 remains the relevant authoring/diagnostics draft.

| Triggered category | Concrete source evidence and treatment |
| --- | --- |
| `cli_command_file_changed` |
`src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs`: experimental capability
metadata. Existing authoring draft #1747; this page documents
experimental helper boundaries, not CLI behavior again. |
| `diagnostic_documentation_changed` | `docs/list-of-diagnostics.md`:
provisioning/projection diagnostics. Existing #1747; new page retains
`ASPIREAZUREPROVISIONING001` caveat. |
| `diff_scan_skipped_due_to_missing_patch` |
`AspireProvisioningProxyGenerator.cs` exceeded cached patch coverage.
This follow-up directly reads release source and validates actual
generated package SDK instead of treating missing patch as a skip. |
| `integration_readme_changed` | Shared
`Aspire.Hosting.Azure.Provisioning/README.md` and per-service READMEs.
New page adds the missing complete helper-to-SDK/Bicep mapping without
duplicating general authoring prose. |
| `new_hosting_integration_project` | Shared runtime and original
provisioning service `.csproj` additions. New examples explicitly name
Storage/KeyVault opt-in packages; service inventory stays separate. |
| `new_package_added` | Runtime, generator and original 12 provisioning
service packages. Actual matching runtime/Storage/KeyVault packages used
to generate and execute snippets. |
| `new_public_type` | `BicepValueProxy`, `ProvisionableResourceProxy`,
export provider attribute. Reference explains value/resource handle
distinctions and factory/declaration semantics; export provider
authoring stays in #1747. |
| `polyglot_code_generator_changed` | TypeScript/Python/Java code
generators and TypeScript projector. Genuine generated TypeScript SDK
validated; the observed build-method limitation is explicitly surfaced.
|
| `pr_body_has_user_facing_section` | Source PR's “User-facing usage”
section contains customization examples. This adds complete
user-oriented Storage and Key Vault scenarios, not more internal
authoring guidance. |
| `target_framework_changed` | New provisioning project target-framework
declarations. No evidence of a changed AppHost prerequisite; this PR
doesn't change prerequisites or dependency manifests. |

**Human review is required before merging**, especially the
exact-preview string-builder caveat and exhaustive mapping tables. SME
requested: @eerhardt.

---------

Co-authored-by: Sébastien Ros <1165805+sebastienros@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
David Negstad (danegsta) added a commit to microsoft/aspire.dev that referenced this pull request Sep 29, 2026
[![aspire.dev vnext
(13.6)](https://img.shields.io/badge/aspire.dev-vnext_(13.6)-512BD4?style=flat&logoColor=white&logo=...)](https://aka.ms/aspire/vnext)

## Summary

Prepare the Aspire 13.6 documentation release. The release article is
reconciled against [`microsoft/aspire` release/13.6 at
`a11eca9611073f7cf66fa87faac63c2119e87713`](https://github.com/microsoft/aspire/tree/a11eca9611073f7cf66fa87faac63c2119e87713),
compared with `v13.5.0`. The inventory contains 402 first-parent history
entries, including maintenance, merges, and reversions—not 402 distinct
shipped features.

Highlights cover dashboard persistence/run history and terminals; Java,
Rust, Connector Namespace and Sandboxes; coordinated .NET builds; CLI
and VS Code workflows; deployment and integration improvements; emulator
images; and migration guidance for Cosmos DB, Front Door,
connection-string aliases, and terminal namespaces.

### Published documentation and ingestion work

- `94b5f0c19`: migrate Java guides from Toolkit to first-party hosting,
document typed Azure provisioning customization and VS Code agent
lifecycle tools, and refresh 34 container-image records from the pinned
release source. Default tag changes: App Configuration `1.0.2 → 1.2.0`,
Cosmos DB `stable → vnext-latest`.
- `27e2db77a`: exact release-version selection, ATS-only package
metadata, union and canonical SDK enum handling, empty C# navigation
filtering, and fail-closed handling of SDK dump errors.
- `0b64558c1`: reconcile all 29 contributors against the pinned release
snapshot.
- `2696e2207`: recognize const-object enum declarations, retain
colliding enum-name literals in the shared Twoslash bundle while
preserving exact package-specific JSON, and increase the full
example-audit time budget for the larger dataset.
- `7ab5f74bd`: include the exact Dotnet package as supporting scan
context for Radius's generic .NET program export; subtract
core/supporting modules without dropping Radius's real IDs or receiver
targets.
- **`44b9819bb`: publish the complete, validated 13.6 catalog, mappings,
C#/TypeScript API data, and Twoslash bundle together.**
- Concurrent release updates are preserved, including the environment
badge and #1745's agent lifecycle options. Isolation/launch-profile
inputs were confirmed in the pinned 13.6 source.
- Related product changes: microsoft/aspire#18033,
microsoft/aspire#19675, and microsoft/aspire#19134.

The maintainer-set planned release date remains September 29, 2026
(#1690). Published package constants remain separate from prerelease
ingestion. Release membership comes from product source, not merely a
docs PR's target; #1740 documents microsoft/aspire#20231 (14.0), not a
13.6 feature.

### Generated data and provenance

The published snapshot contains **217 catalog entries**, **161
documentation mappings** (including the 26 new mappings), **210 C#
records**, **146 TypeScript modules**, and the rebuilt Twoslash bundle.
There are 132 official packages at exact version
`13.6.0-preview.1.26473.12`, with **no 14.x imports**. Independently
versioned packages retain their selected catalog versions.

Generation used genuine pinned packages from the public dotnet9 feed and
an isolated, locally built **13.6** CLI/RemoteHost. Package provenance
remains `a11eca9611073f7cf66fa87faac63c2119e87713`; the scanner fixes
are separate development-build provenance, not a claim that an official
corrected CLI has shipped.

- Full TypeScript ingestion with the inherited-method fix
(`320eed42f85a7d4b090a9429b98c7a6a8547a4b8`) produced 146 modules, 0
failures, and 7 explicit skips.
- Core/Radius regeneration with the additional target-specificity fix
(`435fd4eb7d06ef99702ae5106cf01c10f5c6a780`) succeeded. The real
compound Radius + exact Dotnet SDK dump has no diagnostics and retains
both `withContainerImage` and `withDotnetProgramContainerImage`
capability IDs.
- ProjectResource/CSharpAppResource use the concrete Radius export;
DotnetProjectResource uses the generic export. Dotnet's APIs are not
attributed to Radius. No source-package attributes, capability
identities, or missing-export checks were altered to force validation
through.

## Third-party links and affiliations

- Radius documentation — no material affiliation.
- Source/specification links remain within `microsoft/aspire`; Java
debugger links point to the corresponding Visual Studio Marketplace
extensions. No new material affiliation claims.

## Validation

- All **25 authored TypeScript guide/release examples** pass against the
final declaration bundle; guide samples were also compiled with the
genuine generated SDK.
- The **complete annotated-site Twoslash audit passes**, with no
diagnostic suppression.
- Final semantic validation passes: 217 package identities, 146
module-provenance matches, 74 DTO shapes, and 2,873 handle inheritance
chains.
- **82 structured-data tests**, **75
API-reference/declaration-generator/API-route tests**, and **17 ATS
transformer tests** pass. The final API-reference gate resolves the
Radius exports without exceptions or aliases.
- Earlier compile-only C# validation covered 24 guide methods and one
type declaration without warnings or errors. Browser checks covered
Java, Azure customization, VS Code and AI-agent routes and language
tabs.
- Source scanner/dispatcher/context-filter/API-export regressions: **215
pass on each product branch**, including exact-package dispatch and
generated-SDK compilation checks.
- No local production site build, cloud deployment, destructive cleanup
scenario, CLI self-update, or release workflow was run. Current-head CI
must still complete after the latest pushes.

## Remaining release gates

- **Main scanner fix: microsoft/aspire#20438**, ready for review, latest
commit `5482164dc1225f3c2a1a93bf5055e11b720117e9`. **13.6 backport:
microsoft/aspire#20443**, draft, latest commit
`435fd4eb7d06ef99702ae5106cf01c10f5c6a780`. Both require human
review/merge; neither has been merged or released by this session.
Latest-commit CI is still being monitored.
- Official shipping requires the corrected RemoteHost-containing
CLI/bundle. Rebuilding Network or Radius alone is insufficient. Local
documentation generation does not replace that packaging gate.
- The Express diagnostic short link requires owner action:
#1599 (comment).
- Complete current-head docs CI and final release/runtime acceptance.
Keep this PR draft until the release gates are satisfied.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: aspire-repo-bot[bot] <268009190+aspire-repo-bot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: James Newton-King <james@newtonking.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com>
Co-authored-by: David Pine <7679720+IEvangelist@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Maddy Montaquila <maddy@pi.hole>
Co-authored-by: Eric Erhardt <eric.erhardt@microsoft.com>
Co-authored-by: Ella Hathaway <ellahathaway@microsoft.com>
Co-authored-by: aspire-repo-bot[bot] <aspire-repo-bot[bot]@users.noreply.github.com>
Co-authored-by: David Aniebo <aniebovictor001@gmail.com>
Co-authored-by: Alistair Matthews <alistairwebdojo@live.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Maddy Montaquila <maddy@MadBook-Pro-20.local>
Co-authored-by: Ella Hathaway <67609881+ellahathaway@users.noreply.github.com>
Co-authored-by: David Pine <dapine@microsoft.com>
Co-authored-by: Nell Shamrell-Harrington <nellshamrell@gmail.com>
Co-authored-by: David Negstad <50252651+danegsta@users.noreply.github.com>
Co-authored-by: Sébastien Ros <sebastienros@gmail.com>
Co-authored-by: David Negstad <David.Negstad@microsoft.com>
Co-authored-by: Sébastien Ros <1165805+sebastienros@users.noreply.github.com>
Co-authored-by: karolz-ms <15271049+karolz-ms@users.noreply.github.com>
Co-authored-by: Karol Zadora-Przylecki <karolz@microsoft.com>
Co-authored-by: Mitch Denny <midenn@microsoft.com>
Co-authored-by: Mitch Denny <midenn@orangecake.local>
Co-authored-by: Mitch Denny <midenn@Mac.localdomain>
Co-authored-by: Jose Perez Rodriguez <joperezr@microsoft.com>
Co-authored-by: Maddy Montaquila <maddyleger1@gmail.com>
Co-authored-by: Maddy Montaquila <maleger@microsoft.com>
Copilot-Session: b0007635-1ab8-4ffc-9c7b-8c09439c79f6
Copilot-Session: 9ecc352e-ddd2-4c3e-9c4a-eafcc2a74157
Copilot-Session: b8ebe88c-337e-4d4a-aa80-e14c2c76289b
Copilot-Session: 5b0c81a3-d822-462e-8cf5-8eb6debfe968
Copilot-Session: b156fe61-0b1c-460c-9735-1eaeaa356b0a
Copilot-Session: 41298945-9592-4284-be9e-be0c58f31fad
Copilot-Session: 5eeee6c8-e0b2-4836-96ff-a9726e92b2ee
Copilot-Session: 829e510d-2b06-4301-9759-3bd760c45e5c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-integrations Issues pertaining to Aspire Integrations packages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants