Skip to content

feat: transfer Foundry provisioning to projects#9133

Open
huimiu wants to merge 18 commits into
mainfrom
hui/own-ai-project-service
Open

feat: transfer Foundry provisioning to projects#9133
huimiu wants to merge 18 commits into
mainfrom
hui/own-ai-project-service

Conversation

@huimiu

@huimiu huimiu commented Jul 14, 2026

Copy link
Copy Markdown
Member

Related to #9134

Why

Foundry project provisioning still lived in azure.ai.agents, even though azure.ai.projects owns project resources. Moving provisioning now gives each extension a clearer job. We are keeping init in agents temporarily so the handoff can be validated before moving the remaining setup flow.

What changed

  • Moved the microsoft.foundry provisioning provider from azure.ai.agents to azure.ai.projects.
  • Moved split-project deployment handling to azure.ai.projects, while keeping the old agents path for backward compatibility.
  • Kept azd ai agent init and init --infra in azure.ai.agents for now. Parity tests keep the temporary synthesis copies aligned.
  • Added support for updating deployments and connections on existing Foundry projects. These projects must set AZURE_AI_PROJECT_ID to the full project ARM resource ID.
  • Kept typed connection metadata while passing credentials separately as a secure ARM parameter.
  • Used the customer VNet region when creating private endpoints.
  • Blocked private-network projects from creating an ACR automatically, since the current templates do not create the ACR private networking they would need. Users should provide a pre-built image instead.
  • Added projects unit tests to the agents CI workflow and installed the local projects dependency before running agents tests.

Follow-up work

  • Move the remaining azd ai agent init and init --infra logic to azure.ai.projects and remove the temporary agents-side copy.
  • Publish the coordinated projects and agents releases, then update the extension registry and microsoft.foundry meta-package together.

Release notes

The projects and agents releases must be published together. Mixing old and new versions can cause both extensions to register the same provider.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).
20 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@github-actions github-actions Bot added ext-agents azure.ai.agents extension ext-projects azure.ai.projects extension labels Jul 14, 2026
@huimiu
huimiu marked this pull request as ready for review July 14, 2026 10:24
Copilot AI review requested due to automatic review settings July 14, 2026 10:24
@huimiu huimiu linked an issue Jul 14, 2026 that may be closed by this pull request
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).
20 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@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

Transfers Foundry provisioning ownership from azure.ai.agents to azure.ai.projects, including lifecycle projection, validation, infrastructure synthesis, and coordinated versioning.

Changes:

  • Registers the Foundry provider and validation checks in Projects.
  • Moves deployment projection while retaining legacy Agents fallback.
  • Adds synchronized release metadata, tests, templates, and documentation.

Reviewed changes

