feat: transfer Foundry provisioning to projects#9133
Conversation
|
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. |
|
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. |
📋 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
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. |
jongio
left a comment
There was a problem hiding this comment.
One test-coverage gap worth closing on the new synthesizer.
jongio
left a comment
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
brownfieldDeploymentsas well as connections. On the new connection-only path this remains a nil Go slice, so ARM receivesdeployments.value: nullfor 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, butResourceGroupLocationCheck.isBrownfieldFoundryProjectstill calls the raw-YAMLfoundryServiceEndpointhelper. Whenendpointcomes 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 samesynthesis.ProjectEndpointresolver in that check.
jongio
left a comment
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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_IDandendpointare 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 anaccounts/projectsresource 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
$refbefore recognizing a brownfield endpoint, butResourceGroupLocationCheck.isBrownfieldFoundryProjectstill readsendpointdirectly 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 sameProjectEndpointresolution with the project root in the validation check. (azd-code-reviewer)
| # 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
left a comment
There was a problem hiding this comment.
Reapproving after recent commit
jongio
left a comment
There was a problem hiding this comment.
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 } |
There was a problem hiding this comment.
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.
|
@copilot resolve the merge conflicts in this pull request |
Co-authored-by: huimiu <107838226+huimiu@users.noreply.github.com>
Resolved the merge conflicts and merged |
jongio
left a comment
There was a problem hiding this comment.
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
left a comment
There was a problem hiding this comment.
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.
Related to #9134
Why
Foundry project provisioning still lived in
azure.ai.agents, even thoughazure.ai.projectsowns 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
microsoft.foundryprovisioning provider fromazure.ai.agentstoazure.ai.projects.azure.ai.projects, while keeping the old agents path for backward compatibility.azd ai agent initandinit --infrainazure.ai.agentsfor now. Parity tests keep the temporary synthesis copies aligned.AZURE_AI_PROJECT_IDto the full project ARM resource ID.Follow-up work
azd ai agent initandinit --infralogic toazure.ai.projectsand remove the temporary agents-side copy.microsoft.foundrymeta-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.