Skip to content

Support extending synthesized Foundry infra with user-owned Bicep #9256

Description

@huimiu

Summary

When a project uses the Foundry provider's synthesized infrastructure (infra.provider: microsoft.foundry), there is no first-class way to add your own Azure resources as an extra Bicep module while still letting azd auto-generate the Foundry infra. Today you must either fully eject and own the entire main.bicep, or run a second deployment from a postprovision hook.

We should close this gap so a user can supply a user-owned Bicep module (e.g. a Playwright workspace + Foundry connection) and have azd deploy it alongside the synthesized Foundry infra — for both greenfield and brownfield (existing project) scenarios.

Why this is needed

The browser-automation / Playwright sample needs to provision a custom Azure resource (Playwright workspace) and a Foundry connection as part of azd provision. The team already has the Bicep. The only options today are:

  • Eject and hand-edit the generated main.bicep — greenfield only, and the user now owns the full template, or
  • a postprovision hook that runs a separate az deployment group create.

Neither is a real "extend the infra" experience, and eject is not available at all for existing/brownfield projects. This pushes every custom-resource sample onto hook-based workarounds.

Current behavior (the gap)

From the Foundry synth flow in cli/azd/extensions/azure.ai.projects/internal/provisioning/foundry_provisioning_provider.go:

  1. No auto-merge. Before synth, the provider stat-checks only infra/main.bicep / infra/main.bicepparam (onDiskTemplatePresent). Any other .bicep file in infra/ is never scanned, referenced, or deployed — it is a dead file.
  2. main.bicep takes over. If infra/main.bicep exists, the provider logs skipping synthesizer and treats that file as the sole template. Everything the Foundry provider would have generated is gone unless the user re-adds it by hand.
  3. Brownfield cannot eject. For an existing project (endpoint: set), the on-disk Bicep path is skipped entirely, and azd ai agent init --infra rejects brownfield (cli/azd/extensions/azure.ai.agents/internal/cmd/init_infra.go). So there is no eject path at all for existing projects.

Net: the only way to add custom resources is a postprovision hook (a second deployment), which is what the official sample does.

Desired capability

Let a user extend the synthesized Foundry infra with their own Bicep module without:

  • fully ejecting / owning the whole main.bicep, or
  • resorting to a postprovision hook,

…and have it work for both greenfield and brownfield.

Possible directions (open for design)

  • A convention where azd auto-includes a user module (e.g. infra/extensions/*.bicep, or a declared module) into the synthesized deployment.
  • An azure.yaml field to reference additional Bicep modules to deploy alongside the synth output, with dependsOn ordering.
  • For brownfield: support a "resources/connection only" extension deployment targeted at the existing project's resource group.

Related note (separate gap)

The azure.ai.connection service host cannot currently express fields like audience / isSharedToAll that a Playwright connection needs, so today that connection still has to be authored in Bicep. Worth tracking alongside, but not required to close this issue.

Related issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/extensionsExtensions (general)ext-agentsazure.ai.agents extensionext-foundryazure.ai.{agents,connections,inspector,projects,routines,skills,toolboxes}, microsoft.foundry

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions