Databricks Unity Catalog 外部ロケーションと資格情報の登録 (Azure)


# はじめに

外部の場所とストレージの資格情報を使用すると、ユーザーに代わって Unity Catalog でクラウド テナントのデータの読み取りと書き込みを行うことができます。今回はAzure環境での実践編です。[AWS編はこちら](https://qiita.com/maroon-db/items/6f3dee8a8ebd863989a6)をご覧ください。

またUnityCatalog自体の設定などはこちらをご覧ください。
https://qiita.com/maroon-db/items/57cee03cef202c839b94

外部ロケーションについてもっと詳しく知りたい方は、こちらの[マニュアル](https://learn.microsoft.com/ja-jp/azure/databricks/data-governance/unity-catalog/manage-external-locations-and-credentials)をご覧ください。

# 要件

- ストレージの資格情報を作成するには、Azure Databricks のアカウント管理者である必要があります。ストレージの資格情報を作成するアカウント管理者は、この資格情報に対するアクセス許可を管理するように、所有権を別のユーザーまたはグループに委任できます。
- 外部の場所を作成するには、メタストア管理者か、CREATE EXTERNAL LOCATION 特権を持つユーザーである必要があります。
- Unity カタログでは、外部の場所の Azure Data Lake Storage Gen2 のみがサポートされます。

# Azure側の設定

外部ロケーションと資格情報の登録のため、Azure側でまずは**ADLSストレージアカウントとコンテナ**、そしてそれにアクセスするために**AzureマネージドID**の作成を行います。資格情報はAzureマネージドID以外にもサービスプリンシパルもサポートしてますが、AzureマネージドIDを強く推奨しております。その理由はこちらです。
- ストレージ ファイアウォールによって保護されている Azure Data Lake Storage Gen2 アカウントに接続できます。
- マネージド ID では、資格情報を維持したり、シークレットをローテーションしたりする必要がありません。

## 1. ADLS gen2ストレージアカウントの作成

今回は、以下の通り新規ストレージアカウントを作成しました。

- ストレージアカウント名： ucexternal2
- 地域： Japan East
- パフォーマンス： Standard
- 冗長性： GRS 
- ADLS gen2(階層型名前空間): 有効

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/c49f1b2b-1391-43a8-ad53-6ae8474935f9.png)

次のページに進み**階層型名前空間を有効にする**にチェックを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/9fcddcc3-a76b-6fb5-2b67-6acd0ad1ae3a.png)

残りはデフォルト値のままで作成。

## 2. 新規ストレージコンテナを作成します。

次に作成したストレージアカウント上にコンテナを作成します。

- コンテナ名：　ex-container

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/dcc5bfa8-7132-ffe1-1581-7b522fc0cde0.png)

最後にコンテナーの ADLSv2 URI を書き留めます。これは次の形式です。
```abfss://<container-name>@<storage-account-name>.dfs.core.windows.net```

今回のケースだとこちらになります。
```abfss://ex-container@ucexternal2.dfs.core.windows.net```


## 3. マネージドIDを作成してストレージにアクセスできるようにする

次に作成したストレージコンテナにアクセス出来るようにするため、マネージドIDコネクタを作成して登録します。
参考マニュアルは[こちら](https://learn.microsoft.com/ja-jp/azure/databricks/data-governance/unity-catalog/azure-managed-identities)です。

### ステップ１. Azure Databricks アクセス コネクタを作成する
Azure Databricks アクセス コネクタはファースト パーティーの Azure リソースであり、マネージド ID を Azure Databricks アカウントに接続できます。 Azure Databricks アカウント管理者は、アクセス コネクタに割り当てられたマネージド ID を、Unity Catalog メタストアなどの Azure Databricks リソースに委任できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/7e5be3fb-3c93-c68f-05dc-c954f0ffabc3.png)

1). リソース グループの共同作成者または所有者として Azure portal にログインします。
新規でリソースグループを作成して、ストレージアカウントと別のリソースグループを用意することも可能です。ただしリソース グループは、接続先の**ストレージ アカウントと同じリージョン**に存在する必要があります。

今回はストレージアカウント(ucexternal2)と同じリソースグループである`external-rg`を利用します。

2). [+ 作成] または [新しいリソースを作成] をクリックします。
3). [テンプレートのデプロイ]で検索し、作成をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/4847c33e-4b11-2546-11bb-cb81f321606e.png)

4). [エディターで独自のテンプレートをビルド] をクリックします。
5). このテンプレートをコピーして貼り付けます。

