Repository navigation
azd foundry app insights VNET support - #10819
Conversation
|
Azure Pipelines: 5 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Thank you for your contribution Kayla Seager (@kseager)! We will review the pull request and get back to you soon. |
2152de9 to
8ad9393
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Critical gaps in private-monitoring conflict checks can disrupt shared DNS and existing telemetry, while workspace ingestion remains publicly accessible despite the private-only configuration.
9 open issues
Skip monitoring when endpoint conflict checks are inconclusive · New Check conflicts before the existing-connection early return · New Exempt only the exact planned scope ID from conflict checks · New Gate monitoring creation on BYO egress · New Protect the Bicep deployment path from endpoint conflicts · New Validate shared DNS zones before binding Monitor endpoints · New Disable public ingestion on the workspace too · New Make skip warnings persistent and visible in automated runs · New Document VNet-wide Monitor routing impact and opt-out · New
What changed in this PR
Extends the Foundry infrastructure synthesis shared by the Projects and Agents extensions to support private Application Insights ingestion for new projects using customer-provided agent subnets.
Changes:
- Adds Azure Monitor private-link infrastructure, DNS integration, a project capability host, and an ordered component re-sync.
- Enables BYO-network monitoring with endpoint-conflict checks and private-ingestion policy validation.
- Updates embedded ARM templates, Bicep exports, tests, and networking documentation.
Extension user-contract review: blocked (23 files inspected; 0 new contract comments; 0 matched threads; review history unavailable).
| File | Description |
|---|---|
cli/azd/extensions/azure.ai.projects/synthesis/vnet_requirements_test.go |
Checks capability-host template requirements. |
cli/azd/extensions/azure.ai.projects/synthesis/templates/modules/resources.bicep |
Adds the project capability host and network outputs. |
cli/azd/extensions/azure.ai.projects/synthesis/templates/modules/monitoring.bicep |
Wires private monitoring and component re-sync. |
cli/azd/extensions/azure.ai.projects/synthesis/templates/modules/monitoring-resync.bicep |
Reapplies the component after private-link setup. |
cli/azd/extensions/azure.ai.projects/synthesis/templates/modules/monitor-private-link.bicep |
Defines the Monitor scope, endpoint, and DNS resources. |
cli/azd/extensions/azure.ai.projects/synthesis/templates/main.bicep |
Passes network settings into monitoring. |
cli/azd/extensions/azure.ai.projects/synthesis/templates/main.arm.json |
Regenerates embedded new-project infrastructure. |
cli/azd/extensions/azure.ai.projects/synthesis/templates/existing-project.arm.json |
Regenerates the embedded monitoring module. |
cli/azd/extensions/azure.ai.projects/synthesis/synthesizer.go |
Enables monitoring creation for BYO networks. |
cli/azd/extensions/azure.ai.projects/synthesis/monitoring_test.go |
Updates network-specific monitoring expectations. |
cli/azd/extensions/azure.ai.projects/synthesis/monitoring_resolver.go |
Applies private-network component validation. |
cli/azd/extensions/azure.ai.projects/synthesis/monitoring_private_link.go |
Adds Monitor endpoint-conflict discovery. |
cli/azd/extensions/azure.ai.projects/synthesis/monitoring_private_link_test.go |
Tests conflicts, template settings, and ingestion policy. |
cli/azd/extensions/azure.ai.projects/synthesis/monitoring_policy.go |
Allows disabled public ingestion on private paths. |
cli/azd/extensions/azure.ai.projects/README.md |
Documents private monitoring behavior and limits. |
cli/azd/extensions/azure.ai.projects/internal/provisioning/monitoring_preflight.go |
Integrates private-network monitoring checks and skips. |
cli/azd/extensions/azure.ai.projects/internal/provisioning/monitoring_preflight_test.go |
Retargets the unsupported-network skip test to reuse. |
cli/azd/extensions/azure.ai.projects/internal/provisioning/monitoring_graph.go |
Applies private-network policy during graph validation. |
cli/azd/extensions/azure.ai.projects/internal/cmd/project_existing_infra.go |
Exports the new monitoring Bicep dependencies. |
cli/azd/extensions/azure.ai.projects/cspell.yaml |
Adds Monitor terminology to spell checking. |
cli/azd/extensions/azure.ai.agents/internal/cmd/init_infra.go |
Includes both new modules in Bicep exports. |
cli/azd/extensions/azure.ai.agents/docs/private-networking.md |
Describes private monitoring support and exclusions. |
cli/azd/extensions/azure.ai.agents/cspell.yaml |
Adds the Azure Monitor group identifier. |
Review effort: Max
Adds AMPLS, azuremonitor private endpoint, private DNS zones, project capability host, and a deterministic App Insights component re-sync after the AMPLS scoped resources so ingestion is reliable on fresh environments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491
… ingestion, docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491
9257128 to
ee24b66
Compare
There was a problem hiding this comment.
🔵 Needs a closer look
Human assessment is needed because private-monitoring safety gaps across network checks, legacy templates, and shared DNS reuse can permit public ingestion or disrupt other projects’ telemetry.
No open issues 🎉
Review effort: Max
Hosted agents export telemetry with their instance identity, which only exists after the agent version is created. Grant it Monitoring Metrics Publisher on the azd-managed App Insights component at deploy time (best effort, with a manual command on failure). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491
…role Application Insights caches Entra ingestion authorization, so a new Monitoring Metrics Publisher assignment returned 403 for over 20 minutes until the component was updated. Merge a tag on the component after a new assignment to force a refresh. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491
There was a problem hiding this comment.
🔵 Needs a closer look
The monitoring gate applies RBAC and tag writes to public-network and customer-owned components, contradicting documented ownership guarantees and introducing unnecessary deployment permission requirements.
4 open issues
Review effort: Max
… honor skip opt-out, surface warnings in deploy note Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491
There was a problem hiding this comment.
🟡 Changes recommended
Activity-only hosted agents drop failed or skipped publisher-grant warnings when no artifacts are produced, leaving successful deployments without the recovery command.
1 open issue
4 resolved since last review
Review effort: Max
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491
…g refresh Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491
There was a problem hiding this comment.
🔵 Needs a closer look
Human assessment is needed because private-network DNS conflicts and monitoring-dependent egress rules can block provisioning, disrupt existing workloads, or break hosted-agent connectivity.
No open issues 🎉
2 resolved since last review
Review effort: Max
…nstants Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491
There was a problem hiding this comment.
🔵 Needs a closer look
Human assessment is needed because interactions among monitoring, private networking, and authorization can cause provisioning failures, hosted-agent connectivity loss, or silent permission-refresh failures.
No open issues 🎉
Review effort: Max
|
/check-enforcer override |
* Add private Azure Monitor path for VNet-injected Foundry projects Adds AMPLS, azuremonitor private endpoint, private DNS zones, project capability host, and a deterministic App Insights component re-sync after the AMPLS scoped resources so ingestion is reliable on fresh environments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Test private link conflict check edge cases Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Add Azure Monitor terms to cspell dictionaries Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Connect existing App Insights component on BYO-egress private networks Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Address review: gate private monitoring, exact owned scope, workspace ingestion, docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Approve private monitoring before planning, keep BYO private link reconciled, fix ingestion-only wording Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Keep owned private monitoring on conflict, reuse preserved keyless connections, add preflight tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Give a reuse-specific recovery message when a failed private reuse-connect retry no longer matches the template Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Document shared-VNet impact of the Azure Monitor private link scope and how to keep other telemetry Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Support private monitoring on managed egress Add an ampls-monitor-rule outbound rule to the managed network, grant the account identity the Network Connection Approver role, and stop skipping monitoring for managed egress. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Fix spelling in managed egress monitoring docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Include principal in managed-egress network approver role assignment name Deploy the assignment through a module so the GUID is derived from scope, principal and role, avoiding RoleAssignmentUpdateNotPermitted when the account is recreated with the same project ID. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Include network-approver-role-assignment module in Bicep ejects monitoring.bicep references the module, so both eject paths must copy it or compilation fails. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Add account self private endpoint rule for managed-egress hosted agents Hosted agents fail with 'Public access is disabled' under a managed network unless the account has an outbound private endpoint rule to itself. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Document managed-egress self private endpoint rule and validation status Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Add ampls to agents extension cspell words Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Canonicalize and clean up the owned Private Link Scope output; block owned envs on unresolved vnetId Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Grant hosted agent identity Monitoring Metrics Publisher on deploy Hosted agents export telemetry with their instance identity, which only exists after the agent version is created. Grant it Monitoring Metrics Publisher on the azd-managed App Insights component at deploy time (best effort, with a manual command on failure). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Refresh App Insights component after granting hosted agent publisher role Application Insights caches Entra ingestion authorization, so a new Monitoring Metrics Publisher assignment returned 403 for over 20 minutes until the component was updated. Merge a tag on the component after a new assignment to force a refresh. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Gate hosted-agent monitoring grant to private azd-created components, honor skip opt-out, surface warnings in deploy note Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Re-apply monitoring sync tag on deploy when it is missing Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Surface monitoring grant warning for Activity-only agents and test tag refresh Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 * Split monitoring publisher grant into focused files and centralize constants Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491 --------- Co-authored-by: Kayla Porter <kaseager@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c1d0003f-40c8-481d-92a5-ecb8d7afb491



