Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Baseline Developer Enablement Package — Agentic AI

Scope: Four Entra ID groups provide role-based access across two projects within one Foundry Resource. An Account Owner group administers the Foundry Resource, two Dev groups each own a project, and a Subscription Admin group has full resource provisioning rights. All resource connections use managed identity — no keys or secrets in Bicep parameters.

What Gets Deployed

Resource Purpose
AI Foundry Resource CognitiveServices account (2025-09-01) with allowProjectManagement — the central workspace
AI Foundry Project 1 First team-scoped project under the Foundry Resource for agent development
AI Foundry Project 2 Second team-scoped project under the Foundry Resource for agent development
Model Deployments 15 models across Standard, DataZoneStandard, and GlobalStandard SKUs (see Model Deployments section)
Azure AI Search Grounding and vector search for agent knowledge
Azure Blob Storage Grounding corpus, agent artifacts, file storage
Azure Cosmos DB Serverless — agent memory and session state
Azure Key Vault RBAC-enabled, soft-delete + purge protection for secrets
Grounding with Bing Search Web grounding for agents via Bing Search API (G1 SKU)
Log Analytics Workspace Shared observability workspace
Application Insights Telemetry linked to Log Analytics
Diagnostic Settings Enabled for all services → Log Analytics
Budget Alert 80% and 100% spend alerts to owner email
Foundry Connections AI Search, Storage, Cosmos DB, Key Vault, App Insights, Bing Search — all AAD/MI auth (except Bing: ApiKey)
Capability Hosts Agent infrastructure wiring per project (threads, storage, vector store)
RBAC Assignments Account Owner group, 2× Project Dev groups, Subscription Admin group, and Managed Identity roles

Architecture

Resource Group
├── AI Foundry Resource (SystemAssigned MI)
│   ├── Project 1 (SystemAssigned MI)
│   │   └── Capability Host (Agents)
│   ├── Project 2 (SystemAssigned MI)
│   │   └── Capability Host (Agents)
│   ├── Connections
│   │   ├── AI Search (AAD)
│   │   ├── Blob Storage (AAD)
│   │   ├── Cosmos DB (AAD)
│   │   ├── Key Vault (AccountManagedIdentity)
│   │   ├── Bing Search (ApiKey)
│   │   └── App Insights (ApiKey)
│   └── Model Deployments (15 models — see below)
├── Azure AI Search
├── Azure Storage Account
├── Azure Cosmos DB (serverless)
├── Azure Key Vault
├── Grounding with Bing Search
├── Log Analytics Workspace
├── Application Insights
└── Budget Alert

Entra ID Groups
├── Account Owners    → Azure AI Administrator on Foundry Resource + admin on connected services
├── Project 1 Devs    → Azure AI Developer scoped to Project 1 + contributor on Cosmos DB + reader on other services
├── Project 2 Devs    → Azure AI Developer scoped to Project 2 + contributor on Cosmos DB + reader on other services
└── Subscription Admins → Contributor at subscription scope

Naming Convention

Shared infrastructure resources are prefixed with the businessUnit parameter, while Foundry projects use their own projectName/project2Name:

Resource Naming pattern Example
Foundry Resource {businessUnit}{suffix} og-01-eastus2abcd
Project 1 {projectName}-proj-{suffix} aiteam01-proj-abcd
Project 2 {project2Name}-proj-{suffix} aiteam02-proj-abcd
AI Search {businessUnit}-search-{suffix} og-01-eastus2-search-abcd
Storage Account {businessUnit}st{suffix} og01eastus2stabcd
Cosmos DB {businessUnit}-cosmos-{suffix} og-01-eastus2-cosmos-abcd
Key Vault {businessUnit}-kv-{suffix} og-01-eastus2-kv-abcd
Bing Search {businessUnit}-bing-{suffix} og-01-eastus2-bing-abcd

The {suffix} is a stable 4-character hash derived from uniqueString(resourceGroup().id). It is deterministic — the same resource group always produces the same suffix — enabling idempotent re-deploys that update resources in place rather than creating duplicates.

