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:

Install the NuGet package
dotnet add package Aspire.Hosting.Foundry

Note

This integration was previously shipped as Aspire.Hosting.Azure.AIFoundry. When upgrading from earlier previews, replace that package with Aspire.Hosting.Foundry. If your code referenced package-specific Foundry types such as the old AIFoundryModel, update those references to FoundryModel and add using Aspire.Hosting.Foundry; where needed.

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

Add a Microsoft Foundry resource

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

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.

Important

When you call AddFoundry, it implicitly calls AddAzureProvisioning—which adds support for generating Azure resources dynamically during app startup. The app must configure the appropriate subscription and location. For more information, see Local provisioning: Configuration.

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:

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();

Configure deployment properties

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.

Add a Microsoft Foundry project

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

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.

Configure a Foundry project

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

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

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

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.

Add and publish a prompt agent

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

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

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

Important

When you call RunAsExisting, PublishAsExisting, or AsExisting methods to work with resources that are already present in your Azure subscription, you must add certain configuration values to your AppHost to ensure that Aspire can locate them. The necessary configuration values include SubscriptionId, AllowResourceGroupCreation, ResourceGroup, and Location. If you don't set them, "Missing configuration" errors appear in the Aspire dashboard. For more information about how to set them, see Use existing Azure resources.

Use Foundry Local for development

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

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.

Caution

Foundry Projects aren't supported when the parent Foundry resource uses RunAsFoundryLocal(). Use account-level deployments for local emulator scenarios.

Assign roles to resources

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

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.

Provisioning-generated Bicep

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.

@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:

@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.

Customize provisioning infrastructure

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:

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.