Azure Key Vault hosting integration

Azure Key Vault logo

The Aspire Azure Key Vault hosting integration models an Azure Key Vault resource as the AzureKeyVaultResource type. To access this type and APIs for expressing them within your AppHost project, install the 📦 Aspire.Hosting.Azure.KeyVault NuGet package:

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

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

Add Azure Key Vault resource

To add an Azure Key Vault resource to your AppHost project, call the AddAzureKeyVault method providing a name:

var builder = DistributedApplication.CreateBuilder(args);
  
var keyVault = builder.AddAzureKeyVault("key-vault");
  
builder.AddProject<Projects.ExampleProject>()
    .WithReference(keyVault);
  
// After adding all resources, run the app...

The WithReference method configures a connection in the ExampleProject named "key-vault".

Caution

By default, AddAzureKeyVault configures a Key Vault Administrator built-in role.

Tip

When you call AddAzureKeyVault, 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.

Connect to an existing Azure Key Vault instance

You might have an existing Azure Key Vault instance that you want to connect to. You can chain a call to annotate that your resource is an existing resource:

var builder = DistributedApplication.CreateBuilder(args);
  
var existingKeyVaultName = builder.AddParameter("existingKeyVaultName");
var existingKeyVaultResourceGroup = builder.AddParameter("existingKeyVaultResourceGroup");
  
var keyvault = builder.AddAzureKeyVault("key-vault")
    .AsExisting(existingKeyVaultName, existingKeyVaultResourceGroup);
  
builder.AddProject<Projects.ExampleProject>()
    .WithReference(keyvault);

Note

Alternatively, instead of representing an Azure Key Vault 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.

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 add an Azure Key Vault resource, the following Bicep is generated:

@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location
  
resource key_vault 'Microsoft.KeyVault/vaults@2024-11-01' = {
  name: take('keyvault-${uniqueString(resourceGroup().id)}', 24)
  location: location
  properties: {
    tenantId: tenant().tenantId
    sku: {
      family: 'A'
      name: 'standard'
    }
    enableRbacAuthorization: true
  }
  tags: {
    'aspire-resource-name': 'key-vault'
  }
}
  
output vaultUri string = key_vault.properties.vaultUri
  
output name string = key_vault.name

The preceding Bicep is a module that provisions an Azure Key Vault 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 key_vault_outputs_name string
  
param principalType string
  
param principalId string
  
resource key_vault 'Microsoft.KeyVault/vaults@2024-11-01' existing = {
  name: key_vault_outputs_name
}
  
resource key_vault_KeyVaultSecretsUser 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(key_vault.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6'))
  properties: {
    principalId: principalId
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6')
    principalType: principalType
  }
  scope: key_vault
}

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 type enables the customization of the generated Bicep by providing a fluent API to configure the Azure resources using the ConfigureInfrastructure API. For example:

var builder = DistributedApplication.CreateBuilder(args);
  
builder.AddAzureKeyVault("key-vault")
    .ConfigureInfrastructure(infra =>
    {
        var keyVault = infra.GetProvisionableResources()
                            .OfType<KeyVaultService>()
                            .Single();
  
        keyVault.Properties.Sku = new()
        {
            Family = KeyVaultSkuFamily.A,
            Name = KeyVaultSkuName.Premium,
        };
        keyVault.Properties.EnableRbacAuthorization = true;
        keyVault.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 KeyVaultService resource is retrieved.
    • The Sku property is set to a new KeyVault.KeyVaultSku instance.
    • The KeyVaultProperties.EnableRbacAuthorization property is set to true.
    • A tag is added to the resource with a key of ExampleKey and a value of Example value.

There are many more configuration options available to customize the Key Vault resource. For more information, see Azure.Provisioning customization.

Connection properties

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

Property Name Description
Uri The Key Vault endpoint URI, typically https://<vault-name>.vault.azure.net/

Note

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