Scope
ampls-monitor-ruleoutbound rule.foundry-account-peoutbound rule (account to itself), required for hosted agents.AllowInternetOutbound.Problem
A project with a
network:block (VNet-injected agents) could not send traces: native azd monitoring created public-ingestion App Insights, and #10743 skips monitoring in that case. This PR adds a private path so agent traces arrive in App Insights and can be read from inside the network.What azd now provisions (new project,
network:with your own agent subnet, monitoring enabled)Ingestion is private only. Traces are sent through the AMPLS private endpoint and the component rejects public ingestion. Query matches Foundry sample 15 (AMPLS query
Open). Difference with S2 bug bash sample for VNET is that our set-up connects the App Insight/workspace to the project vs Foundry.Component re-sync (reliability fix)
In earlier fresh environments, ingestion intermittently returned
403 Component private link id does not match incoming linkfor 45 minutes or more (one environment stayed stuck for hours) after ARM reported everything Succeeded. Touching the component's tags cleared it immediately.Suspected cause: a stale routing cache. Private Link data-plane traffic is handled by internal distributed proxies (the Private Link mapping layer), which ARM does not expose. When the component is created, it registers routing metadata with no AMPLS link. Linking it through the AMPLS scoped resource updates the AMPLS side (the
scopedServicestable), but the proxy mapping for the component appears to be treated as a cache that is only refreshed by a modification event on the component itself. Until one arrives, the mapping can stay stale and ingestion keeps being rejected as a link-id mismatch. ARM only sees control-plane state, so it reports Succeeded while the data plane is still stale.A second PUT on the component, even one that only changes a tag, makes ARM send a metadata sync to the underlying resource provider. That should invalidate the stale mapping and reload the link ID.
This mechanism is inferred from the symptoms. It is not confirmed by Azure Monitor or Private Link documentation, and I have not verified it with the service team. The only evidence is the live runs below.
To fix this reliably,
monitoring-resync.bicepre-declares the component with identical properties after the AMPLS scoped resources exist, adding a deterministic tagazd-ampls-link(a hash of the scope ID and component name; noutcNow, so re-provision is a no-op). The project connection depends on it.Test evidence (westus3, jump VM inside the VNet, public ingestion off)
Flow per environment:
azd provisionfrom a laptop;azd deployandazd ai agent invokefrom the jump VM; traces read privately from the VM.AllowOnlyApprovedOutbound, headfcde87864)Notes and limits:
Behavior and limits
network.dns), a VNet that already has anazuremonitorprivate endpoint, or a network azd cannot inspect do not block provisioning: monitoring is skipped with a warning (opt-out:monitoring.enabled: false).ampls-monitor-rule(targetazuremonitor) lets the agent runtime reach the Private Link Scope.foundry-account-pe(targetaccount, to the account itself) is required for hosted agents. Without it they fail withPublic access is disabled. Prompt agents are not affected. Writes to this rule can be slow or fail transiently; re-runningazd provisionis the recovery.azd deploy(azd-created components on the private path only; skip withAZD_AGENT_SKIP_ROLE_ASSIGNMENTS=true), azd grants that identityMonitoring Metrics Publisheron the Application Insights component and updates a component tag so Application Insights refreshes its cached ingestion authorization (otherwise 403 for 20+ minutes). The deployer needs Owner, or User Access Administrator plus Contributor, on the component. If the grant is skipped or fails, the deploy note carries theaz role assignment createcommand.PrivateOnly, telemetry from the VNet to Azure Monitor resources that are not in the scope is blocked.Open, queries are not restricted to the private network. Verified live: private ingestion plus a read from inside the VNet, not a private-only read.Changes
synthesis/templates/modules/monitor-private-link.bicep: AMPLS, scoped resources,azuremonitorprivate endpoint, four DNS zones (create-and-link or reuse existing).synthesis/templates/modules/monitoring-resync.bicep(new), wired intomonitoring.bicep; added to both eject module lists.resources.bicep.main.arm.jsonandexisting-project.arm.json.TestMonitorPrivateLinkAccessModes,TestMonitoringResyncMatchesComponent,TestCheckMonitorPrivateLinkConflict,TestMonitoringKeyPolicyForPrivateNetwork, VNet requirement tests, preflight tests, hosted-agent grant tests.README.mdandazure.ai.agents/docs/private-networking.md.Not covered
One region. Prompt-agent traces under managed egress (descoped; not observed). Terraform parity and eject for this module follow the same shape but were not live-tested. The project-scoped connection was exercised live only in the runs above.