Azure Data Explorer (Kusto)

Azure Data Explorer logo

Azure Data Explorer (also known as Kusto) is a fast and highly scalable data exploration service for log and telemetry data. The Aspire Azure Data Explorer integration enables you to provision Kusto clusters and databases, or run a local emulator during development.

Hosting integration

The Aspire Azure Data Explorer hosting integration models Kusto resources as the following types:

  • AzureKustoClusterResource: Represents an Azure Data Explorer (Kusto) cluster resource.
  • AzureKustoReadWriteDatabaseResource: Represents an Azure Data Explorer database resource.
  • AzureKustoEmulatorResource: Represents an Azure Data Explorer emulator resource.

To access these types and APIs, add the 📦 Aspire.Hosting.Azure.Kusto NuGet package to your AppHost project.

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

Add Azure Data Explorer cluster resource

In your AppHost project, call AddAzureKustoCluster to add and return an Azure Data Explorer cluster resource builder:

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

The preceding code adds an Azure Data Explorer cluster resource named kusto to the application model.

Caution

When you call AddAzureKustoCluster, 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 Azure Data Explorer database

To add a database to a Kusto cluster, call the AddReadWriteDatabase method on the cluster resource builder:

var builder = DistributedApplication.CreateBuilder(args);
  
var kusto = builder.AddAzureKustoCluster("kusto");
var database = kusto.AddReadWriteDatabase("analytics");
  
builder.AddProject<Projects.ExampleProject>()
    .WithReference(database)
    .WaitFor(database);
  
// After adding all resources, run the app...

The preceding code:

  • Adds an Azure Data Explorer cluster resource named kusto.
  • Adds a database named analytics to the cluster.
  • References the database in the ExampleProject and waits for it to be ready.

Run Azure Data Explorer as an emulator

For local development and testing, you can run Azure Data Explorer as an emulator using the Kustainer container. Call the RunAsEmulator method:

var builder = DistributedApplication.CreateBuilder(args);
  
var kusto = builder.AddAzureKustoCluster("kusto")
    .RunAsEmulator();
  
var database = kusto.AddReadWriteDatabase("analytics");
  
builder.AddProject<Projects.ExampleProject>()
    .WithReference(database)
    .WaitFor(database);
  
// After adding all resources, run the app...

When running as an emulator:

  • The Kustainer Docker container is used to emulate Azure Data Explorer.
  • Databases are automatically created when the emulator starts.
  • The connection string is automatically configured for local development.

Configure the emulator port

By default, the emulator uses a dynamic port. To configure a specific host port:

var builder = DistributedApplication.CreateBuilder(args);
  
var kusto = builder.AddAzureKustoCluster("kusto")
    .RunAsEmulator(emulator =>
    {
        emulator.WithHostPort(8080);
    });
  
// After adding all resources, run the app...

Add database creation script

When running as an emulator, you can provide a KQL script to initialize the database with tables and data:

var builder = DistributedApplication.CreateBuilder(args);
  
var kusto = builder.AddAzureKustoCluster("kusto")
    .RunAsEmulator();
  
var database = kusto.AddReadWriteDatabase("analytics")
    .WithCreationScript("""
        .create table Events (
            Timestamp: datetime,
            EventType: string,
            Message: string
        )
        """);
  
builder.AddProject<Projects.ExampleProject>()
    .WithReference(database)
    .WaitFor(database);
  
// After adding all resources, run the app...

Note

The creation script is only executed when running as an emulator. In production scenarios, database schema should be managed through your deployment and provisioning process.

Client integration

Note

The Azure Data Explorer hosting integration does not include a corresponding client integration package. Use the Kusto .NET SDK directly in your application to query data.

Connect to Azure Data Explorer from your application

To connect to Azure Data Explorer from your application, use the connection string provided by Aspire:

var connectionString = builder.Configuration.GetConnectionString("analytics");
  
