LowCodeStacks™
Sign in

Microsoft Foundry from zero: deploy a model, set quota and call it safely

Set up Microsoft Foundry from nothing: create the resource and a project, deploy a model with the right deployment type and quota, give your team the roles that actually let them build, and make the first call with Entra ID instead of a key.

AI & agentsFix a problem9 min read

Checked against Microsoft Learn · 7 sourcesPosted by the Maker DeskHow we write guides

Microsoft Foundry is where you deploy a model and build agents on Azure today. It's the same platform that was called Azure AI Foundry, and Azure OpenAI before that, under one resource type with projects inside it. The set-up takes about fifteen minutes. What takes longer is getting three things right that the wizard doesn't explain: which deployment type to pick, how quota works, and why someone with the Owner role still can't call the model.

Before you start

  • An Azure subscription, and a role that can create the resource: Foundry Account Owner or Foundry Owner on the subscription or resource group. With the Azure CLI, Contributor or Owner on the resource group is enough.
  • The Owner role if you'll be giving other people access, because only a role that can assign roles can do that.
  • Azure CLI 2.80.0 or later if you prefer the command line; the project commands were added in that version.
  • A region check. Not every model or feature is in every region, and the Responses API and agents are in fewer regions than the models. Check before you create the resource; moving later means creating a new one.

Create the resource and a project

A Foundry resource is the Azure resource (type Microsoft.CognitiveServices/accounts, kind AIServices) that holds your model deployments, quota, networking and access control. A project is a folder inside it that organises one team's work and is where developers build.

In the portal: sign in to ai.azure.com with the New Foundry toggle on, select Create a new project, name it, and under Advanced options choose the resource group and location. The portal creates the resource and the project together, and, if you can assign roles, gives you the Foundry User role on it.

With the Azure CLI, after az login:

bash
az group create --name my-foundry-rg --location eastus

az cognitiveservices account create \
  --name my-foundry-resource \
  --resource-group my-foundry-rg \
  --kind AIServices \
  --sku S0 \
  --location eastus \
  --custom-domain my-foundry-resource \
  --assign-identity \
  --allow-project-management true

az cognitiveservices account project create \
  --name my-foundry-resource \
  --resource-group my-foundry-rg \
  --project-name my-foundry-project \
  --location eastus

Three things in that command matter. --assign-identity creates the managed identity that project management needs; without it, creating the project fails. --allow-project-management true can't be changed after the resource exists. The custom domain must be unique across Azure, so a taken name fails with CustomDomainInUse.

Your project endpoint is https://<resource>.services.ai.azure.com/api/projects/<project>. It's on the project's home page, or from az cognitiveservices account project show under properties.endpoints. Developers need it, plus the deployment name.

Deploy a model

In the portal: Build > Models > Deploy > Deploy a base model, pick the model, and choose Deploy > Default settings or customise the deployment type and capacity. With the CLI, list what's available in your region first, because a model, version or type that isn't there fails with DeploymentModelNotSupported:

bash
az cognitiveservices model list --location eastus \
  --query "[?model.name=='gpt-5-mini'].{version:model.version,skus:join(',',model.skus[].name)}" \
  --output table

az cognitiveservices account deployment create \
  --name my-foundry-resource \
  --resource-group my-foundry-rg \
  --deployment-name gpt-5-mini \
  --model-name gpt-5-mini \
  --model-version "2025-08-07" \
  --model-format OpenAI \
  --sku-capacity 10 \
  --sku-name GlobalStandard

The deployment name is what your code sends as the model. Keep it the same as the model name unless you have a reason not to.

Which deployment type

TypeWhere requests are processedBillingChoose it when
Global StandardAny Azure regionPer tokenYour default: new models arrive here first, it's the cheapest, and it's in the most regions
Data Zone StandardWithin the US, EU or Asia Pacific data zone of your resourcePer tokenYour rules say processing must stay in that zone
StandardWithin your resource's Azure geographyPer tokenProcessing must stay in the geography; arrives last for new models
Provisioned (global, data zone or regional)As above, on reserved capacityReserved throughputSteady high volume, or latency that must not vary
Batch (global or data zone)Asynchronous jobsPer token, about half priceLarge jobs that aren't time-sensitive
DeveloperGlobal, no SLAPer tokenTrying out a fine-tuned model only

Data at rest stays in your resource's geography whichever type you choose; the types differ in where the request is processed. Microsoft's own advice is to start with Global Standard and move only for data residency, reserved throughput or batch work.

Set the quota

Quota is a per-subscription allowance of tokens per minute (TPM) for each model, region and deployment type. Each deployment takes a slice of it, and that slice is the deployment's rate limit. A requests-per-minute limit comes with it in a fixed ratio that varies by model: for older chat models, one unit of capacity is 1,000 TPM and 6 RPM.

  • Manage it under Manage > Quota in the portal, where you can move TPM between deployments and request more. Changes take up to 15 minutes to apply.
  • To see quota at all, a person needs the Cognitive Services Usages Reader role at the subscription scope. A role on the resource group or the resource doesn't do it.
  • Quota increases go through Microsoft's request form, in order, and priority goes to subscriptions that use what they already have.
  • Deleting a resource through the API without deleting its deployments first leaves the quota unavailable for 48 hours unless you purge the resource.

Put the TPM where the traffic is. A common surprise is approved quota at the subscription level while the deployment that actually gets the calls has a small allocation. Our guide to Azure OpenAI 429 errors covers what happens then.

Give your team the right roles

Foundry separates managing the resource from building in it, and the familiar Azure roles only do the first.

RoleGivesGive it to
Foundry UserBuild and test in a project, call models and agents, read the resourceDevelopers, on the project
Foundry Agent ConsumerCall agent endpoints onlyApps and service principals that only use agents
Foundry Project ManagerBuild, manage projects, publish agents, and give others Foundry UserTeam leads, on the resource
Foundry Account OwnerCreate projects and resources, deploy models, assign roles; not buildManagers and platform admins
Foundry OwnerAll of the aboveA small team that does everything
Owner or Contributor (Azure)Create resources and deployments; no data actionsNobody as their only role

So a subscription Owner who tries to create an agent gets "no permission", because Owner and Contributor grant management operations only. Give them Foundry User too. The project's managed identity needs Foundry User on the resource as well; the portal does this for you when the creator can assign roles.

The roles were recently renamed from Azure AI User, Azure AI Owner, Azure AI Account Owner and Azure AI Project Manager, and both names still appear. In scripts, use the role IDs instead: Foundry User is 53ca6127-db72-4b80-b1b0-d745d6d5456d. Don't use the roles that start with "Cognitive Services" for Foundry work, except Usages Reader for quota, and not Azure AI Developer either, which is for hubs and machine learning workspaces.

bash
PROJECT_ID=$(az cognitiveservices account project show \
  --name my-foundry-resource --resource-group my-foundry-rg \
  --project-name my-foundry-project --query id -o tsv)

az role assignment create \
  --role "53ca6127-db72-4b80-b1b0-d745d6d5456d" \
  --assignee "someone@contoso.com" \
  --assignee-principal-type User \
  --scope "$PROJECT_ID"

In the portal the same lives under Manage > Project details > Users. Adding a Microsoft Entra security group instead of people saves doing this again later.

Make the first call

Use Microsoft Entra ID rather than an API key. Roles apply only to Entra sign-ins; a key grants full access to the resource with no role check, so it's one secret away from everything. The SDK handles sign-in through DefaultAzureCredential, which uses az login on your machine and a managed identity in Azure.

bash
pip install "azure-ai-projects>=2.3.0" azure-identity
az login
python
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient

project = AIProjectClient(
    endpoint="https://<resource>.services.ai.azure.com/api/projects/<project>",
    credential=DefaultAzureCredential(),
)
openai = project.get_openai_client()

response = openai.responses.create(
    model="gpt-5-mini",  # your deployment name
    input="What is the size of France in square miles?",
)
print(response.output_text)

This uses the Responses API, which is the current API for models and agents; the openai package talks to Foundry through the project endpoint, and api-version parameters are gone in favour of stable v1 routes. If you call REST directly, the token scope is https://ai.azure.com/.default.

To turn keys off for good, set disableLocalAuth: true on the resource in Bicep or the portal once every caller uses Entra ID.

Things that catch people out

What you seeWhyFix
401 with a valid accountWrong token scope, or no data-plane roleUse the https://ai.azure.com/.default scope; give the caller Foundry User
404Wrong endpoint, deployment name or API versionCompare the deployment name in Build > Models with your model value
Owner can't create an agentOwner is management onlyAdd Foundry User
Quota page is emptyNo subscription-scope Usages ReaderAssign Cognitive Services Usages Reader on the subscription
Agents or Responses API missing from the portalThe resource's region doesn't support themCreate a resource in a supported region
SDK samples fail with odd errorsazure-ai-projects 1.x with the new portal, or 2.x with the classic oneMatch the SDK major version to the portal you use

Sources

Did this fix it?

Comments

No comments yet. Share what worked for you.

Sign in to comment. Comments show under a display name you choose, never your email.