Skip to content
Docs Try Aspire
Docs Try

Set up Azure AI Foundry in the AppHost

Azure AI Foundry logo

This article is the reference for the Aspire Azure AI Foundry hosting integration. It enumerates the AppHost APIs — with examples for both AppHost.cs and apphost.ts — that you use to model a Foundry account, model deployments, Foundry projects, hosted agents, and prompt agents in your AppHost project.

If you’re new to the Azure AI Foundry integration, start with the Get started with Azure AI Foundry integrations guide. For how consuming apps read the connection information this page exposes, see Connect to Azure AI Foundry.

To start building an Aspire app that uses Azure AI Foundry, install the 📦 Aspire.Hosting.Foundry NuGet package:

Terminal
aspire add azure-ai-foundry

Learn more about aspire add in the command reference.

Or, choose a manual installation approach:

C# — AppHost.cs
#:package Aspire.Hosting.Foundry@*
XML — AppHost.csproj
<PackageReference Include="Aspire.Hosting.Foundry" Version="*" />

For an introduction to working with the Azure AI Foundry hosting integration, see Get started with Azure AI Foundry integrations.

To add an Azure AI Foundry resource to your AppHost project, call the AddFoundry method providing a name:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var foundry = builder.AddFoundry("foundry");
builder.AddProject<Projects.ExampleProject>()
.WithReference(foundry);
// After adding all resources, run the app...

The preceding code adds an Azure AI Foundry resource named foundry to the AppHost project. The WithReference method passes the connection information to the ExampleProject project.

To add a Foundry deployment resource, call the AddDeployment method with one of the generated FoundryModel entries:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var foundry = builder.AddFoundry("foundry");
var chat = foundry.AddDeployment("chat", FoundryModel.OpenAI.Gpt5Mini);
builder.AddProject<Projects.ExampleProject>()
.WithReference(chat)
.WaitFor(chat);
// After adding all resources, run the app...

The preceding code:

  • Adds an Azure AI Foundry resource named foundry.
  • Adds a Foundry deployment resource named chat using the generated FoundryModel.OpenAI.Gpt5Mini descriptor.

If you need a different generated model descriptor, use the corresponding nested type, such as FoundryModel.Microsoft.Phi4Reasoning:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var foundry = builder.AddFoundry("foundry");
var chat = foundry.AddDeployment("chat", FoundryModel.Microsoft.Phi4Reasoning);
builder.AddProject<Projects.ExampleProject>()
.WithReference(chat)
.WaitFor(chat);
builder.Build().Run();

You can customize deployment properties using the WithProperties method:

var chat = foundry.AddDeployment("chat", FoundryModel.OpenAI.Gpt5Mini)
.WithProperties(deployment =>
{
deployment.SkuName = "Standard";
deployment.SkuCapacity = 10;
});

The preceding code sets the SKU name to Standard and capacity to 10 for the deployment.

Use the AddProject method to create an Azure AI Foundry project for agents, project-scoped connections, and related Azure resources:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var foundry = builder.AddFoundry("foundry");
var project = foundry.AddProject("my-project");
var chat = project.AddModelDeployment("chat", FoundryModel.OpenAI.Gpt5Mini);
builder.AddProject<Projects.ExampleProject>("api")
.WithReference(project)
.WithReference(chat)
.WaitFor(chat);
builder.Build().Run();

The preceding code creates a Foundry project and adds a deployment through AddModelDeployment. When you call WithReference(project), Aspire injects the standard connection string and project-specific connection properties such as the project endpoint and Application Insights connection string into the consuming resource.

You can customize the Azure resources associated with a Foundry project:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var foundry = builder.AddFoundry("foundry");
var appInsights = builder.AddAzureApplicationInsights("appinsights");
var keyVault = builder.AddAzureKeyVault("keyvault");
var registry = builder.AddAzureContainerRegistry("agents");
var project = foundry.AddProject("my-project")
.WithAppInsights(appInsights)
.WithKeyVault(keyVault)
.WithContainerRegistry(registry);

AddProject creates a default Azure Container Registry for hosted agents. Use WithContainerRegistry when you want to point the project at a different registry.

Publish a hosted agent to Azure AI Foundry

Section titled “Publish a hosted agent to Azure AI Foundry”

Use PublishAsHostedAgent to publish an executable or containerized app as a hosted agent in a Foundry project:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var foundry = builder.AddFoundry("foundry");
var project = foundry.AddProject("my-project");
var chat = project.AddModelDeployment("chat", FoundryModel.OpenAI.Gpt5Mini);
builder.AddPythonApp("agent-python", "..\\agent", "main:app")
.WithReference(project)
.WithReference(chat)
.PublishAsHostedAgent(project);
builder.AddProject<Projects.Agent>("agent-dotnet")
.WithHttpEndpoint(targetPort: 9000)
.WithReference(project)
.WithReference(chat)
.PublishAsHostedAgent(project);
builder.Build().Run();

