# Azure Data Explorer (Kusto)

<Image
  src={kustoIcon}
  alt="Azure Data Explorer logo"
  height={80}
  width={80}
  class:list={'float-inline-left icon'}
  data-zoom-off
/>

[Azure Data Explorer](https://azure.microsoft.com/services/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](https://www.nuget.org/packages/Aspire.Hosting.Azure.Kusto) NuGet package to your AppHost project.

<InstallPackage packageName="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:

```csharp title="C# — AppHost.cs"
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](/integrations/cloud/azure/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:

```csharp title="C# — AppHost.cs"
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:

```csharp title="C# — AppHost.cs"
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:

```csharp title="C# — AppHost.cs"
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:

```csharp title="C# — AppHost.cs"
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](https://learn.microsoft.com/azure/data-explorer/kusto/api/netfx/about-the-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:

```csharp title="C# — Program.cs"
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:

```csharp title="C# — Program.cs"
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](https://learn.microsoft.com/azure/azure-resource-manager/bicep/overview), 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:

```bicep title="Generated Bicep — kusto.bicep"
@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:

```csharp title="AppHost.cs"
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](/integrations/cloud/azure/customize-resources/). For the full list of configurable properties, see the [Azure.Provisioning.Kusto](https://learn.microsoft.com/dotnet/api/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

- [Azure Data Explorer documentation](https://learn.microsoft.com/azure/data-explorer/)
- [Kusto Query Language (KQL) overview](https://learn.microsoft.com/azure/data-explorer/kusto/query/)
- [Kusto .NET SDK](https://learn.microsoft.com/azure/data-explorer/kusto/api/netfx/about-the-sdk)
- [Azure integration overview](/integrations/cloud/azure/overview/)