Azure OpenAI hosting integration

Azure OpenAI logo

The Aspire Azure OpenAI hosting integration models the Azure OpenAI service as the AzureOpenAIResource type. To access this type and APIs for expressing them within your AppHost project, install the 📦 Aspire.Hosting.Azure.CognitiveServices NuGet package:

Install the NuGet package
dotnet add package Aspire.Hosting.Azure.CognitiveServices

For an introduction to working with the Azure OpenAI hosting integration, see Get started with the Azure OpenAI integration.

Add an Azure OpenAI resource

To add an Azure OpenAI resource to your AppHost project, call the AddAzureOpenAI method providing a name:

var builder = DistributedApplication.CreateBuilder(args);
  
var openai = builder.AddAzureOpenAI("openai");
  
builder.AddProject<Projects.ExampleProject>()
    .WithReference(openai);
  
// After adding all resources, run the app...

The preceding code adds an Azure OpenAI resource named openai to the AppHost project. The WithReference method passes the connection information to the ExampleProject project.

Caution

When you call AddAzureOpenAI, 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 an Azure OpenAI deployment resource

To add an Azure OpenAI deployment resource, call the AddDeployment method:

var builder = DistributedApplication.CreateBuilder(args);
  
var openai = builder.AddAzureOpenAI("openai");
  
openai.AddDeployment(
    name: "preview",
    modelName: "gpt-4.5-preview",
    modelVersion: "2025-02-27");
  
builder.AddProject<Projects.ExampleProject>()
       .WithReference(openai)
       .WaitFor(openai);
  
// After adding all resources, run the app...

The preceding code:

  • Adds an Azure OpenAI resource named openai.
  • Adds an Azure OpenAI deployment resource named preview with a model name of gpt-4.5-preview. The model name must correspond to an available model in the Azure OpenAI service.

Connect to an existing Azure OpenAI service

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

var builder = DistributedApplication.CreateBuilder(args);
  
var existingOpenAIName = builder.AddParameter("existingOpenAIName");
var existingOpenAIResourceGroup = builder.AddParameter("existingOpenAIResourceGroup");
  
var openai = builder.AddAzureOpenAI("openai")
    .AsExisting(existingOpenAIName, existingOpenAIResourceGroup);
  
builder.AddProject<Projects.ExampleProject>()
    .WithReference(openai);
  
// After adding all resources, run the app...

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

Note

Alternatively, instead of representing an Azure OpenAI resource, you can add a connection string to the AppHost. This approach is weakly-typed, and doesn't work with role assignments or infrastructure customizations. For more information, see Add existing Azure resources with connection strings.

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 an Azure OpenAI resource with standard defaults.

@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 preview 'Microsoft.CognitiveServices/accounts/deployments@2024-10-01' = {
  name: 'preview'
  properties: {
    model: {
      format: 'OpenAI'
      name: 'gpt-4.5-preview'
      version: '2025-02-27'
    }
  }
  sku: {
    name: 'Standard'
    capacity: 8
  }
  parent: openai
}
  
output connectionString string = 'Endpoint=${openai.properties.endpoint}'
  
output name string = openai.name

The preceding Bicep is a module that provisions an Azure Cognitive Services resource. 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 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#. Customizations to the Bicep file directly will be overwritten, so make changes through the C# provisioning APIs to ensure they are 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:

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");
    });

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 CognitiveServicesAccount property is assigned to a new instance of CognitiveServices.CognitiveServicesSku with an E0 name and CognitiveServicesSkuTier.Enterprise` tier.
    • A tag is added to the Cognitive Services resource with a key of ExampleKey and a value of Example value.

Connection properties

When you reference Azure OpenAI resources using WithReference, the following connection properties are made available to the consuming project:

Azure OpenAI resource

The Azure OpenAI resource exposes the following connection properties:

Property Name Description
Uri The endpoint URI for the Azure OpenAI resource, typically https://<resource-name>.openai.azure.com/

Azure OpenAI deployment

The Azure OpenAI deployment resource inherits all properties from its parent Azure OpenAI resource and adds:

Property Name Description
ModelName The name of the Azure OpenAI deployment, e.g., chat

Note

Aspire exposes each property as an environment variable named [RESOURCE]_[PROPERTY]. For instance, the Uri property of a resource called chat becomes CHAT_URI.