fix: stamp endpoint on ai-project service in adopt flow for existing projects - #9051
Conversation
…projects When the adopt init flow (Start new from a template) selected an existing Foundry project, configureFoundryProject correctly set environment variables (FOUNDRY_PROJECT_ENDPOINT, USE_EXISTING_AI_PROJECT=true) but never wrote the endpoint to the azure.ai.project service in azure.yaml. The provisioning provider uses that endpoint field as the brownfield signal to reuse an existing project instead of creating a new one. Add a SetServiceConfigValue call after configureFoundryProject returns with a non-nil FoundryProject to stamp the endpoint onto the existing ai-project service in azure.yaml. Fixes #9050 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
📋 Prioritization NoteThanks for the contribution! The linked issue isn't in the current milestone yet. |
There was a problem hiding this comment.
Pull request overview
This PR fixes issue #9050, where the azd AI agents "adopt" init flow (azd ai agent init → "Start new from a template" → "Use an existing Foundry project") ignored the user's existing-project selection and provisioned brand-new resources on the subsequent azd up. The provisioning provider treats the endpoint: field on the azure.ai.project service as its brownfield signal (synthesizer.go returns ErrEndpointBrownfield when set), but the adopt flow set the corresponding environment variables without ever stamping that endpoint: field into azure.yaml. The fix writes the endpoint onto the existing ai-project service via SetServiceConfigValue after configureFoundryProject returns a selected project.
Changes:
- After
configureFoundryProject, stamp the selected project'sEndpoint()onto the existingazure.ai.projectservice (Path: "endpoint") so provisioning recognizes the brownfield signal. - Guard the write behind a non-empty endpoint and an existing project service key (
existingProjectServiceKey), so the "create new" path is unaffected. - Add two tests plus an in-process gRPC recording server/client helper.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
cli/azd/extensions/azure.ai.agents/internal/cmd/init_adopt.go |
Stamps the existing project endpoint onto the ai-project service after project selection; correct brownfield mechanism and safe (result is non-nil on success). |
cli/azd/extensions/azure.ai.agents/internal/cmd/init_adopt_test.go |
Adds two "adopt flow" tests and a gRPC recorder helper; both tests bypass/duplicate production logic rather than exercising runInitFromAzureYaml, and the helper duplicates an existing same-package helper. |
Address PR review feedback: - Extract the endpoint stamping logic into a reusable stampProjectEndpoint helper in resource_services.go so the production code is testable directly. - Rewrite tests to call the real stampProjectEndpoint function instead of duplicating its logic inline. - Extend the existing recordingProjectServer with configValues to capture non-'uses' SetServiceConfigValue calls, eliminating the duplicate gRPC server/client helpers. - Add a third test case (no existing project service) for better coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Why
When a user runs
azd ai agent init, selects "Start new from a template", and chooses "Use an existing Foundry project", the subsequentazd upignores that selection and provisions a brand-new account/project. The user's chosen project is never reused.Root Cause
The "adopt" init flow (
init_adopt.go) callsconfigureFoundryProject()which correctly sets environment variables (FOUNDRY_PROJECT_ENDPOINT,USE_EXISTING_AI_PROJECT=true,AZURE_AI_PROJECT_ID, etc.), but never writes theendpoint:field to theazure.ai.projectservice in azure.yaml.The provisioning provider uses that
endpoint:field as its brownfield signal -- if present, it connects to the existing project; if absent, it creates a new one. Since the adopt flow never stamped the endpoint, provisioning always took the "create new" path.Fix
After
configureFoundryProjectreturns with a non-nilFoundryProject, callSetServiceConfigValueto write the endpoint onto the existingai-projectservice in azure.yaml. This uses the sameexistingProjectServiceKeyhelper the codebase already provides.The resulting azure.yaml now includes:
Which the provisioning provider recognizes as brownfield, skipping new resource creation.
Testing
TestAdoptFlow_WritesEndpointForExistingProject-- verifies the endpoint is written viaSetServiceConfigValuewhen an existing project is selectedTestAdoptFlow_SkipsEndpointWhenNoExistingProject-- verifies no endpoint is written when the user chose "Create new"Fixes: #9050