In run mode, PublishAsHostedAgent(...) configures a local http endpoint for the agent. Aspire first checks whether the resource already has an endpoint named http. If that endpoint has a target port, Aspire preserves it. If there is no existing http target port, Aspire defaults to 8088.

Aspire also injects the selected port as DEFAULT_AD_PORT, so hosted-agent apps can bind to the right port:

var port = Environment.GetEnvironmentVariable("DEFAULT_AD_PORT") ?? "8088";
builder.WebHost.UseUrls($"http://+:{port}");

If your hosted agent listens on a different port, declare the endpoint before calling PublishAsHostedAgent(...):

var dotnetWeatherAgent = builder.AddProject<Projects.WeatherAgent_Dotnet>("weather-agent-dotnet")
.WithHttpEndpoint(targetPort: 9000)
.WithReference(project).WaitFor(project)
.WithReference(chat).WaitFor(chat);
dotnetWeatherAgent.PublishAsHostedAgent(project);

In run mode, Aspire also adds dashboard URLs for /responses, /liveness, and /readiness, configures /liveness as an HTTP health check, adds a dashboard command for sending a message to /responses, and enables OpenTelemetry environment variables for agent instrumentation.

For .NET hosted agents, add your Service Defaults project reference and call builder.AddServiceDefaults() in the hosted-agent app so logs, metrics, traces, HTTP instrumentation, and OTLP export flow into the Aspire dashboard. Then enable telemetry on the Foundry Responses chat client that backs the Microsoft Agent Framework (MAF) agent.

In publish mode, Aspire creates an AzureHostedAgentResource and publishes the container to the project-associated registry.

If you omit the project argument, Aspire uses an existing Foundry project from the app model or creates one automatically.

For prompt-only scenarios, use AddPromptAgent on a Foundry project:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var foundry = builder.AddFoundry("foundry");
var project = foundry.AddProject("my-project");
var chat = project.AddModelDeployment("chat", FoundryModel.OpenAI.Gpt5Mini);
var webSearch = project.AddWebSearchTool("web-search");
var webResearcher = project.AddPromptAgent(chat, name: "web-researcher",
instructions: """
You are the Web Researcher. Use web search for current information,
cite sources, summarize tradeoffs, and keep answers concise and practical.
""")
.WithTool(webSearch);
builder.Build().Run();

Parameter details:

APIParameterDescription
AddPromptAgent(...)modelThe Foundry model deployment resource the prompt agent uses, such as chat from project.AddModelDeployment(...).
AddPromptAgent(...)nameThe Aspire resource name and Foundry agent name. This also drives generated environment variable prefixes, for example web-researcher becomes WEB_RESEARCHER.
AddPromptAgent(...)instructionsOptional system instructions for the prompt agent. Use this to define behavior, tool-use guidance, and response style.
WithTool(...)toolA Foundry tool resource created on the same Foundry project, such as AddWebSearchTool(...), AddCodeInterpreterTool(...), or AddAISearchTool(...).

Prompt agents are deployed to Azure AI Foundry even during local development. Local apps call the cloud-provisioned agent through the injected project endpoint and agent name.

Aspire also makes the declared agents easy to try from the dashboard. Prompt agents get a Send Message command from AddPromptAgent(...). Hosted agents published with PublishAsHostedAgent(...) get a highlighted Send Message command that posts to the local /responses endpoint, plus dashboard links for /responses, /liveness, and /readiness.

Aspire dashboard showing prompt and hosted agent resources with Send Message commands. Hosted agent responses invocation result in the Aspire dashboard.

You might have an existing Azure AI Foundry service that you want to connect to. You can chain a call to annotate that your FoundryResource is an existing resource:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var existingFoundryName = builder.AddParameter("existingFoundryName");
var existingFoundryResourceGroup = builder.AddParameter("existingFoundryResourceGroup");
var foundry = builder.AddFoundry("foundry")
.AsExisting(existingFoundryName, existingFoundryResourceGroup);
builder.AddProject<Projects.ExampleProject>()
.WithReference(foundry);
// After adding all resources, run the app...

Aspire supports the usage of Foundry Local for local development. Add the following to your AppHost project:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var foundry = builder.AddFoundry("foundry")
.RunAsFoundryLocal();
var chat = foundry.AddDeployment("chat", FoundryModel.Local.Phi4);
builder.AddProject<Projects.ExampleProject>()
.WithReference(chat)
.WaitFor(chat);
// After adding all resources, run the app...

