Design and Implement a GenAIOps Infrastructure · Topic 2 of 4
Private Networking and Infrastructure as Code for Foundry
AI-300 GenAIOps: lock down Foundry with private endpoints, DNS and network rules, and deploy the whole environment with Bicep templates and Azure CLI.
- 4 min
- Private endpoint group ID for the Foundry account is
account. - Private DNS zones must be linked to the virtual network.
publicNetworkAccess: 'Disabled'plus a private endpoint is the strict pattern.
What it is
A Foundry resource has a public endpoint by default. To meet network security requirements you disable public network access, add a private endpoint in your virtual network, and make private DNS resolve the resource name to that private address. Then you capture the whole setup in Bicep so every environment is built the same way with Azure CLI.
How it works
Network controls
| Control | What it does |
|---|---|
| Public network access | Enabled, Disabled, or limited with network rules |
Network rules (networkAcls) | Default action Deny plus allowed IP ranges and virtual network subnets (service endpoints) |
| Private endpoint | A private IP in your subnet for the resource; sub resource (group ID) is account |
| Private DNS zones | Resolve the resource hostnames to the private IP |
| Trusted services bypass | Lets selected Azure services reach the resource even when network rules deny public traffic |
The private DNS zones used with a Foundry resource are privatelink.cognitiveservices.azure.com, privatelink.openai.azure.com and privatelink.services.ai.azure.com. Link each zone to the virtual network so clients resolve the private IP. A common failure is a private endpoint with no DNS link, so the name still resolves to the public address and the call is refused.
Services the Foundry project uses must be locked down too: Azure AI Search and storage (and any other dependency you connect) each get private endpoints, and the Foundry side reaches them over private links with managed identity authentication. Without that, the resource is private but data still flows over public paths. Azure Policy can deny creation of Foundry resources that have public access enabled.
Bicep: private Foundry with a private endpoint
param location string = resourceGroup().location
param foundryName string
param subnetId string
param dnsZoneIds array
resource foundry 'Microsoft.CognitiveServices/accounts@2025-06-01' = {
name: foundryName
location: location
kind: 'AIServices'
sku: { name: 'S0' }
identity: { type: 'SystemAssigned' }
properties: {
allowProjectManagement: true
customSubDomainName: foundryName
disableLocalAuth: true
publicNetworkAccess: 'Disabled'
networkAcls: { defaultAction: 'Deny' }
}
}
resource pe 'Microsoft.Network/privateEndpoints@2023-09-01' = {
name: '${foundryName}-pe'
location: location
properties: {
subnet: { id: subnetId }
privateLinkServiceConnections: [
{
name: 'foundry'
properties: {
privateLinkServiceId: foundry.id
groupIds: [ 'account' ]
}
}
]
}
}
resource dns 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2023-09-01' = {
parent: pe
name: 'default'
properties: {
privateDnsZoneConfigs: [for (id, i) in dnsZoneIds: {
name: 'zone${i}'
properties: { privateDnsZoneId: id }
}]
}
}
The DNS zone group registers the endpoint's records in the zones automatically.
Deploy with Bicep and Azure CLI
az group create --name rg-genai-prod --location eastus
az deployment group what-if --resource-group rg-genai-prod \
--template-file main.bicep --parameters main.prod.bicepparam
az deployment group create --resource-group rg-genai-prod \
--template-file main.bicep --parameters main.prod.bicepparam
A .bicepparam file starts with using './main.bicep' and assigns values, so one template serves dev, test and prod. Split reusable parts (Foundry, network, role assignments) into modules. The Azure CLI also manages pieces directly:
az cognitiveservices account create --name foundry-prod --resource-group rg-genai-prod \
--kind AIServices --sku S0 --location eastus --custom-domain foundry-prod
az cognitiveservices account deployment create --name foundry-prod \
--resource-group rg-genai-prod --deployment-name chat \
--model-name <model> --model-version <version> --model-format OpenAI \
--sku-name GlobalStandard --sku-capacity 50
Run these from a GitHub Actions workflow with OIDC sign in, exactly as for Azure Machine Learning infrastructure. Treat the template as the source of truth: change Bicep through a pull request, never in the portal.
A worked example
A regulated team deploys foundry-prod with public access disabled, a private endpoint in the application subnet, and the three DNS zones linked to the virtual network. Search and storage have private endpoints too. The pipeline runs what-if on pull requests and deploys on merge; drift between the template and the portal is corrected by redeploying.
How the exam asks about this
- "Foundry must not be reachable from the internet." Disable public access and use a private endpoint.
- "The client still resolves the public address." Missing or unlinked private DNS zone.
- "Build identical environments repeatedly." Bicep with parameter files, deployed with
az deployment group create.
What to remember for the exam
- Private endpoint group ID for the Foundry account is
account. - Private DNS zones must be linked to the virtual network.
publicNetworkAccess: 'Disabled'plus a private endpoint is the strict pattern.- Connected services (Search, storage) need private endpoints as well.
what-ifpreviews; deployments are idempotent.
Disabling public access before DNS and routing are ready cuts off your own pipeline and developers.
Common mistakes
Creating the endpoint but not the DNS zones. Traffic then never uses the private IP.
Locking only the Foundry resource. A public Search service or storage account still exposes the data.
Editing in the portal. The next template deployment silently reverts the change.
Check yourself
What is the private endpoint group ID for a Foundry (AIServices) account?
account.Which command previews a Bicep deployment?
az deployment group what-if.Why does a client still reach the public address after adding a private endpoint?
Private DNS is missing or not linked to the virtual network.
Topic 2 of 4 in Design and Implement a GenAIOps Infrastructure
Test yourself on Design and Implement a GenAIOps Infrastructure
The full Microsoft AI-300 question bank has 650 questions, with timed practice exams and an explanation for every answer.
This study guide is independent and is not affiliated with, endorsed by, or sponsored by Microsoft. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.