Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Use the table below to choose the right infrastructure template for your scenari

> **Notes:**
- If you do not provide an existing virtual network, the template will create a new virtual network with the default address spaces and subnets described above. If you use an existing virtual network, make sure it already contains two subnets (Agent and Private Endpoint) before deploying the template.
- The account-level capability host is now provisioned declaratively by `modules-network-secured/add-account-capability-host.bicep` as part of `main.bicep`. The standalone `createCapHost.sh` script is no longer required for first-time deployments; it remains in the folder only to support the cleanup-then-recreate flow described in the [Account Deletion Prerequisites and Cleanup Guidance](#account-deletion-prerequisites-and-cleanup-guidance).
- For network-secured deployments, the account-level capability host (`{accountName}@aml_aiagentservice`) is auto-created by the Cognitive Services resource provider (`Microsoft.CognitiveServices`) when the account is created with `properties.networkInjections[].scenario = 'agent'` (set in `modules-network-secured/ai-account-identity.bicep`). Neither `createCapHost.sh` nor the `add-account-capability-host.bicep` module is invoked for first-time deployments; both remain in the folder only to support the cleanup-then-recreate flow described in the [Account Deletion Prerequisites and Cleanup Guidance](#account-deletion-prerequisites-and-cleanup-guidance).
- You must ensure the subnet is exclusively delegated to __Microsoft.App/environments__ and cannot be used by any other Azure resources.


Expand All @@ -128,7 +128,7 @@ Before deleting an **Account** resource, it is essential to first delete the ass

**2. Retain Account, Remove Capability Host**: If you intend to retain the account but remove the capability host, execute the script `deleteCaphost.sh` located in this folder. After deletion, allow approximately max of 20 minutes for all resources to be fully unlinked from the account. To recreate the capability host for the account, use the script `createCaphost.sh` located in the same folder.

> **Note**: The account-level capability host is created declaratively by `main.bicep` (via `modules-network-secured/add-account-capability-host.bicep`) on first deployment. The `createCapHost.sh` script is intended for this cleanup-then-recreate scenario only; it is not required for an initial deployment.
> **Note**: For network-secured deployments, the account-level capability host is auto-created by the Cognitive Services resource provider on first deployment (triggered by the `networkInjections.scenario = 'agent'` property set in `modules-network-secured/ai-account-identity.bicep`). The `createCapHost.sh` script and the `add-account-capability-host.bicep` module are intended for this cleanup-then-recreate scenario only; neither is required for an initial deployment.


> **Important**: Before deleting the account capability host, ensure that the **project capability host** is deleted.
Expand Down Expand Up @@ -465,7 +465,7 @@ Private endpoints ensure secure, internal-only connectivity. Private endpoints a

```text
modules-network-secured/
├── add-account-capability-host.bicep # Declarative account-level capability host (replaces createCapHost.sh for first-time deployments)
├── add-account-capability-host.bicep # (Not invoked by main.bicep in network-secured deployments — the account-level capability host is auto-created by the Cognitive Services resource provider via networkInjections.scenario='agent'. Retained for the cleanup-then-recreate flow.)
├── add-project-capability-host.bicep # Configuring the project's capability host
├── ai-account-identity.bicep # Microsoft Foundry deployment and configuration (supports BYO existing account)
├── ai-project-identity.bicep # Foundry project deployment and connection configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,6 @@ param existingAiFoundryAccountResourceId string = ''
@description('Optional. When true, skip the model deployment. Recommended when reusing an existing account that already has the required model deployments.')
param skipModelDeployment bool = false

// Re-derive BYO account context at main.bicep level so we can scope the
// account-level capabilityHost module to the right RG/subscription.
var useExistingAccount = !empty(existingAiFoundryAccountResourceId)
var existingAccountIdParts = split(existingAiFoundryAccountResourceId, '/')
var existingAccountSubscriptionId = useExistingAccount ? existingAccountIdParts[2] : subscription().subscriptionId
var existingAccountResourceGroupName = useExistingAccount ? existingAccountIdParts[4] : resourceGroup().name

@description('The AI Search Service full ARM Resource ID. This is an optional field, and if not provided, the resource will be created.')
param aiSearchResourceId string = ''
@description('The AI Storage Account full ARM Resource ID. This is an optional field, and if not provided, the resource will be created.')
Expand Down Expand Up @@ -431,20 +424,36 @@ module aiSearchRoleAssignments 'modules-network-secured/ai-search-role-assignmen
]
}

// Account-level capabilityHost (bootstraps before project caphost).
// The current sample relies on createCapHost.sh being run manually; making it
// declarative keeps the flow idempotent and works for both new and BYO accounts.
module addAccountCapabilityHost 'modules-network-secured/add-account-capability-host.bicep' = {
name: 'account-caphost-${uniqueSuffix}-deployment'
scope: resourceGroup(existingAccountSubscriptionId, existingAccountResourceGroupName)
params: {
accountName: aiAccount.outputs.accountName
agentSubnetResourceId: vnet.outputs.agentSubnetId
}
dependsOn: [
privateEndpointAndDNS
]
}
// Account-level capabilityHost.
//
// PR #261 added this module to bootstrap the account-level capabilityHost so
// the flow becomes fully declarative (no createCapHost.sh) and works for BYO
// Foundry accounts that never had the script run.
//
// HOWEVER, this network-secured Standard Setup template creates the AI Foundry
// account with `properties.networkInjections=[{scenario:'agent', subnetArmId:.., useMicrosoftManagedNetwork:false}]`
// (see modules-network-secured/ai-account-identity.bicep). The Cognitive Services
// resource provider (`Microsoft.CognitiveServices`) reacts to that property by
// auto-creating an account-level capabilityHost named `{accountName}@aml_aiagentservice`
// ~5 seconds after the account PUT. Any subsequent PUT of a second account-level
// capabilityHost with a different name (here `caphostacct`) for the same account
// then fails with HTTP 409:
//
// "There is an existing Capability Host with name: {account}@aml_aiagentservice,
// provisioning state: Succeeded for workspace: ...
// cannot create a new Capability Host with name: caphostacct for the same ClientId."
//
// Account-level capability hosts are 1-per-account, keyed on ClientId, and
// cannot be updated. The auto-created `@aml_aiagentservice` is what the
// project-level capabilityHost (addProjectCapabilityHost) binds to, so we must
// NOT create our own here.
//
// Because this template is network-secured-only (every deploy passes
// networkInjections), the auto-create path is always taken. We therefore do
// NOT call modules-network-secured/add-account-capability-host.bicep here.
// The module file is intentionally kept in the directory because it may still
// be useful for other (non-network-secured) BYO bootstrap scenarios.
// See foundry-samples issues #312 / #254 / #255 / #265.

// This module creates the capability host for the project and account
module addProjectCapabilityHost 'modules-network-secured/add-project-capability-host.bicep' = {
Expand All @@ -458,7 +467,6 @@ module addProjectCapabilityHost 'modules-network-secured/add-project-capability-
projectCapHost: projectCapHost
}
dependsOn: [
addAccountCapabilityHost // account caphost must exist first
aiSearch // Ensure AI Search exists
storage // Ensure Storage exists
cosmosDB
Expand Down