Prerequisites

  1. Azure subscription with Owner or User Access Administrator access (needed for subscription-level RBAC)
  2. Four Entra ID groups created — note each Object ID:
    • Account Owners group
    • Project 1 Dev group
    • Project 2 Dev group
    • Subscription Admins group
  3. Azure CLI v2.60+ with Bicep extension
  4. Microsoft.Bing provider registered on the subscription:
    az provider register --namespace Microsoft.Bing

Deployment

1. Edit parameters

Open main.bicepparam and replace all placeholder values:

param location = 'eastus2'
param projectName = 'aiteam01'
param project2Name = 'aiteam02'

param accountOwnerGroupObjectId = '<account-owner-group-object-id>'
param project1DevGroupObjectId = '<project1-dev-group-object-id>'
param project2DevGroupObjectId = '<project2-dev-group-object-id>'
param subscriptionAdminGroupObjectId = '<subscription-admin-group-object-id>'

param businessUnit = 'og-01-eastus2'
param costCenter = 'og-01-eastus2-cs-001'
param ownerEmail = 'owner@company.com'
param monthlyBudget = 500

// Model deployments are defined as an array — see main.bicepparam for the full list
param modelDeployments = [ ... ]

2. Create the resource group

az group create \
  --name rg-og-01-eastus2 \
  --location eastus2

3. Deploy

az deployment group create \
  --resource-group rg-og-01-eastus2 \
  --template-file main.bicep \
  --parameters main.bicepparam

Re-deploying

The template is idempotent — re-running the same command against the same resource group will update existing resources in place (no duplicates). This is safe for changing model TPM limits, adding connections, updating RBAC, etc.

To deploy a separate environment, create a new resource group:

az group create --name rg-og-02-eastus2 --location eastus2
az deployment group create \
  --resource-group rg-og-02-eastus2 \
  --template-file main.bicep \
  --parameters main.bicepparam

Each resource group generates a unique suffix, so globally-scoped resources (Storage, Cosmos DB, Key Vault, AI Search, Foundry) won't collide.

RBAC Summary

Account Owner Group (Entra ID Group)

Resource Role
Foundry Resource Azure AI Administrator
AI Search Search Service Contributor
Blob Storage Storage Blob Data Contributor
Cosmos DB Cosmos DB Operator
Key Vault Key Vault Secrets Officer

Project Dev Groups (Entra ID Groups — one per project)

Resource Role
Assigned Foundry Project Azure AI Developer
AI Search Search Index Data Reader
Blob Storage Storage Blob Data Reader
Cosmos DB Cosmos DB Built-in Data Contributor
Key Vault Key Vault Secrets User

Dev groups are scoped to their specific project only — teams are isolated from each other at the Foundry level. Cosmos DB write access enables agent memory and session state operations.

Subscription Admin Group (Entra ID Group)

Resource Role
Entire subscription Contributor

Members can provision any resource in the subscription. Does not include RBAC management (Owner role would be needed for that).

Managed Identities

Identity Roles
Foundry MI Search Index Data Contributor, Search Service Contributor, Storage Blob Data Contributor, Cosmos DB Operator + Data Contributor, Key Vault Secrets User
Project 1 MI Storage Blob Data Contributor, Search Index Data Contributor, Search Service Contributor, Cosmos DB Operator + Data Contributor
Project 2 MI Storage Blob Data Contributor, Search Index Data Contributor, Search Service Contributor, Cosmos DB Operator + Data Contributor

Cost Containment

Guardrail Mechanism Details
LLM rate limit TPM cap per model deployment Each model set to 25% of subscription quota max
Budget alert Azure Budget at 80% and 100% Configurable via monthlyBudget (default $500/mo), emails ownerEmail
AI Search scale lock Devs lack Search Service Contributor Cannot add partitions/replicas — locked to Standard 1×1
Cosmos DB storage cap Serverless 1 TB limit Inherent platform limit — no additional config needed
Bing Search G1 pay-per-call 1,000 free transactions/month; usage driven by agent calls
Storage Devs have read-only access Cannot upload data directly; writes flow through Foundry MI

The budget is notification-only — it alerts the owner but does not stop spending. For automated enforcement, add an Action Group with an Azure Function or Logic App.

Model Deployments

15 models deployed across three SKU types, each set to 25% of subscription quota max. Models are deployed sequentially via @batchSize(1).

Standard (eastus2 region)

