Azure Databricks: 3-1. DBFSにBlob Storageをマウント

# ストレージアカウントの作成
**※既存のBlob Storageをマウントする場合は「[DBFSにBlob&nbsp;Storageをマウント](#DBFSにBlob&nbsp;Storageをマウント)」から操作を実行します**

Azureポータルの「リソースの作成」をクリックし、一覧から「ストレージアカウント」を選択して作成を開始します。
![img03-0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/1e84ef7a-3084-8068-f48a-78085676a4f4.png)
作成に必要な情報を入力します。設定内容は任意ですが、「リソースグループ」と「場所」はAzure Databricksと同じものを指定します。設定が出来たら「次: 詳細 >」をクリックします。
![img03-0002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/46a89a03-dc96-c55c-d780-28374fdfe682.png)
「詳細」設定に関してはデフォルトのままで、「確認および作成」をクリックします。
![img03-0003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/1050fbbd-fb7c-fa64-7671-16b184912422.png)
設定内容に誤りがないことを確認して、「作成」をクリックします。
![img03-0004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/db2f17d1-39e3-9ced-a0ad-016c07f1fe19.png)
しばらく待機し、作成が完了したら作成したリソースに移動します。
![img03-0005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/30b97ba3-e752-57fd-b72e-aca2836235aa.png)
マウント時のパラメータとしてストレージアカウントの「アクセスキー」必要となるため、メニューの「アクセスキー」を開いて、「key1」、「key2」いずれかの「キー」をコピーして控えておきます。
![img03-0006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/5c241502-97b0-f7f4-9b44-c217f54241b3.png)

# Blobコンテナーの作成とファイルの配置
ストレージアカウントのメニューの「概要」に戻り、「サービス」の「BLOB」をクリックします。
![img03-0007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/de858c14-55d1-4d17-e0bb-32d14d7d6c7b.png)
「+コンテナー」をクリックして、「名前」を任意のコンテナ名、「パブリックアクセスレベル」を「プライベート」としてコンテナを作成します。
![img03-0008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/4a3bee82-b207-7108-a5d9-15c4d828743c.png)
ファイルを配置するため作成したコンテナーをクリックし、コンテナーを開きます。
![img03-0009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/c4751197-8ada-831c-22b4-76fe7ba5c00b.png)
「↑アップロード」をクリックして、ファイルを選択し、「アップロード」をクリックします。
![img03-0010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/337b6aa4-a4df-1b76-f004-84b0cd8147d5.png)
アップロードが完了するとコンテナーにファイルのリストが表示されます。
![img03-0011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/a24ea7a5-42c5-d119-1626-0db232ab1ccd.png)

# DBFSにBlob&nbsp;Storageをマウント
## Blobコンテナーのマウント
Blob Storageのマウントは下記のスクリプトを使用します。(ストレージ情報、マウント先DBFSディレクトリは作成したリソースに合わせて変更してください。)  
一度マウントすると、Clusterを停止、変更してもマウント状態が維持されます。
マウントされた状態で再度操作を実行するとエラーが発生するため、マウント状態をチェックするか、スクリプトをコメントアウトしてエラーの回避します。

```python:Cmd&nbsp;1
# Blob Storage情報
storage = {
  "account": "{ストレージアカウント名}",
  "container": "{Blobコンテナ名}",
  "key": "{ストレージアカウントキー}"
}

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

try:
  # マウント状態のチェック
  mount_dir = mount_point
  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

  # Blob Storageのマウント
  if not mounted:
    source = "wasbs://{container}@{account}.blob.core.windows.net".format(**storage)
    conf_key = "fs.azure.account.key.{account}.blob.core.windows.net".format(**storage)

    mounted = dbutils.fs.mount(
      source=source,
      mount_point = mount_point,
      extra_configs = {conf_key: storage["key"]}
    ) 

except Exception as e:
  raise e
  
"mounted: {}".format(mounted)
```
![img03-0012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/511c61a9-322f-de8e-7574-1024bc2cc9fa.png)
下記スクリプトでマウントされているディレクトリを確認します。
Blob Storageをマウントしたディレクトリがリストで確認できます。

```python:Cmd&nbsp;2
# mount_point = "/mnt/{マウント先ディレクトリ}"
display(dbutils.fs.mounts())
```
![img03-0013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/d5f17d0b-2bff-8727-6d30-5391ae449067.png)

## マウントされたディレクトリの確認
下記スクリプトを使用してマウントしたディレクトリ内のファイルを表示します。  
※ マウントしたディレクトリにファイルが存在しないとエラーが発生します。

```python:Cmd&nbsp;3
# mount_point = "/mnt/{マウント先ディレクトリ}"
display(dbutils.fs.ls(mount_point))
```
![img03-0014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/737806d2-c34c-975d-10f7-171729c9d85c.png)

## Blobコンテナーのアンマウント
ストレージのマウントを解除する場合は下記スクリプトを使用します。

```python:Cmd&nbsp;4
# mount_point = "/mnt/{マウント先ディレクトリ}"
dbutils.fs.unmount(mount_point)
```
![img03-0015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/5b8eaca6-ec51-58c8-54e7-963d07017bd1.png)

# 秘密情報の安全な管理
秘密情報をスクリプト上に記載することはセキュリティ上の懸念となります。  
ストレージアカウントキーのような秘密情報を安全に管理するため、Azure Key Vaultの使用が推奨されます。
## Azure Key Vaultのキーコンテナー作成
Azureポータルの「リソースの作成」で「Key Vault」を検索し、検索候補の「Key Vault」をクリックして作成を開始します。
![img03-0016.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/a7e48361-60e8-5972-5328-22dfd691bfe8.png)
「キーコンテナーの作成」に必要な情報を入力します。「名前」は任意の名称、「リソースグループ」、「場所」Azure Databricksと同じものを指定します。その他の設定はデフォルトのままとします。
![img03-0017.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/32d26798-0da8-0abc-ad1a-d2fcd5c34fb6.png)
作成が完了したらリソースに移動します。
![img03-0018.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/07714f2a-3f22-2c69-b37a-33805f6192a0.png)

## キーの登録
作成したキーコンテナーにストレージアカウントキーを登録します。
作成したリソースのメニューから「シークレット」を開いて「+生成/インポート」をクリックします。
![img03-0019.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/2cfab006-77f7-6415-8f20-0e5f9a852b24.png)
「アップロードオプション」を「手動」として、「名前」、「値」に任意の名称とストレージアカウントキーを入力し、「作成」をクリックします。
![img03-0020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/f3fca0f0-068b-5f54-dff2-03260ab6daa6.png)

## DatabricksにAzure Key Vaultを登録
キーコンテナーのメニューから「プロパティ」を開き、「DNS名」と「リソースID」をコピーして控えておきます。
Databricksワークスペースのホーム画面を開き、URLに「#secrets/createScope」を追加して「Create Secret Scope」のページを開きます。
「Scope Name」に任意のスコープ名を入力し、「DNS Name」、「Resource ID」に作成したキーコンテナーの「プロパティ」で取得した「DNS名」、「リソースID」を入力します。
Databricks作成時にStandard Planを選択した場合、「Manage Principal」は「All Users」のみ選択できます。
入力したスコープ名はキーの取得に必要となるため控えておきます。
![img03-0021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/6a4ca0b2-392a-65d5-59c7-a717b7e0e302.png)
Notebookを開き、下記のスクリプトでスコープのリストを確認します。
スコープが登録されていると、登録したスコープがリストにあることが確認できます。

```python:Cmd1
display(dbutils.secrets.listScopes())
```
![img03-0022.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/acaf2e70-ef5d-1f53-a5e4-ded7263c5936.png)
BlobコンテナーのマウントにKey Vaultのキーを使用する場合は、Blob Storageの情報を下記のように書き換えます。

```python
# Blob Storage情報
storage = {
  "account": "{ストレージアカウント名}",
  "container": "{Blobコンテナ名}",
  # "key": "{ストレージアカウントキー}"
  "key": dbutils.secrets.get(scope="{スコープ名}", key="{シークレット名}")
}
```



# 参考
- [Databricks Documentation - Data Sources - Azure Blob Storage](https://docs.azuredatabricks.net/spark/latest/data-sources/azure/azure-storage.html)
- [クイックスタート：Azureポータルを使用してAzure Key Vaultから秘密を設定および取得する](https://docs.microsoft.com/en-us/azure/key-vault/quick-create-portal)