CAMPUX learn / ai / 05
Project 05 of 09
Public network access: disabled.

Ship it like infrastructure

The whole Warranty Desk stack as Bicep, deployed from GitHub Actions with no secret in the repo, into a Foundry environment where nothing has a public endpoint and every model call goes through a gateway that counts tokens.

build time
8 to 10 hours
cost
Under $25 if torn down the same day3
services
Bicep, GitHub Actions, azd, Virtual Network, Private Link, Private DNS, Azure Firewall, API Management, Key Vault
assumes
Project 01, and that you have deployed anything with Bicep before. If not, the CAMPUX bootcamp covers it; this page does not.
exams
Overlaps AI-200, AZ-104, AZ-305
vocabulary
Standard setup, BYO resources, private endpoint, VNet injection, delegated subnet, federated credential, AI gateway

The problem

Projects 01 to 04 were built by hand, by you, in a subscription you own. Campux Retail's platform team will not run that. Their rules are short.

Everything is code and it deploys from a pipeline, not a laptop. Nothing the agent touches has a public endpoint: not the project, not the search index, not the order data. The pipeline holds no secret that could leak. Every model call goes through one gateway so the platform team can cap a team's tokens and see who spent what. And a second environment must be one command away, identical to the first. The platform lead's test is blunt: "if you can reach it from a coffee shop, it is not done."

definition
Standard setup. A Foundry project that brings its own Storage, Azure AI Search and Cosmos DB, so every byte the Agent Service stores lands in resources you own and can put behind private endpoints. The basic setup manages those for you and is the wrong choice here.

The architecture

One virtual network, private endpoints for everything, and a pipeline that holds no secret.

Ship it architecture: GitHub Actions with a federated credential runs Bicep through azd into a virtual network with public access disabled; API Management fronts the Foundry project as an AI gateway; the agent client is injected into a delegated subnet; Azure AI Search, Storage and Cosmos DB sit behind private endpoints with private DNS; Azure Firewall controls egress; Key Vault holds keys. public network access: disabled. If you can reach it from a coffee shop, it is not done. PIPELINE VIRTUAL NETWORK · PUBLIC ACCESS DISABLED GitHub Actionsazd provision + deployfederated credential Bicepstack as code API ManagementAI gateway, no keytoken limit, safety Foundry projectprivate endpointstandard setup, injected Agent clientinjected into your subnet/27, Microsoft.App delegated Azure Cosmos DBprivate endpoint Storageprivate endpoint Azure AI Searchprivate endpointindexer: private execution Private DNS zonesprivatelink records Azure Firewallegress allowlist, logged Key Vaultkeys, never in the pipeline Application Insightstokens per team Microsoft Entra IDGitHub to Azure: federated credential, OIDC · agent to services: managed identities · no secret in the repo, no key in the pipeline 1 2 3 4 5 6 7
livepress play to deploy one environment
Figure 8 The pipeline is outside the network on purpose and holds no secret. Everything the agent touches is inside it, behind a private endpoint, and the template does not create the three on the middle row for you.
  1. Sign in. GitHub Actions authenticates to Azure with a federated credential; there is no client secret to leak.
  2. Provision. azd runs the Bicep from Microsoft's private-network standard-setup template, plus your additions.
  3. Gateway. API Management fronts the model deployment with a per-team token limit, token metrics and content safety.
  4. Inject. The agent client runs in a subnet you own, delegated to Microsoft.App/environments, /27 or larger.
  5. Search privately. Azure AI Search is reached over a private endpoint; the indexer runs in the private execution environment.
  6. Store privately. Agent data lands in your own Storage and Cosmos DB over private endpoints you created.
  7. Egress. Outbound traffic passes an Azure Firewall allowlist: Entra, Application Insights ingestion, nothing else.
Service map, for readers coming from AWS
JobAWS versionThis buildSame idea?
Infrastructure as codeCloudFormation, CDKBicep, driven by azdYes
Pipeline identityGitHub OIDC to an IAM roleGitHub OIDC to an Entra federated credentialYes
Private accessVPC endpointsPrivate endpoints plus private DNS zonesYes
Agent in your networkLambda in a VPCAgent client VNet injection, delegated subnet1Yes
Egress controlNAT plus security groupsAzure Firewall with an FQDN allowlistYes
AI gatewayAPI Gateway plus custom codeAPI Management AI gateway policies2Different. Token limits and metrics are built in

The build