Deployment Name Model Version Capacity (K TPM)
gpt-4-1 gpt-4.1 2025-04-14 250
o4-mini o4-mini 2025-04-16 250
text-embedding-3-large text-embedding-3-large 1 87

DataZoneStandard (US Data Zone)

Deployment Name Model Version Capacity
gpt-5-4-dz gpt-5.4 2026-03-05 75K TPM
gpt-5-mini-dz gpt-5-mini 2025-08-07 75K TPM
gpt-5-nano-dz gpt-5-nano 2025-08-07 500K TPM
model-router-dz model-router 2025-11-18 75K TPM
o3-dz o3 2025-04-16 75K TPM
gpt-image-1-5-dz gpt-image-1.5 2025-12-16 1 (concurrent requests)
text-embedding-3-small-dz text-embedding-3-small 1 250K TPM
text-embedding-3-large-dz text-embedding-3-large 1 250K TPM

GlobalStandard

Deployment Name Model Version Capacity (K TPM)
gpt-5-3-chat-gs gpt-5.3-chat 2026-03-03 250
gpt-5-3-codex-gs gpt-5.3-codex 2026-02-24 250
gpt-5-1-codex-mini-gs gpt-5.1-codex-mini 2025-11-13 250

Note: Some models require registration before deployment: gpt-5.4 & gpt-5.3-codex, gpt-image-1.5.

Deployment Steps (12 steps)

Step Module Description Dependencies
1 ai-search, storage-account, cosmos-db, key-vault Foundation services (parallel) None
2 ai-foundry Foundry Resource + 2 Projects + 15 Model deployments Step 1
3 observability Log Analytics, App Insights, Diagnostic Settings Steps 1–2
4 rbac-managed-identity Foundry Resource & Project MI role assignments Step 2
5 rbac-account-owner-group Account Owner Entra ID group Step 2
6 rbac-project-dev-group (×1) Project 1 Dev group Step 2
7 rbac-project-dev-group (×2) Project 2 Dev group Step 2
8 rbac-subscription-admin Subscription-scoped Contributor None
9 foundry-connections Register 5 connections on Foundry Resource Steps 3–4
10 capability-host (×2) Agent infrastructure per project Steps 4, 9
11 bing-grounding Bing Search resource + Foundry connection Step 4
12 budget Monthly budget alert None

Module Structure

baseline-dev-enablement/
├── main.bicep                           # Orchestrator
├── main.bicepparam                      # Parameters file
├── README.md                            # This file
├── architecture-diagram.md              # Mermaid architecture diagram
└── modules/
    ├── ai-foundry.bicep                 # Foundry Resource + 2 Projects + Model
    ├── ai-search.bicep                  # AI Search service
    ├── storage-account.bicep            # Blob Storage
    ├── cosmos-db.bicep                  # Cosmos DB (serverless)
    ├── key-vault.bicep                  # Key Vault
    ├── bing-grounding.bicep             # Grounding with Bing Search + Foundry connection
    ├── observability.bicep              # Log Analytics + App Insights + Diagnostics
    ├── budget.bicep                     # Budget alert
    ├── foundry-connections.bicep        # All Foundry connections (AAD/MI auth)
    ├── capability-host.bicep            # Agent capability host (reusable per project)
    ├── rbac-account-owner-group.bicep   # Account Owner group role assignments
    ├── rbac-project-dev-group.bicep     # Project Dev group role assignments (reusable)
    ├── rbac-subscription-admin.bicep    # Subscription Admin group (subscription scope)
    ├── rbac-managed-identity.bicep      # Foundry Resource + Project 1 + Project 2 MI role assignments
    ├── rbac-foundry-owner.bicep         # (available) Single-user owner role assignments
    └── rbac-team-group.bicep            # (available) Single team group role assignments

