Skip to content

Fix: ACR not created/linked for hosted container agents (#8861)#8880

Merged
trangevi merged 6 commits into
mainfrom
fix/include-acr-hosted-source-agents
Jun 30, 2026
Merged

Fix: ACR not created/linked for hosted container agents (#8861)#8880
trangevi merged 6 commits into
mainfrom
fix/include-acr-hosted-source-agents

Conversation

@hund030

@hund030 hund030 commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Fixes #8861

Issue

A hosted container agent (built from source) could deploy without an Azure Container Registry being created/wired, leaving AZURE_CONTAINER_REGISTRY_ENDPOINT unset. azd up then failed at container publish:

container publish failed: could not determine container registry endpoint ...
'AZURE_CONTAINER_REGISTRY_ENDPOINT' environment variable has been set

Root cause

An ACR is provisioned/wired in two different paths, and both had holes:

  • Brownfield (reusing an existing project, endpoint: set): the bicep-less init flow defers ACR to the provider, but the provider's brownfield path only reconciled model deployments and never created an ACR — so the env var was never produced and the ACR question was never asked.
  • Greenfield (new project): deriveIncludeAcr gated includeAcr on a docker: block, but docker: isn't part of the azure.ai.agent schema. A schema-conformant hand-authored agent (kind: hosted, no docker:/image:/codeConfiguration:, like schemas/examples/simple.azure.yaml) got includeAcr=false.

Two related brownfield UX gaps surfaced once provisioning was wired: provision --preview reported "nothing to provision", and init --infra failed with a cryptic service has endpoint: (brownfield) error.

What changed

  • init: for a container agent on an existing project, configure ACR even in the bicep-less flow (discover the project's registry connection, or prompt / "create a new one").
  • brownfield.bicep + provider: create a Premium ACR, grant AcrPull to the project identity, add a ContainerRegistry connection, and surface the registry outputs when the acr pending-provision reason is set.
  • preview: provision --preview runs a what-if so the ACR/deployments show as Creates; also fixed a latent 64-char ARM deployment-name overflow.
  • init --infra: clear "unsupported for existing-project configs" error instead of the raw synthesizer error.
  • deriveIncludeAcr: key on the schema fields (codeConfiguration/image/hosted) instead of docker:, matching the deploy-time contract.

Validation

  • Added unit tests for the brownfield ACR logic, the --infra refusal, and expanded synthesizer cases (schema-conformant hosted, kind omitted, image:, codeConfiguration:).
  • go build, gofmt -s, golangci-lint (0 issues), full go test ./..., and the bicep drift test all pass.
  • Verified end-to-end on a live subscription: azd up now creates the ACR + connection, sets AZURE_CONTAINER_REGISTRY_ENDPOINT, and publish/deploy succeed; provision --preview renders the Create plan; init --infra shows the clear message. Test resources were cleaned up.

hund030 added 3 commits June 30, 2026 15:14
When a hosted container agent reuses an existing (brownfield) Foundry
project, no Azure Container Registry was provisioned and
AZURE_CONTAINER_REGISTRY_ENDPOINT was never set, so 'azd up' failed at
container publish with 'could not determine container registry endpoint'.

The unified (bicepless) init flow skipped ACR connection discovery for
existing projects, and the brownfield provision path only reconciled
model deployments. This wires the existing design end to end:

- init: configure ACR for an existing project when the agent builds a
  container (discover a project connection, or prompt for a login server
  / create-on-provision), instead of skipping it with the rest of the
  bicepless connection setup.
- brownfield.bicep: optionally create a Premium ACR, grant AcrPull to
  the project managed identity, and add a ContainerRegistry connection.
- provider: deployBrownfield creates the ACR when init flagged 'acr' in
  AI_AGENT_PENDING_PROVISION and no endpoint is set, then surfaces the
  registry outputs.
Follow-up to the brownfield ACR support. For an existing-project
(endpoint:) config, 'azd provision --preview' reported 'nothing to
provision' even when a container registry would be created, and
'azd ai agent init --infra' failed with a cryptic synthesizer error.

- Preview: previewBrownfield runs a resource-group-scoped what-if on
  brownfield.arm.json so the registry and any model deployments show as
  Creates. Deploy and Preview now share brownfieldParams.
- init --infra: refuse with CodeInfraEjectBrownfieldUnsupported and a
  clear message instead of the raw synthesis error. An ejected ./infra/
  is never compiled for an endpoint: project, so ejecting would mislead.
- Fix a latent 64-char ARM deployment-name overflow for long project
  names via brownfieldDeploymentName (affected real deploys too).
deriveIncludeAcr only set includeAcr when an agent declared a docker:
block, but docker: is not part of the azure.ai.agent schema. A
hand-authored greenfield project that follows the schema (kind: hosted
built from source, no docker:/image:/codeConfiguration: -- as in
schemas/examples/simple.azure.yaml) therefore got no container registry
and failed at container publish.

Key the decision on the schema fields instead, mirroring the deploy-time
contract: codeConfiguration => code/ZIP (no ACR), image => pre-built
(no ACR), otherwise a hosted agent builds from source and needs an ACR.
init-scaffolded projects (which always write docker:) are unaffected.
Copilot AI review requested due to automatic review settings June 30, 2026 08:13
@github-actions

Copy link
Copy Markdown

📋 Prioritization Note

Thanks for the contribution! The linked issue isn't in the current milestone yet.
Thank you for logging this issue; our team is reviewing it. If you need urgent prioritization, tag @RickWinter and @kristenwomack to let us know.

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

Fixes missing Azure Container Registry (ACR) provisioning/wiring for hosted container agents when reusing an existing (brownfield) Foundry project, and improves preview/eject UX for that brownfield path.

Changes:

  • Adds optional ACR creation + project connection wiring to the brownfield ARM/Bicep template, surfaced via new outputs.
  • Updates the Foundry provisioning provider to deploy/preview brownfield resources (models and/or ACR) based on AI_AGENT_PENDING_PROVISION, and caps brownfield deployment name length.
  • Adjusts ACR inclusion detection during synthesis to use schema-conformant signals (image / codeConfiguration) instead of the undocumented docker: block; adds/updates unit tests.

Reviewed changes

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

Show a summary per file
File Description
cli/azd/extensions/azure.ai.agents/internal/synthesis/templates/brownfield.bicep Extends brownfield template to optionally create/wire an ACR and emit related outputs.
cli/azd/extensions/azure.ai.agents/internal/synthesis/templates/brownfield.arm.json Regenerated ARM JSON reflecting the updated brownfield Bicep template.
cli/azd/extensions/azure.ai.agents/internal/synthesis/synthesizer.go Changes ACR inclusion derivation to align with schema fields and hosted-agent behavior.
cli/azd/extensions/azure.ai.agents/internal/synthesis/synthesizer_test.go Adds coverage for schema-conformant hosted agent shapes and ACR gating behavior.
cli/azd/extensions/azure.ai.agents/internal/project/foundry_provisioning_provider.go Implements brownfield ACR provisioning and what-if preview; adds capped brownfield deployment name and merges outputs safely.
cli/azd/extensions/azure.ai.agents/internal/project/foundry_provisioning_provider_brownfield_acr_test.go Adds unit tests for brownfield ACR request detection, naming, params, and deployment-name length capping.
cli/azd/extensions/azure.ai.agents/internal/exterrors/codes.go Adds a dedicated error code for unsupported brownfield --infra eject.
cli/azd/extensions/azure.ai.agents/internal/cmd/init_infra.go Refuses azd ai agent init --infra for brownfield projects with a clearer error.
cli/azd/extensions/azure.ai.agents/internal/cmd/init_infra_test.go Adds test asserting eject refusal for endpoint-based brownfield projects.
cli/azd/extensions/azure.ai.agents/internal/cmd/init_foundry_resources_helpers.go Ensures bicepless init still configures ACR for existing projects to unblock hosted container agents.
cli/azd/extensions/azure.ai.agents/internal/cmd/init_foundry_resources_helpers_test.go Updates bicepless short-circuit test to reflect the new ACR contract.

Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_foundry_resources_helpers.go Outdated
@github-actions github-actions Bot added the ext-agents azure.ai.agents extension label Jun 30, 2026

@jongio jongio left a comment

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.

Solid fix for the brownfield ACR gap. The two root causes are correctly identified and addressed: the bicepless flow not configuring ACR for container agents, and deriveIncludeAcr keying on the absent docker: block instead of the schema fields (codeConfiguration/image/kind). The brownfield Bicep template additions (conditional ACR + AcrPull role + connection) are well-structured.

A few observations:

  • brownfieldLocation can return "" when both AZURE_LOCATION and the resource-group lookup fail. The ARM template has defaultValue: resourceGroup().location for the location param, but passing an explicit empty string overrides that default rather than falling back to it. If there's a realistic path where neither source succeeds, the deploy would fail with a confusing ARM error about an invalid location.

  • brownfield.arm.json is missing a trailing newline (the diff shows No newline at end of file). Minor, but linters and some editors flag this.

  • The agentNeedsAcr helper defaults empty kind to "hosted" for back-compat. If a new kind is added in the future that also doesn't build containers (e.g., "serverless"), it would incorrectly trigger ACR creation. A comment noting this would help future contributors remember to update the function.

Test coverage is thorough: TestBrownfieldACRRequested, TestBrownfieldACRName, TestBrownfieldDeploymentName, and the synthesizer cases all cover the key scenarios well.

hund030 added 2 commits June 30, 2026 16:32
- brownfieldParams: only set the ARM 'location' parameter when resolved.
  An empty value (AZURE_LOCATION unset + RG lookup failure) would override
  the template default resourceGroup().location and fail the deployment.
- Correct the configureFoundryProjectEnv comment that still said the
  provider does not create an ACR for an existing project.
… newline

- agentNeedsAcr: note that a future non-container kind that omits kind:
  would need an explicit allowlist instead of defaulting to hosted.
- brownfield.arm.json: add trailing newline.
@hund030

hund030 commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for the review @jongio. Addressed all three observations:

  1. brownfieldLocation empty override (a5785cb) — brownfieldParams now omits the location param when unresolved, so the template default resourceGroup().location applies instead of an empty-string override. Added a unit test.
  2. brownfield.arm.json trailing newline (4831708) — added. (Note: main.arm.json is also generated without one by bicep build; the drift test normalizes JSON so this is cosmetic.)
  3. agentNeedsAcr empty-kind default (4831708) — added a comment to switch to an explicit allowlist if a future non-container kind can omit kind:.

Also addressed the two Copilot comments (same location fix + the stale configureFoundryProjectEnv doc comment). go build / gofmt / golangci-lint (0 issues) / full go test all pass.

CI (ext-azure-ai-agents-lint / go-fix) enforces 'go fix ./...' cleanliness.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ext-agents azure.ai.agents extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ACR was not created / linked or used.

4 participants