Add Azure sandbox deployment target#17873
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17873Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17873" |
|
❓ CLI E2E Tests unknown — 110 passed, 0 failed, 3 unknown (commit View all recordings
📹 Recordings uploaded automatically from CI run #26998344395 |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
f6a4720 to
9f7b6cf
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces a new experimental Aspire.Hosting.Azure.Sandboxes hosting package that enables deploying Aspire compute resources (projects, containers, Dockerfiles) to Azure Container Apps Sandboxes. The deployment flow builds and pushes container images, converts them into sandbox disk images via the Azure Dev Compute (ADC) management API, provisions sandbox ARM resources with Bicep, exposes HTTP endpoints through the sandbox proxy, and persists endpoint state. The PR also models Azure Connector Gateway resources (connections, access policies, MCP server configs, trigger configs) for SharePoint-style webhook integration.
Changes:
- Adds ~34 new C# files in
src/Aspire.Hosting.Azure.Sandboxes/covering resource types, deployment logic, provisioning models, ADC HTTP client, extension methods, and TypeScript API surface. - Extends core hosting infrastructure:
ContainerRuntimeBasegainsIProcessRunnerinjection and newInspectImageConfigAsync/InspectImageManifestAsyncmethods;DefaultUserPrincipalProvideradds app-token (service principal) detection;BicepProvisionerpropagatesUserPrincipalIdandPrincipalTypeparameters;AcrLoginServiceexposes registry refresh tokens for disk image creation. - Adds comprehensive unit tests (20 in
AzureSandboxesTests) and a guarded E2E deployment test using Hex1b terminal automation against a TypeScript AppHost.
Show a summary per file
| File | Description |
|---|---|
src/Aspire.Hosting.Azure.Sandboxes/ (34 files) |
New package: resource types, deployment steps, ADC client, Bicep provisioning models, extension methods, options, and value providers |
src/Aspire.Hosting/Publishing/ContainerRuntimeBase.cs |
Injects IProcessRunner, adds ExecuteContainerCommandForOutputAsync, InspectImageConfigAsync, InspectImageManifestAsync |
src/Aspire.Hosting/Publishing/IContainerRuntime.cs |
Adds InspectImageConfigAsync and InspectImageManifestAsync to the interface |
src/Aspire.Hosting/Publishing/DockerContainerRuntime.cs |
Updated constructor to accept IProcessRunner |
src/Aspire.Hosting/Publishing/PodmanContainerRuntime.cs |
Updated constructor to accept IProcessRunner |
src/Aspire.Hosting.Azure/Provisioning/ProvisioningContext.cs |
UserPrincipal extended with RoleManagementPrincipalType |
src/Aspire.Hosting.Azure/Provisioning/Internal/DefaultUserPrincipalProvider.cs |
Detects app-only tokens via idtyp/appid JWT claims |
src/Aspire.Hosting.Azure/Provisioning/Provisioners/BicepProvisioner.cs |
Populates UserPrincipalId and PrincipalType well-known parameters |
src/Aspire.Hosting.Azure/Provisioning/BicepUtilities.cs |
Threads ValueProviderContext to IValueProvider.GetValueAsync |
src/Aspire.Hosting.Azure/AcrLoginService.cs |
Extracts retry logic, adds GetRefreshTokenAsync |
src/Aspire.Hosting.Azure/IAcrLoginService.cs |
Adds GetRefreshTokenAsync and AcrRefreshToken record |
src/Aspire.Hosting.Azure.Sandboxes/README.md |
New hosting README (has guideline violations) |
tests/Aspire.Hosting.Azure.Tests/AzureSandboxesTests.cs |
20 unit tests for sandbox resources, ADC client, provisioning |
tests/Aspire.Hosting.Tests/Publishing/FakeContainerRuntime.cs |
Implements new InspectImage* methods |
tests/Aspire.Hosting.Tests/Publishing/ContainerRuntimeBaseTests.cs |
Tests ExecuteContainerCommandForOutputAsync |
tests/Aspire.Deployment.EndToEnd.Tests/AzureSandboxesDeploymentTests.cs |
Guarded E2E deployment test using TypeScript AppHost |
tests/Aspire.Hosting.Azure.Tests/Snapshots/ (10+ files) |
Verified Bicep and JSON snapshot files |
playground/AzureSandboxes/ |
Playground apps for manual validation |
.github/workflows/deployment-tests.yml |
CI config for sandbox deployment tests |
Copilot's findings
Files not reviewed (4)
- playground/AzureSandboxes/NodeStorageApp/package-lock.json: Generated file
- playground/AzureSandboxes/SandboxAppServiceMixed.Frontend/package-lock.json: Generated file
- playground/TypeScriptApps/SandboxStaticSite/package-lock.json: Generated file
- playground/TypeScriptApps/SandboxStaticSite/site/package-lock.json: Generated file
- Files reviewed: 112/117 changed files
- Comments generated: 2
| # Aspire.Hosting.Azure.Sandboxes library | ||
|
|
||
| Provides extension methods and resource definitions for an Aspire AppHost to configure Azure Container Apps sandboxes and connector gateway resources. | ||
|
|
||
| ## Getting started | ||
|
|
||
| ### Prerequisites | ||
|
|
||
| * An Azure subscription with access to the Azure Container Apps sandbox and connector gateway preview features. | ||
| * Azure permissions to create resource groups, sandbox groups, connector gateways, role assignments, and any referenced Azure resources. | ||
|
|
||
| ### Install the package | ||
|
|
||
| In your AppHost project, install the Aspire Azure Sandboxes Hosting library with [NuGet](https://www.nuget.org): | ||
|
|
||
| ```dotnetcli | ||
| dotnet add package Aspire.Hosting.Azure.Sandboxes | ||
| ``` | ||
|
|
||
| ## Usage example | ||
|
|
||
| Then, in the _AppHost.cs_ file of `AppHost`, add an Azure sandbox group and publish a compute resource to it using the following methods: | ||
|
|
||
| ```csharp | ||
| var sandboxGroup = builder.AddAzureSandboxGroup("sandboxes"); | ||
|
|
||
| builder.AddProject<Projects.ApiService>("api") | ||
| .WithExternalHttpEndpoints() | ||
| .PublishAsSandbox(sandboxGroup); | ||
| ``` | ||
|
|
||
| ## Connector trigger limitations | ||
|
|
||
| Connector gateway, connection, MCP server config, access policy, and trigger config resources can be modeled and provisioned by the AppHost. The current implementation does not run an interactive OAuth consent flow for connector connections. For connectors that require user consent, such as SharePoint, complete the connection authorization outside Aspire before relying on authenticated connector trigger delivery. | ||
|
|
||
| ## Configure Azure Provisioning for local development | ||
|
|
||
| Adding Azure resources to the Aspire application model will automatically enable development-time provisioning for Azure resources so that you don't need to configure them manually. Provisioning requires a number of settings to be available via .NET configuration. The Aspire dashboard will prompt you to set these values if they are not already configured. See [Local Azure Provisioning](https://aspire.dev/integrations/cloud/azure/local-provisioning/) for more details. | ||
|
|
||
| > NOTE: Developers must have Owner access to the target subscription so that role assignments can be configured for the provisioned resources. | ||
|
|
||
| ## Additional documentation | ||
|
|
||
| * https://learn.microsoft.com/azure/container-apps/sessions-code-interpreter | ||
| * https://learn.microsoft.com/azure/connectors/connectors-create-api-sharepointonline | ||
|
|
||
| ## Feedback & contributing | ||
|
|
||
| https://github.com/microsoft/aspire |
| public virtual Task<string> InspectImageConfigAsync(string imageName, CancellationToken cancellationToken) | ||
| { | ||
| ArgumentException.ThrowIfNullOrWhiteSpace(imageName); | ||
|
|
||
| return ExecuteContainerCommandForOutputAsync( | ||
| $"image inspect \"{imageName}\" --format \"{{{{json .Config}}}}\"", | ||
| "inspect image config", | ||
| imageName, | ||
| cancellationToken); | ||
| } | ||
|
|
||
| public virtual Task<string> InspectImageManifestAsync(string imageName, CancellationToken cancellationToken) | ||
| { | ||
| ArgumentException.ThrowIfNullOrWhiteSpace(imageName); | ||
|
|
||
| return ExecuteContainerCommandForOutputAsync( | ||
| $"manifest inspect \"{imageName}\"", | ||
| "inspect image manifest", | ||
| imageName, | ||
| cancellationToken); | ||
| } |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Description
Adds a new experimental Aspire hosting package for Azure Container Apps Sandboxes so we can investigate this deployment target end to end. The deployment path is container-image based: Aspire builds and pushes compute resources, converts the pushed OCI image into a sandbox disk image, creates a sandbox from that disk image, applies lifecycle settings, exposes endpoint-derived ports, persists endpoint state, and cleans up sandbox/disk state during destroy.
Sandbox ARM resources are modeled with Azure.Provisioning/Bicep. Sandbox runtime operations use an internal ADC HTTP client for the regional Azure Dev Compute management endpoint (
https://management.{region}.azuredevcompute.io) withapi-version=2026-02-01-preview.This includes:
Aspire.Hosting.Azure.Sandboxespackage and sandbox group deployment environment resource.User-facing usage
C# AppHost:
TypeScript AppHost:
Connector trigger callback into a sandbox-hosted app:
Running
aspire deploybuilds and pushes images, provisions Azure resources, creates sandbox disk images and sandboxes through ADC APIs, exposes modeled HTTP endpoints through the sandbox proxy, and then provisions late trigger configs once sandbox callback URLs exist.Validation
dotnet test --project tests/Aspire.Hosting.Azure.Tests/Aspire.Hosting.Azure.Tests.csproj --no-launch-profile -- --filter-class "*.AzureSandboxesTests" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"(20 tests)dotnet build playground/AzureSandboxes/SandboxAllFeatures.AppHost/SandboxAllFeatures.AppHost.csproj /p:SkipNativeBuild=trueaspire deploy --list-steps --apphost playground/AzureSandboxes/SandboxAllFeatures.AppHost/SandboxAllFeatures.AppHost.csproj --non-interactivedotnet build tests/Aspire.Deployment.EndToEnd.Tests/Aspire.Deployment.EndToEnd.Tests.csproj /p:SkipNativeBuild=true --nologoGITHUB_ACTIONS=true ASPIRE_DEPLOYMENT_TEST_ENABLE_SANDBOXES=false dotnet test --project tests/Aspire.Deployment.EndToEnd.Tests/Aspire.Deployment.EndToEnd.Tests.csproj --no-build --no-launch-profile -- --filter-class "*.AzureSandboxesDeploymentTests" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"Live Azure E2E validation completed against subscription
39a289cd-f0fc-4d59-a745-17cf49d6aafd, regionwestus3:/environment; destroyed and verified resource group deletion./storage, and blob create/list/read with managed identity; destroyed and verified resource group deletion./api/message; destroyed and verified resource group deletion.rg-aspire-sbx-all-0604-2249; verified App Service backend, sandbox frontend, sandbox Node + Storage APIs, sandbox/webhook, connector gateway connections, MCP server config, trigger config, gateway connection access policy, sandbox group RBAC for deployment principal and gateway service principal, and Storage data-plane RBAC for the Node managed identity. Destroy completed 13/13 steps andaz group existsreturnedfalse.The guarded deployment E2E test now uses a TypeScript AppHost and is opt-in for live sandbox deployment through
ASPIRE_DEPLOYMENT_TEST_ENABLE_SANDBOXES.The SharePoint connector resources provision successfully, but the live SharePoint connections remain unauthenticated until interactive OAuth consent is completed. Actual SharePoint event firing was not exercised in the automated E2E validation.
Security considerations
This change creates public sandbox proxy endpoints for external endpoints, obtains ACR refresh tokens for private image disk conversion, invokes the local container runtime for image build/push/inspect, sends resolved environment values to the sandbox data-plane API, and grants Azure RBAC roles for sandbox deployment/runtime operations. No threat model or security review has been completed yet; this PR is draft.
Fixes # (issue)
Checklist
<remarks />and<code />elements on your triple slash comments?