Skip to content
DocsTry Aspire
DocsTry

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

This updates your aspire.config.json with the Azure OpenAI hosting integration package:

aspire.config.json
{
"packages": {
"Aspire.Hosting.Azure.CognitiveServices": "13.5.3"
}
}

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:

apphost.mts
import {
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
} from './.aspire/modules/aspire.mjs';
const
const builder: IDistributedApplicationBuilder
builder
= await
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
();
const
const openai: AzureOpenAIResource
openai
= await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addAzureOpenAI(name: string): AzureOpenAIResource

Adds an Azure OpenAI resource to the application model.

addAzureOpenAI
("openai");
const
const chat: AzureOpenAIDeploymentResource
chat
= await
const openai: AzureOpenAIResource
openai
.
AzureOpenAIResource.addDeployment(name: string, modelName: string, modelVersion: string): AzureOpenAIDeploymentResource

Adds an Azure OpenAI deployment resource

addDeployment
("chat", "gpt-4o", "2024-08-06");
await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addNodeApp(name: string, appDirectory: string, scriptPath: string): NodeAppResource

Adds a node application to the application model. Node should be available on the PATH.

addNodeApp
("api", "./api", "index.js")
.
ExecutableResource.withReference(source: EndpointReference | string | uri, options?: {
connectionName?: string;
optional?: boolean;
name?: string;
} | undefined): NodeAppResource (+1 overload)

Adds a reference to another resource

withReference
(
const chat: AzureOpenAIDeploymentResource
chat
)
.
ExecutableResource.waitFor(dependency: IResource | IResourceWithConnectionString, waitBehavior?: WaitBehavior): NodeAppResource

Waits for another resource to be ready

