Skip to content
Docs Try Aspire
Docs Try

Set up Azure OpenAI in the AppHost

Azure OpenAI logo

This article is the reference for the Aspire Azure OpenAI hosting integration. It enumerates the AppHost APIs — with examples for both AppHost.cs and apphost.ts — that you use to model an Azure OpenAI account and deployment resources in your AppHost project.

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

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

Terminal
aspire add azure-cognitive-services

Learn more about aspire add in the command reference.

Or, choose a manual installation approach:

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

Once you’ve installed the hosting integration in your AppHost project, you can add an Azure OpenAI account resource and then add one or more deployment resources beneath it:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var openai = builder.AddAzureOpenAI("openai");
var chat = openai.AddDeployment(
name: "chat",
modelName: "gpt-4o",
modelVersion: "2024-08-06");
builder.AddProject<Projects.ExampleProject>("apiservice")
.WithReference(chat)
.WaitFor(chat);
// After adding all resources, run the app...
  1. Calling AddAzureOpenAI (or addAzureOpenAI) creates an AzureOpenAIResource that models the Azure Cognitive Services account. It implicitly calls AddAzureProvisioning, which adds support for generating Azure resources dynamically during app startup.

  2. Calling AddDeployment (or addDeployment) creates an AzureOpenAIDeploymentResource child that represents a model deployment on the account. Specify the deployment name, model name, and model version. See Azure OpenAI model versions for available models and versions.

  3. The AppHost reference call configures a connection in the consuming project named after the referenced deployment resource, such as chat in the preceding example.

Add multiple deployment children beneath the same account to share a single Azure OpenAI resource:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var openai = builder.AddAzureOpenAI("openai");
var chat = openai.AddDeployment("chat", "gpt-4o", "2024-08-06");
var embeddings = openai.AddDeployment("embeddings", "text-embedding-3-small", "1");
builder.AddProject<Projects.ExampleProject>("apiservice")
.WithReference(chat)
.WithReference(embeddings)
.WaitFor(chat)
.WaitFor(embeddings);
// After adding all resources, run the app...

Referencing chat passes a connection named chat to the consuming project, and referencing embeddings passes a connection named embeddings. Both share the parent Azure OpenAI account.

By default, Aspire provisions Azure OpenAI with disableLocalAuth: true and automatically creates a CognitiveServicesOpenAIUser role assignment for each app that references the resource. This means consuming apps authenticate via managed identity — no API key is needed.

To explicitly assign roles to a consuming app (for example, to grant contributor access for fine-tuning scenarios), call WithRoleAssignments (or withRoleAssignments) on the consuming resource:

C# — AppHost.cs
using Aspire.Hosting.Azure;
var builder = DistributedApplication.CreateBuilder(args);
var openai = builder.AddAzureOpenAI("openai");
var chat = openai.AddDeployment("chat", "gpt-4o", "2024-08-06");
builder.AddProject<Projects.ExampleProject>("apiservice")
.WithReference(chat)
.WaitFor(chat)
.WithRoleAssignments(openai, AzureOpenAIRole.CognitiveServicesOpenAIContributor);
// After adding all resources, run the app...

The available AzureOpenAIRole values are:

RoleDescription
CognitiveServicesOpenAIUserRead access to models, deployments, and completions. Default when using WithReference.
CognitiveServicesOpenAIContributorCreate and delete deployments in addition to user permissions.
CognitiveServicesUserBroader Cognitive Services access.

To remove the default automatic role assignments and manage them entirely yourself, call ClearDefaultRoleAssignments (or clearDefaultRoleAssignments) on the Azure OpenAI resource:

C# — AppHost.cs
var openai = builder.AddAzureOpenAI("openai")
.ClearDefaultRoleAssignments();

Connect to an existing Azure OpenAI service

Section titled “Connect to an existing Azure OpenAI service”

You might have an already-deployed Azure OpenAI account in your Azure subscription that you want to connect to. Use AsExisting (or asExisting) to point the resource at an existing account instead of provisioning a new one:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var existingOpenAIName = builder.AddParameter("existingOpenAIName");
var existingOpenAIResourceGroup = builder.AddParameter("existingOpenAIResourceGroup");
var openai = builder.AddAzureOpenAI("openai")
.AsExisting(existingOpenAIName, existingOpenAIResourceGroup);
var chat = openai.AddDeployment("chat", "gpt-4o", "2024-08-06");
builder.AddProject<Projects.ExampleProject>("apiservice")
.WithReference(chat)
.WaitFor(chat);
// After adding all resources, run the app...

For more information on treating Azure resources as existing resources, see Use existing Azure resources.

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 — the provisioning APIs generate it for you. When you publish your app, the generated Bicep provisions an Azure Cognitive Services account with standard defaults.

Bicep — openai.bicep
@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location
resource openai 'Microsoft.CognitiveServices/accounts@2024-10-01' = {
name: take('openai-${uniqueString(resourceGroup().id)}', 64)
location: location
kind: 'OpenAI'
properties: {
customSubDomainName: toLower(take(concat('openai', uniqueString(resourceGroup().id)), 24))
publicNetworkAccess: 'Enabled'
disableLocalAuth: true
}
sku: {
name: 'S0'
}
tags: {
'aspire-resource-name': 'openai'
}
}
resource chat 'Microsoft.CognitiveServices/accounts/deployments@2024-10-01' = {
name: 'chat'
properties: {
model: {
format: 'OpenAI'
name: 'gpt-4o'
version: '2024-08-06'
}
}
sku: {
name: 'Standard'
capacity: 8
}
parent: openai
}
output connectionString string = 'Endpoint=${openai.properties.endpoint}'
output name string = openai.name

Role assignments are created in a companion module:

Bicep — openai-roles.bicep
@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location
param openai_outputs_name string
param principalType string
param principalId string
resource openai 'Microsoft.CognitiveServices/accounts@2024-10-01' existing = {
name: openai_outputs_name
}
resource openai_CognitiveServicesOpenAIUser 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(openai.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: openai
}

The generated Bicep is a starting point and is influenced by changes to the provisioning infrastructure in C#. Direct edits to the Bicep file are overwritten, so make changes through the C# provisioning APIs to ensure they are reflected in the generated output.

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

C# — AppHost.cs
using Azure.Provisioning.CognitiveServices;
var builder = DistributedApplication.CreateBuilder(args);
builder.AddAzureOpenAI("openai")
.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");
});
// After adding all resources, run the app...

The preceding C# code:

  • Calls ConfigureInfrastructure to customize the generated Bicep.
  • Retrieves provisionable resources with GetProvisionableResources.
  • Gets the single CognitiveServicesAccount resource.
  • Upgrades the SKU to Enterprise / E0.
  • Adds a tag to the Cognitive Services account.

Common model identifiers for Azure OpenAI:

CategoryModel identifiers
Chatgpt-4o, gpt-4o-mini, gpt-4-turbo
Reasoningo3, o3-mini, o4-mini
Embeddingstext-embedding-3-small, text-embedding-3-large
Imagesdall-e-3
Audiowhisper

For the full list and current model versions, see the Azure OpenAI models documentation.

For the full reference of Azure OpenAI connection properties — and how consuming apps in C#, TypeScript, Python, and Go read them — see Connect to Azure OpenAI.