```
{
   "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
   "contentVersion": "1.0.0.0",
   "parameters": {
      "connectorName": {
         "defaultValue": "testConnector",
         "type": "String",
         "metadata": {
               "description": "The name of the Azure Databricks Access Connector to create."
         }
      },
      "accessConnectorRegion": {
         "defaultValue": "[resourceGroup().location]",
         "type": "String",
         "metadata": {
               "description": "Location for the access connector resource."
         }
      },
      "enableSystemAssignedIdentity": {
         "defaultValue": true,
         "type": "bool",
         "metadata": {
               "description": "Whether the system assigned managed identity is enabled"
         }
      }
   },
   "resources": [
      {
         "type": "Microsoft.Databricks/accessConnectors",
         "apiVersion": "2022-04-01-preview",
         "name": "[parameters('connectorName')]",
         "location": "[parameters('accessConnectorRegion')]",
         "identity": {
               "type": "[if(parameters('enableSystemAssignedIdentity'), 'SystemAssigned', 'None')]"
         }
      }
   ]
}
```

6). [基本] タブで、以下のフィールドの値をそのまま使用するか、選択または入力します。

- [サブスクリプション]: これは、Azure Databricks アクセス コネクタが作成される Azure サブスクリプションです。 既定値は、現在使用している Azure サブスクリプションです。 テナント内の任意のサブスクリプションにすることができます。
- [リソース グループ]: これは、接続先のストレージ アカウントと同じリージョン内のリソース グループである必要があります。
- [リージョン]: これは、接続先のストレージ アカウントと同じリージョンである必要があります。
- [コネクタ名]: コネクタ リソースの目的を示す名前を入力します。
- [コネクタ リージョンへのアクセス]: コネクタ リソースをリソース グループと同じリージョンにデプロイするには、既定値 [resourceGroup().location] をそのまま使用します。 別のリージョンの値も入力できますが、Databricks では、コネクタ リージョンとリソース グループ リージョンは、接続先のストレージ アカウントと同じにすることをお勧めします。
- [システム割り当て ID を有効にする]: 既定値 true をそのまま使用します。

7). [次へ: 確認と作成]> をクリックします。
8). Create をクリックしてください。
デプロイが成功すると、Azure Databricks アクセス コネクタがシステム割り当てのマネージド ID でデプロイされます。
9). デプロイが完了したら、 [リソースに移動] をクリックします。

10). リソース ID を記録しておきます。

リソース ID の形式は次のとおりです。
```/subscriptions/12f34567-8ace-9c10-111c-aea8eba12345c/resourceGroups/<resource_group>/providers/Microsoft.Databricks/accessConnectors/<connector-name>```

### ステップ２. マネージド ID にストレージ アカウントへのアクセスを許可する

1. 作成したストレージアカウントの画面に移動します。(ucexternal2)
1. 左メニューの[アクセス制御 (IAM)] に移動して、[+ 追加] をクリックし、[ロールの割り当ての追加] を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/c394aafd-6010-0cf0-208f-d554d0ebb51f.png)

1. [ストレージ BLOB データ共同作成者] ロールを選択し、[次へ] をクリックします。
1. [アクセスの割り当て先] で [マネージド ID] を選択します。
1. [+ メンバーの選択] をクリックし、[すべてのシステム割り当てマネージド ID] を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/84e0937f-f412-e8f7-9976-1fea0c393e7b.png)

1. コネクタ名を検索して選択し、[確認と割り当て] をクリックします。


# Databricks側の設定

それでは準備が整いましたので、Databricks側の設定に移りたいと思います。
Azure側で作成したコンテナへのURIとAzureマネージドIDコネクタの情報をメモしておきます。

作成したコンテナーの ADLSv2 URI を書き留めます。これは次の形式です。
```abfss://<container-name>@<storage-account-name>.dfs.core.windows.net/<metastore-name>```

作成したアクセス コネクタのリソース IDをメモしておきます。形式は以下の通りです。
`/subscriptions/12f34567-8ace-9c10-111c-aea8eba12345c/resourceGroups/<resource_group>/providers/Microsoft.D
atabricks/accessConnectors/<connector-name>`

## Step1. ストレージ資格情報を作成する

ワークスペースにログインし、「データ」メニューを開き、「ストレージ資格情報」から「資格情報を作成」にて、資格情報を作成します。

資格情報名と、先ほどメモしたAzureリソースIDを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/c3aa23c7-c1d3-7933-14c6-9e39433f00da.png)

必要に応じて権限を付与します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/628bbd88-00f1-d52b-b7de-984ed3273db0.png)


## Step2. 外部の格納場所（外部ロケーション）を作成する

次に外部ロケーションを登録します。
同じく「データ」メニューを開き、「外部の格納場所」から「格納場所を作成」をクリックします。

外部の格納場所名と、ストレージのURLとアクセスするための資格情報を選択します。
URLには、`/path` とサブディレクトリーも指定可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/a2924bd7-2a73-01e3-23fd-c18e317ce75d.png)

ロケーションにも権限付与が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/8596bc2e-422e-20ab-76aa-4d6e6bdb32ae.png)

接続テストボタンをクリックし検証します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/870fd86e-802b-c681-88b0-144e30265191.png)


# さいごに

以上でストレージの外部ロケーションと資格情報の登録が完了しました。
あとは、外部テーブルとしてこちらのパスを指定したり、[カタログやスキーマレベルでストレージ先を変更する](https://qiita.com/maroon-db/items/a9e6aabcbcb5c3a36633)などが可能になります。