Technical Writings · Microsoft Foundry · Environment setup

Setting Up Microsoft Foundry for AI Agent Development with Python and VS Code

From an empty project to a configured Python agent: a practical Windows walkthrough using an application identity, local environment variables and a named model deployment.

By Victor Pereira · November 3, 2026 · Windows / Python / VS Code / Agentic Engineering / Microsoft / Azure / Foundry / Entra ID

The goal is a private learning environment for AI Agents for Beginners and future agent engineering articles. Our first test adapts Microsoft’s Your First Agent tutorial. We keep configuration in .env and authenticate with a dedicated service principal. Budget and quota settings support this setup; the main milestone is running hello_agent.py.

Our practice environment in Microsoft Cloud

This practice brings together three parts of Microsoft Cloud: Azure (subscription, resource group, Access control/IAM, Cost Management budgets), Microsoft Foundry (project, model catalog, quota, model deployment and model playground), and Microsoft Entra ID (app registration, service principal, client secret and security group). VS Code provides our local Python editor and terminal.

Microsoft Cloud application launcher showing Microsoft Foundry, Azure, Entra and Visual Studio Code among other services
The Microsoft Cloud launcher provides context for the services used in this walkthrough. Other products shown are outside this practice.

The Foundry model playground lets us send a short test prompt after deploying yantras-luna-model, before calling it from Python. It helps check that the deployment responds; the Python test separately verifies our service principal and local configuration. Playground requests can incur model usage charges.

1. Prepare a Python workspace

This walkthrough uses Windows and VS Code. Install Python, Git, VS Code and its Microsoft Python extension. Use a Python version supported by the current Agent Framework packages. You also need an Azure subscription and permission to register applications, deploy models and assign roles, or help from an administrator.

PowerShell
python --version
git --version
mkdir yantras
cd yantras
code .

In the VS Code terminal, create an isolated environment. Select Python: Select Interpreter from the Command Palette and choose the interpreter inside .venv.

PowerShell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install python-dotenv agent-framework azure-identity

If PowerShell blocks activation, use the environment’s interpreter directly: .\.venv\Scripts\python.exe -m pip install python-dotenv agent-framework azure-identity. Use that interpreter to run scripts too.

The first-agent tutorial uses the narrower agent-framework-foundry package. We install the broader agent-framework metapackage for our learning workspace. The tutorial explains that both provide the core framework; the Foundry integration is needed for this client. Installation reference.

2. Create a Microsoft Foundry project

Open Microsoft Foundry, select Create project, and follow the wizard. Confirm the subscription, resource group, region, Foundry resource and project name before creating them. Portal labels can change; retain these relationships when following the screens.

On the project home page, locate the Project endpoint. Keep it locally for the configuration step. It has a project-specific path, unlike the separate Azure OpenAI endpoint.

Microsoft Foundry · Project home
Build an agent

Instructions, tools and knowledge

Use a model

View deployments

Project endpoint https://*****.services.ai.azure.com/api/projects/*****
API key *****
Diagram based on the project dashboard; private values are replaced with asterisks. This is not a portal screenshot.

3. Give the application its own identity

Azure Identity supports local developer sign-in and application identities. For this exercise, we chose a service principal: it separates application permissions from a personal account and allows authentication without Azure CLI. Microsoft recommends Microsoft Entra token authentication for Azure services. Authentication overview.

  1. In Azure portal, open Microsoft Entra ID → App registrations → New registration.
  2. Name the application yantras-app-v1. Select the single-tenant option for this tenant-specific exercise; an interactive redirect URI is not needed for this client-secret flow.
  3. Select Register. Copy the Application (client) ID and Directory (tenant) ID to your local configuration.
  4. Open Certificates & secrets → Client secrets → New client secret. Choose an expiration consistent with your organization’s policy.
  5. Copy the secret’s Value immediately. The secret ID is not the credential value.
Azure application registration with the name yantras-app-v1 and single-tenant account type
Application registration for the private learning workspace. The application display name is intentionally retained.

A secret expires and must be protected and rotated. Keep it outside source control. When hosting on Azure later, prefer managed identity where supported. Microsoft’s local service principal guide describes registration and configuration.

4. Create a group and grant access

Authentication identifies the app; authorization determines what it can do. Our first service-principal request returned 403 because creating an identity alone did not grant Foundry access.

  1. In Microsoft Entra ID, open Groups → New group.
  2. Choose Security, name it yantras-group, and use Assigned membership.
  3. Add the enterprise application/service principal yantras-app-v1 as a member, then create the group.
  4. Open the Foundry resource in Azure portal, then Access control (IAM) → Add role assignment.
  5. Select Foundry User, which may still appear as Azure AI User. Under User, group, or service principal, select yantras-group and complete Review + assign.
yantras-app-v1
Application identity
yantras-group
Security group
Foundry User
Resource access
Permission path. Object IDs and tenant details are intentionally omitted.

Our session assigned the role at resource group scope, which is inherited by its Foundry resource. For a focused setup, prefer the narrower Foundry resource scope when sufficient. Allow propagation time and restart Python before retrying. Role assignment requires an account authorized to grant Azure roles. Foundry role and scope reference.

5. Set a budget and request model capacity

Before testing, decide how much you are willing to spend. Our deployment is private, but repeated requests and future agent loops can still incur charges.

Create monthly email alerts

  1. In Azure portal, open the tutorial’s resource group, then Cost Management → Budgets → Add. Use subscription scope instead to monitor its entire spend.
  2. Confirm the scope, name the budget yantras-learning-monthly, select Monthly, and choose start and expiration dates.
  3. Enter an amount you can afford. For illustration, use 20 in the displayed currency; this is not a cost estimate.
  4. Select Next and create three Actual cost conditions: 50%, 80%, 100%.
  5. Add your email recipient and language; optionally add a 100% forecasted-cost alert.
  6. Select Create and verify the saved scope, dates and recipients.

Request quota for GPT-6 Luna

For this walkthrough, we selected gpt-6-luna / Global Standard. Check its availability and quota for your subscription before deploying.

  1. In Foundry, select Manage → Quota → Token per minute.
  2. Check the subscription, region, model and deployment type. Existing unused capacity may avoid the need for an increase.
  3. If capacity is zero or insufficient, select Request quota. Choose gpt-6-luna and Global Standard.
  4. For field 15, which asks for total quota in kTPM, our initial target is 30: 30,000 tokens per minute total. This is our learning-workload choice, not a universal requirement.
  5. Describe the workload: private personal training, technical writing, one developer, and future multi-agent experiments. Submit and await review; approval and timing are not guaranteed.
Quota request form for gpt-6-luna explaining that total chat model quota is entered in kTPM
Field 15 requests existing plus additional capacity, expressed in thousands of tokens per minute.

Quota limits throughput, not monthly spending. RPM follows model-specific capacity ratios. Approval does not create a deployment. Microsoft quota reference. Once approved, allocate only the capacity needed for current tests and bound retries, tool calls and agent loops.

6. Deploy the model

  1. Return to Build → Models → Deployments and select Deploy a base model.
  2. Select gpt-6-luna and the approved Global Standard option. Verify the intended Foundry resource, regional availability, quota and displayed pricing.
  3. Enter yantras-luna-model as the deployment name and complete deployment.
  4. Wait for provisioning to succeed, then test a short prompt in the playground.
Three different names in this walkthrough
PurposeValue
Application identityyantras-app-v1
Base modelgpt-6-luna
Deployment used by Pythonyantras-luna-model

Use the deployment name, not an arbitrary model catalog label, in the Python client. This missing deployment caused our next error: 404 — API deployment does not exist.

7. Configure .env and verify it

Create .env beside hello_agent.py. Replace every ***** locally; asterisks are publication masks, not working credentials. The endpoint is the project endpoint copied from Foundry.

.env · masked example
AZURE_TENANT_ID=*****
AZURE_CLIENT_ID=*****
AZURE_CLIENT_SECRET=*****
AZURE_PROJECT_ENDPOINT=*****
AZURE_MODEL_DEPLOYMENT_NAME=yantras-luna-model

python-dotenv loads these values into the Python process. It does not create Azure credentials or resources. Our variable names are passed explicitly to the client; they need not match every SDK’s automatic configuration names.

.gitignore
.env
.venv/
__pycache__/

To check configuration without printing values, save and run this as get-env.py:

Python · get-env.py
import os
from pathlib import Path
from dotenv import load_dotenv