Copilot reviewed 66 out of 67 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
docs/reference/telemetry-data.md Updates telemetry ownership.
cli/azd/extensions/azure.ai.projects/version.txt Bumps Projects version.
cli/azd/extensions/azure.ai.projects/README.md Documents project ownership.
cli/azd/extensions/azure.ai.projects/internal/version/version.go Adds build metadata.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/terraform/variables.tf Defines Terraform inputs.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/terraform/provider.tf Configures Terraform providers.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/terraform/outputs.tf.tmpl Defines conditional outputs.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/terraform/main.tf Provisions core Foundry resources.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/terraform/acr.tf Provisions connected ACR.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/modules/subnet.bicep Adds subnet module.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/modules/resources.bicep Defines Foundry resources.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/modules/private-endpoint-dns.bicep Adds private endpoint and DNS.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/modules/network.bicep Adds VNet wiring.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/modules/connections.bicep Provisions project connections.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/modules/acr.bicep Adds Bicep ACR module.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/main.bicep Adds greenfield template.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/brownfield.bicep Adds existing-project template.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/brownfield.arm.json Embeds compiled brownfield ARM.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates/abbreviations.json Defines resource abbreviations.
cli/azd/extensions/azure.ai.projects/internal/synthesis/templates_embed.go Embeds provisioning templates.
cli/azd/extensions/azure.ai.projects/internal/synthesis/synthesizer.go Adds configuration synthesis.
cli/azd/extensions/azure.ai.projects/internal/synthesis/schema_test.go Tests schema and ARM parity.
cli/azd/extensions/azure.ai.projects/internal/synthesis/parity_test.go Enforces Agents synthesis parity.
cli/azd/extensions/azure.ai.projects/internal/provisioning/resource_group_location_check.go Moves location validation.
cli/azd/extensions/azure.ai.projects/internal/provisioning/resource_group_location_check_validate_test.go Ports validation tests.
cli/azd/extensions/azure.ai.projects/internal/provisioning/resource_group_location_check_test.go Ports location tests.
cli/azd/extensions/azure.ai.projects/internal/provisioning/provisioning_provider.go Defines provider constants.
cli/azd/extensions/azure.ai.projects/internal/provisioning/preview_helpers.go Moves preview helpers.
cli/azd/extensions/azure.ai.projects/internal/provisioning/preview_helpers_test.go Ports preview tests.
cli/azd/extensions/azure.ai.projects/internal/provisioning/ondisk_template.go Moves on-disk template support.
cli/azd/extensions/azure.ai.projects/internal/provisioning/ondisk_template_test.go Ports template tests.
cli/azd/extensions/azure.ai.projects/internal/provisioning/foundry_provisioning_provider.go Moves the Foundry provider.
cli/azd/extensions/azure.ai.projects/internal/provisioning/foundry_provisioning_provider_test.go Ports provider tests.
cli/azd/extensions/azure.ai.projects/internal/provisioning/foundry_provisioning_provider_resolveenv_test.go Tests environment resolution.
cli/azd/extensions/azure.ai.projects/internal/provisioning/foundry_provisioning_provider_destroy_confirm_test.go Tests destroy confirmation.
cli/azd/extensions/azure.ai.projects/internal/provisioning/foundry_provisioning_provider_brownfield_acr_test.go Tests brownfield ACR.
cli/azd/extensions/azure.ai.projects/internal/provisioning/contract_parity_test.go Enforces migration contract parity.
cli/azd/extensions/azure.ai.projects/internal/exterrors/errors.go Adds provider error helpers.
cli/azd/extensions/azure.ai.projects/internal/exterrors/codes.go Adds provisioning error codes.
cli/azd/extensions/azure.ai.projects/internal/cmd/version.go Uses shared version metadata.
cli/azd/extensions/azure.ai.projects/internal/cmd/service_target.go Updates ownership documentation.
cli/azd/extensions/azure.ai.projects/internal/cmd/root.go Registers providers and handlers.
cli/azd/extensions/azure.ai.projects/internal/cmd/project_service_config.go Projects deployment environment data.
cli/azd/extensions/azure.ai.projects/internal/cmd/project_service_config_test.go Tests lifecycle projection.
cli/azd/extensions/azure.ai.projects/internal/cmd/ownership_test.go Tests extension ownership metadata.
cli/azd/extensions/azure.ai.projects/internal/azure/client_options.go Configures Azure SDK clients.
cli/azd/extensions/azure.ai.projects/go.sum Updates dependency checksums.
cli/azd/extensions/azure.ai.projects/go.mod Adds provisioning dependencies.
cli/azd/extensions/azure.ai.projects/extension.yaml Declares provider ownership.
cli/azd/extensions/azure.ai.projects/cspell.yaml Adds spelling terms.
cli/azd/extensions/azure.ai.projects/ci-build.ps1 Updates CI linker metadata.
cli/azd/extensions/azure.ai.projects/CHANGELOG.md Adds Projects release notes.
cli/azd/extensions/azure.ai.projects/build.sh Updates Unix linker metadata.
cli/azd/extensions/azure.ai.projects/build.ps1 Updates Windows linker metadata.
cli/azd/extensions/azure.ai.projects/AGENTS.md Documents ownership and release flow.
cli/azd/extensions/azure.ai.agents/version.txt Bumps Agents version.
cli/azd/extensions/azure.ai.agents/README.md Documents transferred ownership.
cli/azd/extensions/azure.ai.agents/internal/project/provisioning_provider.go Updates provider ownership comment.
cli/azd/extensions/azure.ai.agents/internal/cmd/resource_services.go Retains legacy deployment fallback.
cli/azd/extensions/azure.ai.agents/internal/cmd/resource_services_test.go Tests split and legacy behavior.
cli/azd/extensions/azure.ai.agents/internal/cmd/listen.go Removes provider registration.
cli/azd/extensions/azure.ai.agents/extension.yaml Adds Projects dependency.
cli/azd/extensions/azure.ai.agents/docs/private-networking.md Updates networking ownership docs.
cli/azd/extensions/azure.ai.agents/CHANGELOG.md Adds Agents release notes.
cli/azd/extensions/azure.ai.agents/AGENTS.md Documents coordinated release flow.

