Azure DatabricksのDBFSにAzure Data Lake Storage Gen2 (ADLS Gen2)をマウント 手順

#概要
Azure Databricks の DBFS に ADLS Gen2 をマウントする手順をご紹介します。
マウントすると、Databricks 内の DBFS に /mntディレクトリ が作成され、いつでもアクセスができるようになります。

#目次
**1.** サービスプリンシパルの作成　**サービスプリンシバルの作成にはAzure ワークスペース内の所有者権限が必要になります**
**2.** 新しいクライアントシークレットの作成
**3.** ADLS Gen2へのアクセス権限の付与　**サービスプリンシバルの作成にはAzure ワークスペース内の所有者権限が必要になります**
**4.** ADLS Gen2をDBFSにマウント

#サービスプリンシパルの作成
Azure DatabricksのDBFSにAzure Data Lake Storage Gen2 (ADLS Gen2)をマウントするには、サービスプリンシパルの設定が必要になるため、サービスプリンシパルの作成を行います。
**サービスプリンシバルの作成にはAzure ワークスペース内の所有者権限が必要になります**

Azure Portal > Azure Active Directory > エンタープライズアプリケーションを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/e4d234c0-45bd-c16b-309c-88bf7fc1364b.png)

エンタープライズアプリケーション / すべてのアプリケーションが開く
新しいアプリケーションの作成　を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/09f30a65-b2f7-0f69-766f-290956c5a583.png)

Azure AD ギャラリーの参照が開く
以下の画像の赤枠をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/74369811-694b-afde-e7fc-39c8c1767292.png)

アプリケーションの追加　が開く
開発中のアプリケーション　作業中のアプリを登録して Azure AD と統合します　をクリック　（以下の画像の赤枠をクリック）> アプリの登録をクリック
ここからアプリの登録をしていきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/576bbb0a-4ee3-b3a0-f2f2-97011be0f445.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/78e4e386-184c-d6bf-cc6a-ea59d1d18bac.png)

アプリの登録 > 新規登録をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/eafb1ddf-d4f8-a70d-a231-41621b9b2a87.png)


アプリの登録を行っていく
**名前:**　apsnews-AAD
**サポートされているアカウントの種類:**　この組織ディレクトリのみに含まれるアカウント を指定
**リダイレクト URI (省略可能):**　Databricks の URL を入力　https://japaneast.azuredatabricks.net/ こちらの URL をコピー&ペースト

こちらの入力が終わったら**登録**をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/1774f8cb-83d0-3154-d669-ee0ba58a4e74.png)

アプリの登録が終わると、以下の画面に遷移する
登録後に表示される「アプリケーション(クライアント)ID」と「ディレクトリ(テナント)ID」はマウント時のパラメータとして必要になるため、コピーして控えておきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/5cdd46ac-b8a4-2f12-eebd-09044a63acaf.png)

#新しいクライアントシークレットの作成
証明書とシークレット > 新しいクライアントシークレット をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/0fd11e8d-3aa2-27c3-68ba-5992ddfc142d.png)
「説明」と「有効期限」を設定して「追加」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/ef1f525d-d3b7-5dfe-fc86-d6b9d90f7681.png)
作成されるとクライアントシークレットの文字列が表示される
この文字列は作成後最初の1回しか表示されないため、コピーして控えておく
クライアントシークレットもマウント時の必要パラメータとなる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/5c444d5b-6622-48a0-6dec-89906666d89c.png)

#ADLS Gen2へのアクセス権限の付与
ストレージアカウント > 作成したIAMアカウント > アクセス制御 (IAM) > ロールの割り当ての追加　をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/c284a076-b578-066d-97e4-8fb2dd54ce8f.png)

「役割」を「ストレージBLOBデータ共同作成者」に変更し、「次へ」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/24ff5144-00d1-d586-d655-1a928dd4e636.png)

以下の画面に遷移する
「サービスプリンシパルの作成」で作成したサービスプリンシパル:apsnews-AAD を選択して「次へ」をクリック　こちらで権限割り当ては完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/dd40767e-e0eb-9e87-7a05-d4b071e96122.png)

「ロールの割り当て」タブをクリックするとサービスプリンシパルに割り当てられた権限が確認できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/2fb45701-371b-c3cf-b445-05561a5a2b93.png)

#ADLS Gen2をDBFSにマウント
DBFSにADLS Gen2をマウントするには、下記のスクリプトを使用
(ストレージ、サービスプリンシパル情報、マウント先DBFSディレクトリは作成したリソースに合わせて変更する)

**ストレージ情報**
ストレージアカウント名:ADLS Gen2 アカウント名を入力
ファイルシステム名:ADLS Gen2に追加したコンテナ名を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091796/31b14273-99a2-1663-7948-9e11e225a054.png)

**サービスプリンシパル情報**
アプリケーション(クライアント)ID:サービスプリンシバルの作成　Azure AD > アプリの登録から保持していたアプリケーション(クライアント)ID を入力
ディレクトリ(テナント)ID:サービスプリンシバルの作成　Azure AD > アプリの登録から保持していたディレクトリ(テナント)ID を入力
クライアントシークレット:サービスプリンシバルの作成　Azure AD > クライアントシークレットでコピーした値を入力

**マウントするDBFSディレクトリ**
mount_point_adls = "/mnt/mnt/my_adls2_fs

こちらのスクリプトを Databricks 上で実行すると、マウントが完了
Databricks > Data > DBFS からマウントした ADLS Gen2 が確認できる

```
# ストレージ情報
storage_alds = {
    "account": "{ストレージアカウント名}",
    "file_system": "{ファイルシステム名}"
}

# サービスプリンシパル情報
service_principal = {
  "client_id": "{アプリケーション(クライアント)ID}",
  "directory_id": "{ディレクトリ(テナント)ID}",
  "client_secret": "{クライアントシークレット}"
  # "client_secret": dbutils.secrets.get(scope="{スコープ名}", key="{キー名}") # Key Vault使用時
}

# マウントするDBFSディレクトリ
mount_point_adls = "/mnt/{マウント先ディレクトリ}"

try:
  # マウント状態のチェック
  mount_dir = mount_point_adls
  if mount_dir[-1] == "/":
    mount_dir = mount_dir[:-1]
  if len(list(filter(lambda x: x.mountPoint == mount_dir, dbutils.fs.mounts()))) > 0:
    print("Already mounted.")
    mounted = True
  else:
    mounted = False

  if not mounted:
    # Azure Data Lake Storage Gen2のマウント
    configs = {
      "fs.azure.account.auth.type": "OAuth",
      "fs.azure.account.oauth.provider.type": "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider",
      "fs.azure.account.oauth2.client.id": service_principal["client_id"],
      "fs.azure.account.oauth2.client.secret": service_principal["client_secret"],
      "fs.azure.account.oauth2.client.endpoint": "https://login.microsoftonline.com/{directory_id}/oauth2/token".format(**service_principal)
    }

    mounted = dbutils.fs.mount(
      source="abfss://{file_system}@{account}.dfs.core.windows.net/".format(**storage_alds),
      mount_point=mount_point_adls,
      extra_configs=configs
    )

except Exception as e:
    raise e

"mounted: {}".format(mounted)
```