load_dotenv(Path(__file__).resolve().with_name(".env"))
names = (
    "AZURE_TENANT_ID", "AZURE_CLIENT_ID", "AZURE_CLIENT_SECRET",
    "AZURE_PROJECT_ENDPOINT", "AZURE_MODEL_DEPLOYMENT_NAME",
)
for name in names:
    value = os.getenv(name, "").strip()
    ready = bool(value) and value != "*****"
    print(f"{name}: {'configured' if ready else 'missing or masked'}")

This confirms presence only, not valid credentials, access, endpoint or deployment. Existing process environment variables take precedence over .env by default; stale shell settings can therefore affect the test.

8. Run hello_agent.py

The following adapts Microsoft’s first-agent tutorial: it loads local configuration and replaces Azure CLI authentication with an explicit service principal. It removes unused API-key variables and checks required settings without printing secrets.

Python · hello_agent.py
import asyncio
import os
from pathlib import Path

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from azure.identity import ClientSecretCredential
from dotenv import load_dotenv


def required(name: str) -> str:
    value = os.getenv(name, "").strip()
    if not value or value == "*****":
        raise ValueError(f"Set {name} in .env or the process environment")
    return value


async def main() -> None:
    load_dotenv(Path(__file__).resolve().with_name(".env"))
    with ClientSecretCredential(
        tenant_id=required("AZURE_TENANT_ID"),
        client_id=required("AZURE_CLIENT_ID"),
        client_secret=required("AZURE_CLIENT_SECRET"),
    ) as credential:
        async with FoundryChatClient(
            project_endpoint=required("AZURE_PROJECT_ENDPOINT"),
            model=required("AZURE_MODEL_DEPLOYMENT_NAME"),
            credential=credential,
        ) as client:
            agent = Agent(
                client=client,
                instructions="You are a friendly assistant. Keep your answers brief.",
            )
            response = await agent.run(
                "What is the largest city in the United States by population?"
            )
            print(response)


if __name__ == "__main__":
    asyncio.run(main())
PowerShell
python get-env.py
python hello_agent.py

The client sends one short prompt using the deployed model. This local Agent definition does not create a named, server-managed agent in the portal. Keep the endpoint tied to the resource containing your deployment.

Expected response — illustrative, not captured output

“New York City is the largest city in the United States by population.”

Validation status: the real successful run remains pending quota approval and deployment. After testing, replace this illustrative response with the observed result and record the package versions using python -m pip show agent-framework agent-framework-foundry azure-identity python-dotenv.

9. Understand the errors we encountered

MessageWhat to check
Azure CLI not found on pathThe original sample used AzureCliCredential. Our service-principal version does not need Azure CLI sign-in.
403 PermissionDeniedConfirm role assignment to the app or its group at the correct resource scope, membership and propagation. Network restrictions can also deny access.
404 deployment does not existConfirm a deployed model exists at the configured resource and the exact deployment name matches. A project alone is insufficient.
429 Too Many RequestsReduce concurrency and request size, respect retry guidance, and check the deployment’s assigned quota.

Do not expose client secrets, tokens or private endpoints in terminal screenshots or error reports. Microsoft provides HTTP error troubleshooting guidance.

10. Prepare for the next lessons

Once the smoke test passes, keep this workspace as a foundation for routing, tool use and orchestration experiments. Clone AI Agents for Beginners into a separate course folder using its sparse-checkout instructions:

Terminal · course repository
git clone --filter=blob:none --sparse https://github.com/microsoft/ai-agents-for-beginners.git
cd ai-agents-for-beginners
git sparse-checkout set --no-cone "/*" "!translations" "!translated_images"

This excludes the large translation directories. Follow each lesson’s current setup for additional dependencies, environment names and permissions. A working first-agent example is a starting point; it does not provision every service required by later lessons.

Companion repository

See microsoft-agentic-engineering on GitHub for the companion learning repository. Configuration values shown in this article are illustrative. For security reasons, real credentials, private endpoints and identifiers are not included; sensitive values are represented by *****. Replace them only in your local environment.

References and credits

This article documents Victor Pereira’s learning setup and adapts Microsoft’s examples with attribution. Screenshots reflect the portal seen during the session. Pending steps and sample output are labeled explicitly.