Comment thread cli/azd/extensions/azure.ai.projects/CHANGELOG.md Outdated
Comment thread cli/azd/extensions/azure.ai.agents/CHANGELOG.md Outdated
Comment thread cli/azd/extensions/azure.ai.projects/internal/synthesis/synthesizer.go Outdated
Comment thread cli/azd/extensions/azure.ai.projects/internal/cmd/project_service_config.go Outdated
Comment thread cli/azd/extensions/azure.ai.projects/internal/synthesis/synthesizer.go Outdated
Comment thread cli/azd/extensions/azure.ai.projects/internal/synthesis/synthesizer.go Outdated
Copilot AI review requested due to automatic review settings July 14, 2026 10:38
@huimiu
huimiu requested a review from danieljurek as a code owner July 14, 2026 10:38
@github-actions github-actions Bot added the area/extensions Extensions (general) label Jul 14, 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.

One test-coverage gap worth closing on the new synthesizer.

Comment thread cli/azd/extensions/azure.ai.projects/internal/synthesis/synthesizer.go Outdated

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 67 out of 68 changed files in this pull request and generated 8 comments.

Comment thread cli/azd/extensions/azure.ai.projects/internal/synthesis/synthesizer.go Outdated
Comment thread cli/azd/extensions/azure.ai.projects/internal/synthesis/synthesizer.go Outdated
Comment thread cli/azd/extensions/azure.ai.projects/internal/cmd/project_service_config.go Outdated
Comment thread cli/azd/extensions/azure.ai.projects/CHANGELOG.md Outdated
Comment thread cli/azd/extensions/azure.ai.agents/CHANGELOG.md Outdated
Comment thread cli/azd/extensions/azure.ai.projects/internal/synthesis/synthesizer.go Outdated

@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.

Re-reviewed the new fix: restore typed Foundry connection parameters commit. Switching connections from a @secure() securestring to a typed array reintroduces secret exposure: connection credentials (API keys for ApiKey / CustomKeys) now flow through a non-secure ARM parameter and land in deployment history. Details inline on connections.bicep.

Separately, the version mismatch from my earlier reviews is still open: azure.ai.agents/extension.yaml pins azure.ai.projects to ~1.0.0-beta.3 while projects ships 1.0.0-beta.2, so the agents install fails the constraint in test-ext-azure-ai-agents.yml, and registry installs hit the same mismatch.

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 66 out of 67 changed files in this pull request and generated 3 comments.

Comment thread cli/azd/extensions/azure.ai.agents/extension.yaml
Copilot AI review requested due to automatic review settings July 15, 2026 07:23

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 66 out of 67 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

cli/azd/extensions/azure.ai.projects/internal/provisioning/foundry_provisioning_provider.go:885

  • azd-code-reviewer: Normalize brownfieldDeployments as well as connections. On the new connection-only path this remains a nil Go slice, so ARM receives deployments.value: null for a non-nullable array parameter instead of [], causing template validation to fail before connections are reconciled.
    cli/azd/extensions/azure.ai.projects/internal/provisioning/foundry_provisioning_provider.go:157
  • azd-code-reviewer: This makes brownfield detection $ref-aware for the provider, but ResourceGroupLocationCheck.isBrownfieldFoundryProject still calls the raw-YAML foundryServiceEndpoint helper. When endpoint comes from a service $ref, the globally dispatched validation check treats the project as greenfield and can block it because of an unrelated stale resource-group/location mismatch. Use the same synthesis.ProjectEndpoint resolver in that check.

Copilot AI review requested due to automatic review settings July 15, 2026 10:41

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.

Copilot wasn't able to review this pull request because it exceeds the maximum diff size. Try reducing the number of changed files and lines, and requesting a review from Copilot again.

@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.

Reviewed the template hardening commit. Credential values now ride in a secure object parameter, the private endpoint uses the customer VNet region, and the Terraform version constraint matches the optional-attribute usage. Changes are mirrored across both extensions with matching tests.

func preprovisionHandler(ctx context.Context, azdClient *azdext.AzdClient, args *azdext.ProjectEventArgs) error {
deployments, err := collectProjectDeployments(args.Project.Services)
if err != nil {
if err := updateLegacyProjectDeployments(

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.

What are "legacy projects"?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

By “legacy projects,” I mean existing azure.yaml projects using the older azure.ai.agent or microsoft.foundry service shapes instead of azure.ai.project. We’re keeping this path for backward compatibility while provisioning moves to azure.ai.projects, and we recommend using azure.ai.project for new projects.

Copilot AI review requested due to automatic review settings July 16, 2026 10:17

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 79 out of 80 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

cli/azd/extensions/azure.ai.projects/internal/provisioning/foundry_provisioning_provider.go:806

  • AZURE_AI_PROJECT_ID and endpoint are combined without verifying that they identify the same project: the account and resource group come from the environment ID, while the project name comes from the endpoint. A stale or manually copied ID can therefore update model deployments—and potentially create an ACR or connections—in a different account while returning another project's endpoint. Parse the ID as an accounts/projects resource and reject it unless its account and project match the endpoint before what-if or deployment. (azd-code-reviewer)
    cli/azd/extensions/azure.ai.projects/internal/provisioning/foundry_provisioning_provider.go:157
  • This path now resolves $ref before recognizing a brownfield endpoint, but ResourceGroupLocationCheck.isBrownfieldFoundryProject still reads endpoint directly from raw YAML. When the endpoint exists only in the referenced file, validation treats the project as greenfield and can block provisioning because of an unrelated resource-group location. Use the same ProjectEndpoint resolution with the project root in the validation check. (azd-code-reviewer)

Comment on lines +88 to +90
# Created one at a time; ARM throttles concurrent deployments on one account.
resource "azurerm_cognitive_deployment" "model" {
for_each = { for d in var.deployments : d.name => d }

@trangevi trangevi 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.

Reapproving after recent commit

@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.

One correctness concern on the Terraform provisioning path, otherwise the incremental change since my last look is just a docs wording tweak.


# Created one at a time; ARM throttles concurrent deployments on one account.
resource "azurerm_cognitive_deployment" "model" {
for_each = { for d in var.deployments : d.name => d }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This for_each won't serialize the deployments the way the comment above claims. Terraform creates for_each instances concurrently (up to -parallelism, default 10), so all model deployments get submitted to the account at once. There's no depends_on chain or other ordering between them here. The Bicep path handles the same constraint deliberately with @batchSize(1) in resources.bicep (Sequential model deployment creation; ARM throttles concurrent deployments on the same account). Without an equivalent here, multi-model provisioning can hit the ARM concurrent-deployment throttle and fail intermittently. Consider chaining the deployments so only one is in flight at a time, or documenting a required -parallelism=1 for this template.

@huimiu

huimiu commented Jul 17, 2026

Copy link
Copy Markdown
Member Author

@copilot resolve the merge conflicts in this pull request

Co-authored-by: huimiu <107838226+huimiu@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 17, 2026 08:53
@huimiu
huimiu removed the request for review from Copilot July 17, 2026 08:53

Copilot AI commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Resolved the merge conflicts and merged origin/main into this branch in c1f48e7. I kept Foundry provisioning ownership in azure.ai.projects and updated the transferred validation-check comment to use the current arm-provision terminology.

@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.

Caught up since my last pass. The origin/main merge in c1f48e7 and the telemetry doc reword are clean, no new issues there.

Still open from before: the Terraform for_each on azurerm_cognitive_deployment.model in azure.ai.projects/internal/synthesis/templates/terraform/main.tf. The comment says the deployments are created one at a time because ARM throttles concurrent deployments on a single account, but for_each does not serialize them. Terraform schedules the instances concurrently (up to -parallelism, default 10), so under real throttling this can intermittently hit 429s. Either the comment is inaccurate or the serialization is missing. If one-at-a-time is genuinely required, chain the deployments with explicit ordering rather than relying on the comment. Line-level detail is on the existing thread.

@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.

Re-reviewed the current HEAD after the merge of origin/main and the telemetry docs wording fix. The merge-conflict resolution keeps Foundry provisioning ownership in azure.ai.projects and aligns the transferred validation check with main's arm-provision terminology, which is consistent with the design. The merged main changes (the preflight to provision validation rename and the telemetry field renames) don't change this PR's behavior. No new issues in the incremental changes.

One mechanical heads up: the branch shows as conflicting again since main advanced past the merge commit, so it'll need another merge from main before it can go in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/extensions Extensions (general) ext-agents azure.ai.agents extension ext-projects azure.ai.projects extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task] Coordinate Foundry provider handoff release

6 participants