When the AppHost starts up, the local foundry service is also started. This requires the local machine to have Foundry Local installed and running.

The RunAsFoundryLocal method configures the resource to run as an emulator. It downloads and loads the specified models locally. The method provides health checks for the local service and automatically manages the Foundry Local lifecycle.

You can assign specific roles to resources that need to access the Azure AI Foundry service. Use the WithRoleAssignments method:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var foundry = builder.AddFoundry("chat");
builder.AddProject<Projects.Api>("api")
.WithRoleAssignments(foundry, CognitiveServicesBuiltInRole.CognitiveServicesUser)
.WithReference(foundry);
builder.Build().Run();

The preceding code assigns the CognitiveServicesUser role to the api project, granting it the necessary permissions to access the Microsoft Foundry resource.

If you’re new to Bicep, it’s a domain-specific language for defining Azure resources. With Aspire, you don’t need to write Bicep by-hand, instead the provisioning APIs generate Bicep for you. When you publish your app, the generated Bicep provisions an Azure AI Foundry resource with standard defaults.

Generated Bicep — ai-foundry.bicep
@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location
resource ai_foundry 'Microsoft.CognitiveServices/accounts@2024-10-01' = {
name: take('aifoundry-${uniqueString(resourceGroup().id)}', 64)
location: location
identity: {
type: 'SystemAssigned'
}
kind: 'AIServices'
properties: {
customSubDomainName: toLower(take(concat('ai-foundry', uniqueString(resourceGroup().id)), 24))
publicNetworkAccess: 'Enabled'
disableLocalAuth: true
}
sku: {
name: 'S0'
}
tags: {
'aspire-resource-name': 'ai-foundry'
}
}
resource chat 'Microsoft.CognitiveServices/accounts/deployments@2024-10-01' = {
name: 'Phi-4'
properties: {
model: {
format: 'Microsoft'
name: 'Phi-4'
version: '1'
}
}
sku: {
name: 'GlobalStandard'
capacity: 1
}
parent: ai_foundry
}
output aiFoundryApiEndpoint string = ai_foundry.properties.endpoints['AI Foundry API']
output endpoint string = ai_foundry.properties.endpoint
output name string = ai_foundry.name

The preceding Bicep is a module that provisions an Azure Cognitive Services resource configured for AI Services. Additionally, role assignments are created for the Azure resource in a separate module:

Generated Bicep — ai-foundry-roles.bicep
@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location
param ai_foundry_outputs_name string
param principalType string
param principalId string
resource ai_foundry 'Microsoft.CognitiveServices/accounts@2024-10-01' existing = {
name: ai_foundry_outputs_name
}
resource ai_foundry_CognitiveServicesUser 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(ai_foundry.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a97b65f3-24c7-4388-baec-2e87135dc908'))
properties: {
principalId: principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a97b65f3-24c7-4388-baec-2e87135dc908')
principalType: principalType
}
scope: ai_foundry
}
resource ai_foundry_CognitiveServicesOpenAIUser 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(ai_foundry.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd'))
properties: {
principalId: principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd')
principalType: principalType
}
scope: ai_foundry
}

The generated Bicep is a starting point and is influenced by changes to the provisioning infrastructure in C#. Customizations to the Bicep file directly will be overwritten, so make changes through the C# provisioning APIs to ensure they’re reflected in the generated files.

All Aspire Azure resources are subclasses of the AzureProvisioningResource type. This enables customization of the generated Bicep by providing a fluent API to configure the Azure resources—using the ConfigureInfrastructure API:

C# — AppHost.cs
builder.AddFoundry("foundry")
.ConfigureInfrastructure(infra =>
{
var resources = infra.GetProvisionableResources();
var account = resources.OfType<CognitiveServicesAccount>().Single();
account.Sku = new CognitiveServicesSku
{
Tier = CognitiveServicesSkuTier.Enterprise,
Name = "E0"
};
account.Tags.Add("ExampleKey", "Example value");
});

The preceding code:

  • Chains a call to the ConfigureInfrastructure API:
    • The infra parameter is an instance of the AzureResourceInfrastructure type.
    • The provisionable resources are retrieved by calling the GetProvisionableResources method.
    • The single CognitiveServicesAccount resource is retrieved.
    • The Sku property is assigned to a new instance of CognitiveServicesSku with an E0 name and Enterprise tier.
    • A tag is added to the Cognitive Services resource with a key of ExampleKey and a value of Example value.