In this order. Decide the network before you create anything; outbound isolation cannot be added to an existing Foundry resource, only redeployed.

  1. Start from Microsoft's template

    Clone the Foundry samples repository and read the Bicep in infrastructure-setup-bicep/15-private-network-standard-agent-setup end to end before running it. Note what it creates and what it does not.

    You can list every resource the template creates from memory, and you noticed it does not create private endpoints for Search, Storage or Cosmos.
  2. The network

    A virtual network with three subnets: one for private endpoints, one delegated to Microsoft.App/environments at /27 or larger for the agent client, and one for a firewall. Private DNS zones for every privatelink domain you will need, linked to the network.

    nslookup for the Foundry endpoint from a VM in the network returns a private IP; from your laptop it returns a public one you cannot use.
  3. Foundry, standard setup, private

    Deploy the Foundry resource and project with public network access Disabled, a private endpoint, VNet injection into the delegated subnet, and your own Storage, AI Search and Cosmos DB as the standard setup. Then create the private endpoints for those three yourself.

    Four private endpoint connections show Approved. The Foundry portal from your laptop says you cannot reach the project. Good.
  4. The agent, in the network

    Deploy the Project 01 agent into this project. Its OpenAPI tool and file search now travel through your subnet and private endpoints; check the tool support table before you rely on any other tool.

    From a VM in the network, the agent answers a warranty question. The Function App's public endpoint is disabled and it still works.
  5. Egress

    Route the agent subnet through Azure Firewall with an allowlist of the FQDNs Foundry needs: Entra sign-in, the Application Insights ingestion endpoints, and nothing else.

    The agent still works. A curl to an unrelated site from the same subnet is blocked and the firewall log shows why.
  6. The AI gateway

    Put API Management in front of the model deployment with managed identity, and add three policies: llm-token-limit per team key, llm-emit-token-metric with a team dimension, and llm-content-safety. Point the agent at the gateway, not the model.

    Set a 200 tokens-per-minute limit for a test key and get a 429 on the third question. Application Insights shows tokens per team.
  7. The pipeline

    GitHub Actions with a federated credential to an Entra app: no client secret anywhere. azd provision then azd deploy on push to main, with a manual approval environment gate for production.

    grep -ri secret .github/ finds nothing. A push deploys; a second environment is one variable change away.
  8. The second environment

    Create staging from the same templates with different parameters. Run the Project 03 evaluation against it.

    Two identical stacks, and the evaluation scores match within noise.
  9. Tear it down
    azd down --purge

    Then check for the things Bicep does not own: the private DNS zone links, the firewall's public IP, and the API Management instance, which can take a while to delete.

    The resource group is empty. Today's cost is under $25, most of it the firewall and gateway hours.

Where it breaks

Cause each one on purpose. Private networking fails silently and blames DNS.

The trade-offs

Standard setup, or basic?
Basic is faster and Microsoft manages the storage. Standard means you own every resource the agent writes to and can put each behind a private endpoint. Regulated data, or a platform team with rules, means standard.
Microsoft's template, or your own Bicep?
Their template encodes decisions that took a team months. Your own is smaller and you understand it. Start from theirs, strip what you do not use, and keep the commit history showing what you removed and why.
A gateway in front of the model, or direct?
Direct is one hop faster. The gateway gives per-team token limits, a metric per team, content safety, load balancing and a place to swap models without touching agents. From the second team onward, the gateway pays for itself.
Firewall, or NAT gateway?
A NAT gateway gives egress without inspection. A firewall gives an allowlist and a log. The allowlist is the compliance answer; the log is how you debug it.
Bicep, or Terraform?
Terraform works for Foundry too and is the right answer in a multi-cloud shop. Bicep is what the Foundry samples are written in, so you inherit the most tested path. Pick the one your platform team already reviews.

In the interview

"How would you deploy this for real?"

  • decisionBicep from Microsoft's private-network standard-setup template, driven by azd from GitHub Actions with a federated credential.
  • reasonNo secret in the pipeline, and a second environment is a parameter change.
  • watchedWhat the template does not create: the private endpoints for Search, Storage and Cosmos.

"How is it network-isolated?"

  • decisionPublic access disabled, private endpoints and DNS zones for every service, the agent injected into a delegated subnet, egress through a firewall allowlist.
  • reasonThe platform rule: nothing reachable from outside the network.
  • watchedThe indexer that silently indexed nothing until its execution environment was private.

"How do you control model spend across teams?"

  • decisionAPI Management as the AI gateway with a token limit and a token metric per team key.
  • reasonOne place to cap, count and swap models.
  • watchedA 429 at the limit, and the per-team chart in Application Insights.

Evidence

The two nslookups
The same hostname resolving private from inside and useless from outside.
The 429
The gateway refusing the third question under a test limit, and the per-team token chart.
The repo
Bicep, the workflow file with no secret in it, and a README that lists what the template does not create.
One sentence for the résumé
"Deployed a Microsoft Foundry agent platform as Bicep from GitHub Actions with federated credentials into a private-endpoint-only network with VNet injection and firewall egress control, fronted by an API Management AI gateway enforcing per-team token limits."

Next

Notes

  1. Checked against Microsoft Learn on 2 September 2026. The standard setup requires bring-your-own Storage, Azure AI Search and Cosmos DB; VNet injection needs a subnet delegated to Microsoft.App/environments at /27 or larger; private endpoints for the three BYO resources are not created by the Foundry deployment; outbound networking cannot be added to an existing resource. The sample templates are 11-private-network-basic-vnet, 15-private-network-standard-agent-setup and 19-private-network-agent-tools in the foundry-samples repository.
  2. API Management's AI gateway policies used here are llm-token-limit, llm-emit-token-metric and llm-content-safety; semantic caching (llm-semantic-cache-store and -lookup) needs a Redis-compatible cache and is left out to keep the bill down. The AI gateway inside the Foundry portal was in preview, and a gateway created from there is public until you isolate it yourself.
  3. "Under $25" is dominated by Azure Firewall and API Management hours; both bill while they exist. Deploy in the morning, tear down before dinner, or this footnote is wrong by a lot.