waitFor
(
const chat: AzureOpenAIDeploymentResource
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:

apphost.mts
import {
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
} from './.aspire/modules/aspire.mjs';
const
const builder: IDistributedApplicationBuilder
builder
= await
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
();
const
const openai: AzureOpenAIResource
openai
= await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addAzureOpenAI(name: string): AzureOpenAIResource

Adds an Azure OpenAI resource to the application model.

addAzureOpenAI
("openai");
const
const chat: AzureOpenAIDeploymentResource
chat
= await
const openai: AzureOpenAIResource
openai
.
AzureOpenAIResource.addDeployment(name: string, modelName: string, modelVersion: string): AzureOpenAIDeploymentResource

Adds an Azure OpenAI deployment resource

addDeployment
("chat", "gpt-4o", "2024-08-06");
const
const embeddings: AzureOpenAIDeploymentResource
embeddings
= await
const openai: AzureOpenAIResource
openai
.
AzureOpenAIResource.addDeployment(name: string, modelName: string, modelVersion: string): AzureOpenAIDeploymentResource

Adds an Azure OpenAI deployment resource

addDeployment
("embeddings", "text-embedding-3-small", "1");
await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addNodeApp(name: string, appDirectory: string, scriptPath: string): NodeAppResource

Adds a node application to the application model. Node should be available on the PATH.

addNodeApp
("api", "./api", "index.js")
.
ExecutableResource.withReference(source: EndpointReference | string | uri, options?: {
connectionName?: string;
optional?: boolean;
name?: string;
} | undefined): NodeAppResource (+1 overload)

Adds a reference to another resource

withReference
(
const chat: AzureOpenAIDeploymentResource
chat
)
.
ExecutableResource.withReference(source: EndpointReference | string | uri, options?: {
connectionName?: string;
optional?: boolean;
name?: string;
} | undefined): NodeAppResource (+1 overload)

Adds a reference to another resource

withReference
(
const embeddings: AzureOpenAIDeploymentResource
embeddings
)
.
ExecutableResource.waitFor(dependency: IResource | IResourceWithConnectionString, waitBehavior?: WaitBehavior): NodeAppResource

Waits for another resource to be ready

waitFor
(
const chat: AzureOpenAIDeploymentResource
chat
)
.
ExecutableResource.waitFor(dependency: IResource | IResourceWithConnectionString, waitBehavior?: WaitBehavior): NodeAppResource

Waits for another resource to be ready

waitFor
(
const embeddings: AzureOpenAIDeploymentResource
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 in C# or withCognitiveServicesRoleAssignments in TypeScript on the consuming resource:

apphost.mts
import {
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
,
type AzureOpenAIRole = "CognitiveServicesOpenAIContributor" | "CognitiveServicesOpenAIUser" | "CognitiveServicesUser"
const AzureOpenAIRole: {
readonly CognitiveServicesOpenAIContributor: "CognitiveServicesOpenAIContributor";
readonly CognitiveServicesOpenAIUser: "CognitiveServicesOpenAIUser";
readonly CognitiveServicesUser: "CognitiveServicesUser";
}

Enum Aspire.Hosting.Azure.CognitiveServices.AzureOpenAIRole

AzureOpenAIRole
} from './.aspire/modules/aspire.mjs';
const
const builder: IDistributedApplicationBuilder
builder
= await
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
();
const
const openai: AzureOpenAIResource
openai
= await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addAzureOpenAI(name: string): AzureOpenAIResource

Adds an Azure OpenAI resource to the application model.

addAzureOpenAI
("openai");
const
const chat: AzureOpenAIDeploymentResource
chat
= await
const openai: AzureOpenAIResource
openai
.
AzureOpenAIResource.addDeployment(name: string, modelName: string, modelVersion: string): AzureOpenAIDeploymentResource

Adds an Azure OpenAI deployment resource

addDeployment
("chat", "gpt-4o", "2024-08-06");
await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addNodeApp(name: string, appDirectory: string, scriptPath: string): NodeAppResource

Adds a node application to the application model. Node should be available on the PATH.

addNodeApp
("api", "./api", "index.js")
.
ExecutableResource.withReference(source: EndpointReference | string | uri, options?: {
connectionName?: string;
optional?: boolean;
name?: string;
} | undefined): NodeAppResource (+1 overload)

Adds a reference to another resource

withReference
(
const chat: AzureOpenAIDeploymentResource
chat
)
.
ExecutableResource.waitFor(dependency: IResource | IResourceWithConnectionString, waitBehavior?: WaitBehavior): NodeAppResource

Waits for another resource to be ready

waitFor
(
const chat: AzureOpenAIDeploymentResource
chat
)
.
ExecutableResource.withCognitiveServicesRoleAssignments(target: AzureOpenAIResource, roles: AzureOpenAIRole[]): NodeAppResource

Assigns the specified roles to the given resource, granting it the necessary permissions on the target Azure OpenAI resource. This replaces the default role assignments for the resource.

withCognitiveServicesRoleAssignments
(
const openai: AzureOpenAIResource
openai
, [
const AzureOpenAIRole: {
readonly CognitiveServicesOpenAIContributor: "CognitiveServicesOpenAIContributor";
readonly CognitiveServicesOpenAIUser: "CognitiveServicesOpenAIUser";
readonly CognitiveServicesUser: "CognitiveServicesUser";
}

Enum Aspire.Hosting.Azure.CognitiveServices.AzureOpenAIRole

AzureOpenAIRole
.
type CognitiveServicesOpenAIContributor: "CognitiveServicesOpenAIContributor"
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:

apphost.mts
import {
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
} from './.aspire/modules/aspire.mjs';
const
const builder: IDistributedApplicationBuilder
builder
= await
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
();
const
const openai: AzureOpenAIResource
openai
= await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addAzureOpenAI(name: string): AzureOpenAIResource

Adds an Azure OpenAI resource to the application model.

addAzureOpenAI
("openai");
await
const openai: AzureOpenAIResource
openai
.
AzureBicepResource.clearDefaultRoleAssignments(): IAzureResource

Clears all default role assignments for the specified Azure resource.

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:

apphost.mts
import {
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
} from './.aspire/modules/aspire.mjs';
const
const builder: IDistributedApplicationBuilder
builder
= await
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
();
const
const existingOpenAIName: ParameterResource
existingOpenAIName
= await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addParameter(name: string, options?: {
value?: string;
publishValueAsDefault?: boolean;
secret?: boolean;
}): ParameterResource (+1 overload)

Adds a parameter resource

addParameter
("existingOpenAIName");
const
const existingOpenAIResourceGroup: ParameterResource
existingOpenAIResourceGroup
= await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addParameter(name: string, options?: {
value?: string;
publishValueAsDefault?: boolean;
secret?: boolean;
}): ParameterResource (+1 overload)

Adds a parameter resource

addParameter
("existingOpenAIResourceGroup");
const
const openai: AzureOpenAIResource
openai
= await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addAzureOpenAI(name: string): AzureOpenAIResource

Adds an Azure OpenAI resource to the application model.

addAzureOpenAI
("openai");
await
const openai: AzureOpenAIResource
openai
.
AzureBicepResource.asExisting(name: string | ParameterResource, resourceGroup?: string | ParameterResource): IAzureResource

Marks the resource as an existing resource in both run and publish modes.

asExisting
(
const existingOpenAIName: ParameterResource
existingOpenAIName
,
const existingOpenAIResourceGroup: ParameterResource
existingOpenAIResourceGroup
);
const
const chat: AzureOpenAIDeploymentResource
chat
= await
const openai: AzureOpenAIResource
openai
.
AzureOpenAIResource.addDeployment(name: string, modelName: string, modelVersion: string): AzureOpenAIDeploymentResource

Adds an Azure OpenAI deployment resource

addDeployment
("chat", "gpt-4o", "2024-08-06");
await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addNodeApp(name: string, appDirectory: string, scriptPath: string): NodeAppResource

Adds a node application to the application model. Node should be available on the PATH.

addNodeApp
("api", "./api", "index.js")
.
ExecutableResource.withReference(source: EndpointReference | string | uri, options?: {
connectionName?: string;
optional?: boolean;
name?: string;
} | undefined): NodeAppResource (+1 overload)

Adds a reference to another resource

withReference
(
const chat: AzureOpenAIDeploymentResource
chat
)
.
ExecutableResource.waitFor(dependency: IResource | IResourceWithConnectionString, waitBehavior?: WaitBehavior): NodeAppResource

Waits for another resource to be ready

waitFor
(
const chat: AzureOpenAIDeploymentResource
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:

apphost.mts
import {
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
} from './.aspire/modules/aspire.mjs';
const
const builder: IDistributedApplicationBuilder
builder
= await
function createBuilder(): IDistributedApplicationBuilder

Creates a new distributed application builder

createBuilder
();
const
const openai: AzureOpenAIResource
openai
= await
const builder: IDistributedApplicationBuilder
builder
.
IDistributedApplicationBuilder.addAzureOpenAI(name: string): AzureOpenAIResource

Adds an Azure OpenAI resource to the application model.

addAzureOpenAI
("openai");
await
const openai: AzureOpenAIResource
openai
.
AzureProvisioningResource.configureInfrastructure(configure: (obj: AzureResourceInfrastructure) => Promise<void>): AzureProvisioningResource

Configures the Azure provisioning infrastructure callback

configureInfrastructure
(async
infra: AzureResourceInfrastructure
infra
=> {
const
const resources: any[]
resources
= await
infra: AzureResourceInfrastructure
infra
.
AzureResourceInfrastructure.getProvisionableResources(): Promise<any[]>

Gets the provisionable Azure resources produced by the infrastructure callback.

getProvisionableResources
();
// Modify the CognitiveServicesAccount resource as needed
});
// 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.