Skip to content
Docs Try Aspire

Microsoft Foundry hosting integration

Microsoft Foundry logo 🧪 Preview

The Aspire Microsoft Foundry hosting integration models a Microsoft Foundry account as the FoundryResource type. To access this type and related APIs in your AppHost project, install the 📦 Aspire.Hosting.Foundry NuGet package:

Aspire CLI — Add Aspire.Hosting.Foundry package
aspire add foundry

The Aspire CLI is interactive, be sure to select the appropriate search result when prompted:

Aspire CLI — Example output prompt
Select an integration to add:
> foundry (Aspire.Hosting.Foundry)
> Other results listed as selectable options...

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

To add a Microsoft 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 a Microsoft Foundry resource named foundry to the AppHost project. The WithReference method passes the connection information to the ExampleProject project.

Add a Microsoft Foundry deployment resource

Section titled “Add a Microsoft Foundry deployment resource”

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

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 a Microsoft Foundry resource named foundry.
  • Adds a Microsoft Foundry deployment resource named chat using the generated FoundryModel.OpenAI.Gpt5Mini descriptor.

For more information about the generated model descriptors, see the FoundryModel API reference.

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 a Microsoft 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 Microsoft Foundry

Section titled “Publish a hosted agent to Microsoft 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", "..\\agent", "main:app")
.WithReference(project)
.WithReference(chat)
.PublishAsHostedAgent(project);
builder.Build().Run();

In run mode, PublishAsHostedAgent configures local HTTP, liveness, and readiness endpoints and enables OpenTelemetry output for the 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 AddAndPublishPromptAgent 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);
project.AddAndPublishPromptAgent(
chat,
"support-agent",
instructions: "You are a helpful support assistant.");
builder.Build().Run();

This creates an AzurePromptAgentResource that uses the specified model deployment in the target Foundry project.

Connect to an existing Microsoft Foundry service

Section titled “Connect to an existing Microsoft Foundry service”

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

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 Microsoft Foundry service. Use the WithRoleAssignments method:

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

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 a Microsoft 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.