Key Design Decisions

  • Entra ID (AAD) auth only — local auth / API keys disabled on every service that supports it (see section below).
  • Group-based RBAC — four Entra ID groups replace individual user/group assignments for scalable access management.
  • Project isolation — each dev group is scoped to its own project; teams cannot see each other's Foundry artifacts.
  • Serverless Cosmos DB — cost-efficient for POC/dev scale; no provisioned throughput to manage. Devs have data-plane contributor access for agent memory operations.
  • System-assigned managed identities — Foundry Resource and both projects get their own MI for least-privilege access.
  • BusinessUnit-based naming — shared infrastructure resources (AI Search, Storage, Cosmos DB, Key Vault, Bing) are prefixed with businessUnit; only Foundry projects use their project-specific names.
  • Idempotent deploys — stable uniqueSuffix derived from resource group ID enables re-deploys that update in place without creating duplicates.
  • Grounding with Bing Search — web grounding available to agents via G1 SKU with ApiKey-based Foundry connection.
  • Tags cascade — applied at the resource group level using Microsoft.Resources/tags.
  • API version 2025-09-01 — latest stable GA for all CognitiveServices resource types.

Authentication — Entra ID Only

This deployment enforces Entra ID (AAD) authentication across every service, with local auth and shared keys disabled. This is the enterprise-recommended security pattern for the following reasons:

Why Entra ID Only?

  1. Eliminates shared secrets — API keys and shared access keys are static credentials that can be copied, leaked in source control, or exfiltrated. Disabling them removes this entire attack surface.
  2. Centralized identity governance — all access flows through Entra ID, enabling Conditional Access policies, Multi-Factor Authentication (MFA), and Privileged Identity Management (PIM) to apply uniformly.
  3. Full audit trail — every data-plane and control-plane operation is tied to a named identity in Entra ID sign-in and audit logs, satisfying SOC 2, ISO 27001, and FedRAMP logging requirements.
  4. Automated credential lifecycle — managed identities and Entra ID tokens are rotated automatically by the platform. No manual key rotation schedules or secrets to manage.
  5. Least-privilege by default — RBAC role assignments grant only the specific permissions needed, scoped to the exact resource. Keys typically grant full access with no scoping.
  6. Compliance alignment — Microsoft's own Well-Architected Framework, Azure Security Benchmark, and CIS Azure Foundations Benchmark all recommend disabling local auth in favor of Entra ID.

Per-Service Auth Configuration

Resource Setting Effect
AI Foundry disableLocalAuth: true API keys disabled; Entra ID required
AI Search disableLocalAuth: true Admin/query keys disabled; Entra ID required
Cosmos DB disableLocalAuth: true Primary/secondary keys disabled; Entra ID required
Storage Account allowSharedKeyAccess: false Shared key and SAS disabled; Entra ID required
Key Vault enableRbacAuthorization: true Access policies disabled; RBAC-only via Entra ID
App Insights Connection authType: 'ApiKey' Exception — connection string passed as credential*

* The Application Insights Foundry connection category only supports ApiKey auth type. This is the sole exception — no AAD auth option exists for this connection type. The connection string is not a data-plane secret; it controls where telemetry is sent, not who can read it. Read access to telemetry data is still governed by RBAC on the Application Insights resource.

Model Deployment Configuration

The model deployment is configurable via parameters. Defaults are suitable for most dev/POC teams.

Parameter Default Description
modelName gpt-4.1 Model to deploy
modelFormat OpenAI Provider format
modelVersion 2025-04-14 Model version
modelDeploymentType GlobalStandard Deployment SKU type
modelTpmLimit 40 TPM limit in thousands (40 = 40K TPM)

Deployment Types

Type Description
Standard Single-region deployment with dedicated capacity
GlobalStandard Multi-region load-balanced deployment (default — best availability)
DataZoneStandard Data-zone-scoped deployment for data residency requirements

To customize, update the values in main.bicepparam:

param modelName = 'gpt-4.1'
param modelDeploymentType = 'GlobalStandard'   // Standard | GlobalStandard | DataZoneStandard
param modelTpmLimit = 40                        // TPM in thousands (e.g., 40 = 40K TPM)

Post-Deployment Verification

An Account Owner should:

  1. Open the Azure AI Foundry portal
  2. Verify both projects are visible under the Foundry Resource
  3. Verify each connection is visible under Connected Resources
  4. Test model access with a sample prompt in the Playground
  5. Confirm Project 1 Dev group members can access Project 1 (but not Project 2)
  6. Confirm Project 2 Dev group members can access Project 2 (but not Project 1)
  7. Confirm Subscription Admin group members can provision resources in the subscription

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages