Azure deep dive
Azure AI Foundry
Create the Azure OpenAI resource in Foundry, deploy a structured-output model, and verify it end to end from the backend.
By the end of this stage you have a deployed language model on Azure, its endpoint and deployment name in backend/.env, and a passing end-to-end test call from the project's own code. No application logic yet, just proof that authentication, the deployment, and structured output all work.
Provisioning comes before application code on purpose. Region, quota, tier, and model availability should fail independently, not in the middle of building a feature.
What Foundry is
Azure AI Foundry is Microsoft's platform for working with models on Azure, including the Azure OpenAI models this project uses. The portal at ai.azure.com is where you browse the model catalog, create deployments, and try models in a playground. Under the hood, a Foundry project is backed by an ordinary Azure resource in your subscription, which is why it shows up in your resource group and your bill like everything else.
One vocabulary point saves a lot of confusion. On Azure you do not call "the GPT API". You create a resource, then create a deployment of a specific model inside it, and your code addresses that deployment by name. Same model, your own endpoint, your own quota.
Create the resource and deployment
In the Foundry portal:
- Create a new project, and when asked for the underlying resource, create one in
rg-invoice-reviewso it shares the project's lifecycle - Open the model catalog and pick a model that supports structured outputs. Dave uses
gpt-5.6-terraas a Global Standard deployment in Sweden Central - Deploy it and keep the deployment name, you will reference it from
.env
Model availability differs per region. If your chosen region does not offer the model, deploy in a region that does. The model deployment does not have to live in the same region as the rest of the resource group; that costs you nothing but a little latency.
Verify the deployment from the CLI, so the state is explicit:
az cognitiveservices account deployment show \
--name <your-foundry-resource-name> \
--resource-group rg-invoice-review \
--deployment-name gpt-5.6-terra \
--query '{state:properties.provisioningState,model:properties.model,sku:sku}' \
--output json
# "state": "Succeeded"Configure the backend
Fill in the Azure OpenAI values in backend/.env:
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/openai/v1/
AZURE_OPENAI_DEPLOYMENT=gpt-5.6-terra
AZURE_OPENAI_API_KEY=your-keyThe endpoint ends in /openai/v1/ because the backend talks to Azure through the OpenAI-compatible Responses API surface.
The key is optional. The backend supports Microsoft Entra ID authentication, so if you leave AZURE_OPENAI_API_KEY unset it authenticates as you, through your az login session. Keys are simpler to demo and to deploy; Entra is what production setups prefer because there is no secret to leak or rotate. The project accepts either, which is itself a pattern worth copying.
Test it end to end
The repo has a check script that exercises the deployment through the project's real provider adapter. It sends a small fictional invoice and asks the model for a GL account suggestion with strict structured output:
cd backend
uv run --locked --no-sync python scripts/check_azure_openai.py
# Model: gpt-5.6-terra
# {
# "account_code": "6420",
# ...
# }Two things are being proven here. Your credentials and endpoint work, and the deployment honors a strict JSON schema, which the whole pipeline depends on later. The response is validated against the fixed Northstar account catalog before it is printed, so a schema violation would fail loudly right now instead of deep inside the app.
What this costs
Azure OpenAI is token metered. The public short-context meters for this deployment are $2.50 per million input tokens and $15.00 per million output tokens. A single check-script call uses a few thousand tokens, well under a cent. The complete project evaluation later comes to roughly $0.44. Costs are covered precisely in the evaluation stage.
Checkpoint
- The Foundry deployment reports
Succeeded backend/.envhas the endpoint, deployment name, and key (or you are relying onaz login)check_azure_openai.pyprints a schema-valid GL suggestion
Next: Document Intelligence
Provision the free-tier extraction endpoint from the CLI and analyze your first invoice.