var kcsb = new KustoConnectionStringBuilder(connectionString)
    .WithAadAzureTokenCredentialsAuthentication(new DefaultAzureCredential());
  
using var client = KustoClientFactory.CreateCslQueryProvider(kcsb);

When running against the emulator, no authentication is required:

var connectionString = builder.Configuration.GetConnectionString("analytics");
var kcsb = new KustoConnectionStringBuilder(connectionString);
  
using var client = KustoClientFactory.CreateCslQueryProvider(kcsb);

Dashboard commands

When an Azure Data Explorer cluster resource is running, the Aspire dashboard provides commands to open the Kusto Explorer:

  • Open in Kusto Explorer (Desktop): Opens the desktop Kusto Explorer application (Windows only).
  • Open in Kusto Explorer (Web): Opens the web-based Kusto Explorer (Azure deployments only).

Connection string and properties

When you add an Azure Data Explorer resource to your application, the connection properties are made available to consuming resources. The following properties are available:

Cluster resource

Property Description
Uri The URI of the Azure Data Explorer cluster endpoint.

Database resource

Property Description
Uri The URI of the parent cluster endpoint (inherited from cluster).
DatabaseName The name of the database.

The connection string format is: Data Source=https://{cluster-uri};Initial Catalog={database-name}

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—the provisioning APIs generate Bicep for you. When you publish your app, the generated Bicep is output alongside the manifest file. When you add an Azure Data Explorer resource, the following Bicep is generated:

@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location
  
param principalId string
  
param principalName string
  
resource kusto 'Microsoft.Kusto/clusters@2024-04-13' = {
  name: take('kusto${uniqueString(resourceGroup().id)}', 22)
  location: location
  sku: {
    name: 'Dev(No SLA)_Standard_E2a_v4'
    tier: 'Basic'
    capacity: 1
  }
  properties: {
    enableAutoStop: true
  }
  tags: {
    'aspire-resource-name': 'kusto'
  }
}
  
resource analytics 'Microsoft.Kusto/clusters/databases@2024-04-13' = {
  name: 'analytics'
  location: location
  kind: 'ReadWrite'
  parent: kusto
}
  
resource kusto_principalAssignment 'Microsoft.Kusto/clusters/principalAssignments@2024-04-13' = {
  name: guid(kusto.id, principalId, 'AllDatabasesAdmin')
  properties: {
    principalId: principalId
    principalType: 'App'
    role: 'AllDatabasesAdmin'
  }
  parent: kusto
}
  
output kustoClusterUri string = kusto.properties.uri

The preceding Bicep provisions an Azure Data Explorer cluster with a dev/test SKU and a read-write database.

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, you can configure the cluster SKU, capacity, and more. The following example demonstrates how to customize the Azure Data Explorer resource:

var builder = DistributedApplication.CreateBuilder(args);
  
var kusto = builder.AddAzureKustoCluster("kusto")
    .ConfigureInfrastructure(infra =>
    {
        var cluster = infra.GetProvisionableResources()
            .OfType<KustoCluster>()
            .Single();
  
        cluster.Sku = new KustoSku
        {
            Name = KustoSkuName.StandardE8aV4,
            Tier = KustoSkuTier.Standard,
            Capacity = 2
        };
        cluster.IsAutoStopEnabled = false;
        cluster.Tags.Add("environment", "production");
    })
    .AddReadWriteDatabase("analytics");

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 GetProvisionableResources.
    • The KustoCluster is configured with a Standard SKU, 2-node capacity, and auto-stop disabled.

For more information, see Customize Azure resources. For the full list of configurable properties, see the Azure.Provisioning.Kusto API documentation.

Health checks

The Azure Data Explorer hosting integration automatically adds health checks for both cluster and database resources. The health check verifies that:

  • The cluster is reachable and responding to queries
  • When using a database, the database exists and is accessible

Health check status is displayed in the Aspire dashboard resource list.

See also