> For the complete documentation index, see [llms.txt](https://documentation.alluxio.io/ee-ai-en/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.alluxio.io/ee-ai-en/ai-3.8-15.1.x/ufs/azure-blob-store.md).

# Azure Blob Storage

This guide describes how to use [Azure Blob Storage](https://azure.microsoft.com/products/storage/blobs/) or [Azure Data Lake Storage Gen2](https://learn.microsoft.com/azure/storage/blobs/data-lake-storage-introduction) as an Alluxio under file system (UFS).

Alluxio includes two ABFS implementations:

* **ABFS v2** uses the Azure Blob SDK and supports both hierarchical and flat namespace accounts. Use v2 for new deployments.
* **ABFS v1** uses `hadoop-azure`. It is retained for compatibility with existing deployments and is not recommended for new deployments.

{% hint style="warning" %}
ABFS v1 is still the default to avoid changing existing mounts during an upgrade. Set `alluxio.underfs.abfs.sdk.version=2` explicitly to use the recommended ABFS v2 implementation.
{% endhint %}

## Prerequisites

Before creating a mount, collect the following information:

| Placeholder          | Description                                     |
| -------------------- | ----------------------------------------------- |
| `<AZURE_ACCOUNT>`    | Azure storage account name                      |
| `<AZURE_CONTAINER>`  | Existing container to mount                     |
| `<AZURE_DIRECTORY>`  | Optional directory within the container         |
| `<AZURE_ACCESS_KEY>` | Account key, if using shared-key authentication |

Check whether the storage account uses a hierarchical namespace:

```shell
az storage account show --name <AZURE_ACCOUNT> --query isHnsEnabled --output tsv
```

The command returns `true` for an Azure Data Lake Storage Gen2 account and `false` for a flat namespace Blob Storage account.

## ABFS v2 Quick Start

### Enable ABFS v2

`alluxio.underfs.abfs.sdk.version` is a cluster-wide property. Configure it before creating the mount; it cannot be set as a mount option.

{% tabs %}
{% tab title="Kubernetes (Operator)" %}
Add the property to the `AlluxioCluster` custom resource:

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  properties:
    alluxio.underfs.abfs.sdk.version: "2"
```

Apply the updated custom resource and wait for the Alluxio pods to restart.
{% endtab %}

{% tab title="Docker / Bare-Metal" %}
Add the property to `conf/alluxio-site.properties` on every Alluxio node, then restart the cluster:

```properties
alluxio.underfs.abfs.sdk.version=2
```

{% endtab %}
{% endtabs %}

### Choose the Mount URI

Use the URI that matches the account namespace:

| Account type                       | UFS URI                                                                            |
| ---------------------------------- | ---------------------------------------------------------------------------------- |
| Hierarchical namespace (ADLS Gen2) | `abfs://<AZURE_ACCOUNT>.dfs.core.windows.net/<AZURE_CONTAINER>/<AZURE_DIRECTORY>`  |
| Flat namespace (Blob Storage)      | `abfs://<AZURE_ACCOUNT>.blob.core.windows.net/<AZURE_CONTAINER>/<AZURE_DIRECTORY>` |

For new v2 mounts, place the container name in the path as shown above. Use the `abfs://` scheme for both account types; v2 always connects over HTTPS.

### Configure Authentication

Choose one authentication method for each mount:

* **Managed identity:** Recommended when Alluxio runs on Azure. Do not set a credential property. To select a specific user-assigned managed identity, set `alluxio.underfs.abfs.msi.client.id` to its client ID.
* **Service principal:** Recommended for cross-tenant or non-Azure deployments. Configure the three properties shown below.
* **SAS token:** Recommended for temporary or limited access. Set `alluxio.underfs.abfs.sas.token`. The mount does not refresh an expired token automatically.
* **Account key:** Intended for testing and simple setups. Set `alluxio.underfs.abfs.shared.key`. Managed identity or a service principal is preferred for production.

For service principal authentication, configure:

```properties
alluxio.underfs.abfs.oauth.tenant.id=<TENANT_ID>
alluxio.underfs.abfs.oauth.client.id=<CLIENT_ID>
alluxio.underfs.abfs.oauth.client.secret=<CLIENT_SECRET>
```

Do not configure multiple authentication methods at the same configuration level. Per-mount options take precedence over cluster-wide properties.

### Create the Mount

The following example uses an account key. For production on Azure, managed identity is recommended so that credentials do not need to be stored in configuration.

For the general mount mechanism and `UnderFileSystem` CR fields, see [Underlying Storage](/ee-ai-en/ai-3.8-15.1.x/ufs.md#basic-mount-setup).

{% tabs %}
{% tab title="Kubernetes (Operator)" %}
Create an `UnderFileSystem` custom resource:

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: UnderFileSystem
metadata:
  name: alluxio-abfs
  namespace: alx-ns
spec:
  alluxioCluster: alluxio-cluster
  path: abfs://<AZURE_ACCOUNT>.dfs.core.windows.net/<AZURE_CONTAINER>/<AZURE_DIRECTORY>
  mountPath: /abfs
  mountOptions:
    alluxio.underfs.abfs.shared.key: <AZURE_ACCESS_KEY>
```

Apply and verify the mount:

```shell
kubectl apply -f ufs.yaml
kubectl get ufs -n alx-ns
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}
Create and verify the mount:

```shell
bin/alluxio mount add \
  --path /abfs \
  --ufs-uri abfs://<AZURE_ACCOUNT>.dfs.core.windows.net/<AZURE_CONTAINER>/<AZURE_DIRECTORY> \
  --option alluxio.underfs.abfs.shared.key=<AZURE_ACCESS_KEY>
bin/alluxio mount list
```

{% endtab %}
{% endtabs %}

The examples use the `dfs` endpoint. Replace it with `blob` when mounting a flat namespace account.

## ABFS v2 Advanced Setup

### Multipart Upload

ABFS v2 uploads large files in parallel. The defaults are suitable for most deployments. Tune these properties only when larger objects or a different concurrency limit is required:

| Property                                               | Default | Purpose                             |
| ------------------------------------------------------ | ------- | ----------------------------------- |
| `alluxio.underfs.abfs.multipart.upload.partition.size` | `16MB`  | Size of each upload part            |
| `alluxio.underfs.abfs.multipart.upload.threads`        | `64`    | Concurrent upload threads per mount |
| `alluxio.underfs.abfs.multipart.upload.buffer.number`  | `64`    | Buffered upload parts per process   |

* The default part size supports objects up to approximately 780 GiB. Increase `alluxio.underfs.abfs.multipart.upload.partition.size` for larger objects.
* Configure the partition size and buffer count as cluster properties, not mount options.

### Required Permissions

Permissions depend on the authentication method:

| Authentication    | Read-only mount             | Writable mount                  |
| ----------------- | --------------------------- | ------------------------------- |
| Managed identity  | `Storage Blob Data Reader`  | `Storage Blob Data Contributor` |
| Service principal | `Storage Blob Data Reader`  | `Storage Blob Data Contributor` |
| SAS token         | `r`, `l`                    | `r`, `w`, `d`, `l`              |
| Account key       | No additional configuration | No additional configuration     |

For managed identity and service principal authentication, assign the Azure role to the mounted container or storage account. An account key grants broad access to the storage account, so managed identity or a service principal is preferred for production.

To allow extended-attribute changes, set:

```properties
alluxio.underfs.xattr.change.enabled=true
```

Hierarchical namespace accounts require no additional permissions beyond normal write access. For flat namespace accounts, configure the following additional permissions:

| Authentication    | Additional permission                                                         |
| ----------------- | ----------------------------------------------------------------------------- |
| Managed identity  | `Storage Blob Data Owner`, or a custom role with `tags/read` and `tags/write` |
| Service principal | `Storage Blob Data Owner`, or a custom role with `tags/read` and `tags/write` |
| SAS token         | Add the `t` permission                                                        |
| Account key       | No additional configuration                                                   |

### Private Endpoints

By default, Alluxio verifies that the endpoint in the mount URI matches the account namespace. Keep this validation enabled whenever possible.

If a flat namespace account is reachable only through a Blob private endpoint and the `dfs` endpoint is intentionally unavailable, set the following property:

```properties
alluxio.underfs.abfs.namespace.check.enforced=false
```

When validation is disabled, ensure that the URI uses `blob.core.windows.net` for a flat namespace account or `dfs.core.windows.net` for a hierarchical namespace account.

### Delete Blob Snapshots

Deleting a blob that has snapshots fails by default. Set `alluxio.underfs.abfs.delete.snapshots=true` only when Alluxio should also delete those snapshots.

## ABFS v1 (Legacy)

{% hint style="warning" %}
ABFS v1 is not recommended for new deployments. Use this section only to maintain an existing v1 mount.
{% endhint %}

ABFS v1 uses the `hadoop-azure` driver and is selected by the current default, `alluxio.underfs.abfs.sdk.version=1`. The container name is placed before `@` in the URI, and authentication uses `fs.azure.*` properties:

```
abfs://<AZURE_CONTAINER>@<AZURE_ACCOUNT>.dfs.core.windows.net/<AZURE_DIRECTORY>/
fs.azure.account.key.<AZURE_ACCOUNT>.dfs.core.windows.net=<AZURE_ACCESS_KEY>
```

The `abfss://` scheme is also supported by v1. Do not use v1 URI or credential syntax when creating a new v2 mount.

## WASB (Legacy)

{% hint style="danger" %}
The Azure Storage Java SDK used by WASB was retired by Microsoft. Do not create new `wasb://` or `wasbs://` mounts.
{% endhint %}

Existing WASB mounts use the following format:

```
wasbs://<AZURE_CONTAINER>@<AZURE_ACCOUNT>.blob.core.windows.net/<AZURE_DIRECTORY>/
fs.azure.account.key.<AZURE_ACCOUNT>.blob.core.windows.net=<AZURE_ACCESS_KEY>
```
