Azure AD のアプリ登録(サービス プリンシパル)を作れない――そんな制約下でも、Databricks から Azure Storage に安全かつ実用的にアクセスする方法は複数あります。本記事では「やってはいけない落とし穴」と「すぐ使える手順」をセットで解説し、さらに Unsupported Azure Scheme: abfss エラーの原因切り分けと解決策まで網羅します。
Databricks をアプリ登録なしで Azure Storage に接続する方法
前提として、Databricks から Azure Storage(Blob/ADLS Gen2)へ接続するには以下のどれかの認証方式を選びます。ここではアプリ登録を作らずに済むものだけを扱います。
選択肢の比較(要約)
| 方法 | 概要 | 主な手順/ポイント |
|---|---|---|
| Azure AD パススルー認証 | Databricks が Azure AD(Microsoft Entra ID)のユーザー資格情報を引き継ぎ、ストレージの操作に利用。 | 1. 管理者に「Credential Passthrough(AAD パススルー)」を有効化してもらう 2. パススルー対応のクラスタで実行(一般にシングルユーザー/標準クラスタ) 3. ノートブック側の追加設定は最小で OK( spark.read 等で直接アクセス) |
| SAS トークン | ストレージ側で発行する一時トークンで読み書きする。細かな権限・期限を指定可能。 | 1. ポータルや CLI で SAS を発行(必要最小限の権限・短めの有効期限) 2. SAS は Databricks Secrets に保存し、コードから参照 3. 例: wasbs:// または abfss:// でマウント/直アクセス |
| ストレージ アクセスキー | 最も手軽だが、キー流出リスクが高い。検証・一時用途に限定。 | 1. アクセスキーを Secret に保存(ハードコーディング禁止) 2. 例: fs.azure.account.key.<account>.dfs.core.windows.net を設定 |
| マネージド ID(Managed Identity, MI) | ワークスペース/クラスター/Access Connector に割り当てた MI を使う。アプリ登録なしで RBAC 管理。 | 1. ストレージに Storage Blob Data Contributor 等を付与 2. ADLS Gen2(HNS 有効)なら abfss:// を使用3. 例: fs.azure.account.auth.type.<account>.dfs.core.windows.net=OAuth + MSI トークンプロバイダー |
補足:ストレージを Databricks にマウントすると DBFS の /mnt/... として扱えます。マウントせずにスキーム URL(wasbs:// / abfss://)で読み書きしても構いません。いずれの方法でも資格情報は必ず Databricks Secrets(できれば Key Vault 連携スコープ)に保存し、ノートブックに直書きしないでください。
シナリオ別のおすすめ
| シナリオ | 推奨方式 | 理由 |
|---|---|---|
| 個人/小規模チームの開発環境 | SAS トークン | 短期・最小権限で回せる。発行・廃止が簡単。 |
| 本番環境(ユーザー単位の権限制御が必要) | Azure AD パススルー | ユーザーの AAD 権限でアクセス。棚卸し・監査が明快。 |
| 本番環境(ワークロード単位で権限分離) | マネージド ID | アプリ登録不要で RBAC。秘密情報の運用を簡略化。 |
| ネットワーク制限が厳格(Private Endpoint 等) | マネージド ID or パススルー | 資格情報を配布せずに到達性と権限を制御しやすい。 |
| 検証・短期 PoC | アクセスキー(強い注意) | 最短で接続。ただし流出リスクが高く速やかに廃止すること。 |
実装手順(コピペで始められる最低限の設定例)
Azure AD パススルー認証(Credential Passthrough)
- 管理者にワークスペースで Credential Passthrough を有効化してもらい、対応クラスタ(シングルユーザー/標準)を用意。
- ユーザー/グループに対し、対象コンテナーやフォルダーに必要な RBAC/ACL を付与。
- ノートブックから通常の読み書きを実行。
# 例:マウントせずに直接読み込み(ADLS Gen2)
df = spark.read.parquet("abfss://@.dfs.core.windows.net/path/to/parquet")
df.write.mode("overwrite").parquet("abfss://@.dfs.core.windows.net/out/")
SAS トークン
- ストレージ アカウント/コンテナーで SAS を発行(読み取りのみなら
r、書き込みならrw等、権限を最小化)。 - Databricks Secrets に保存。
- マウント or 直接アクセス。
# 例:Gen2(abfss)で直接アクセス(推奨:マウント不要)
sas = dbutils.secrets.get(scope="storage", key="my-sas")
spark.conf.set("fs.azure.sas...dfs.core.windows.net", sas)
df = spark.read.csv("abfss://@.dfs.core.windows.net/data/input.csv", header=True)
# 例:Blob(wasbs)をマウントしてアクセス
sas = dbutils.secrets.get(scope="storage", key="my-sas")
configs = {"fs.azure.sas...blob.core.windows.net": sas}
dbutils.fs.mount(
source="wasbs://@.blob.core.windows.net",
mount_point="/mnt/myblob",
extra_configs=configs
)
display(dbutils.fs.ls("/mnt/myblob"))
ストレージ アクセスキー(検証限定)
- アクセスキーを Secret に保存。
- ABFS(Gen2)または WASBS(Blob)で設定して利用。
# Gen2(abfss)でアクセスキーを使う
key = dbutils.secrets.get(scope="storage", key="account-key")
spark.conf.set("fs.azure.account.key..dfs.core.windows.net", key)
df = spark.read.format("parquet").load("abfss://@.dfs.core.windows.net/data")
# Blob(wasbs)でアクセスキー
key = dbutils.secrets.get(scope="storage", key="account-key")
spark.conf.set("fs.azure.account.key..blob.core.windows.net", key)
dbutils.fs.ls("wasbs://@.blob.core.windows.net/")
マネージド ID(Managed Identity)
- 対象の MI(ワークスペース/クラスター/Access Connector 等)に、ストレージ側で Storage Blob Data Contributor 以上のロールを付与(アカウントまたはコンテナー)。
- ADLS Gen2(HNS 有効)なら
abfss://を使用。 - システム割り当て MI なら追加 ID 指定は不要。ユーザー割り当て MI はクライアント ID を指定。
# ABFS(Gen2) + MI(システム割り当て)
spark.conf.set("fs.azure.account.auth.type..dfs.core.windows.net", "OAuth")
spark.conf.set("fs.azure.account.oauth.provider.type", "org.apache.hadoop.fs.azurebfs.oauth2.MsiTokenProvider")
df = spark.read.parquet("abfss://@.dfs.core.windows.net/data")
# ABFS(Gen2) + MI(ユーザー割り当て)
spark.conf.set("fs.azure.account.auth.type..dfs.core.windows.net", "OAuth")
spark.conf.set("fs.azure.account.oauth.provider.type", "org.apache.hadoop.fs.azurebfs.oauth2.MsiTokenProvider")
spark.conf.set("fs.azure.account.oauth2.client.id", "")
注意:Blob(HNS 無効)で MI を使いたい場合はクラスタ Runtime/ドライバの実装差に影響を受けます。安定しない場合は SAS もしくは Gen2 への移行を検討してください。
マウントせずに「そのまま読む/書く」設計が安全
マウントは便利ですが、SAS のローテーションや設定の再現性に注意が必要です。SAS を再発行した場合、マウントを作り直す手間が発生します。運用を簡潔にするなら、以下のように毎回 Secret から資格情報を spark.conf.set して直接アクセスする方がスクリプトの可搬性・再現性が高くなります。
sas = dbutils.secrets.get(scope="storage", key="my-sas")
spark.conf.set("fs.azure.sas...dfs.core.windows.net", sas)
input_path = "abfss://@.dfs.core.windows.net/raw/"
output_path = "abfss://@.dfs.core.windows.net/curated/"
spark.read.parquet(input_path).repartition(4).write.mode("overwrite").parquet(output_path)
Databricks Secrets(Key Vault 連携推奨)
- 管理者が Key Vault バックド Secret Scope を作成。
- 発行した SAS/アクセスキーを Key Vault に保存(アクセス制御を限定)。
- ノートブックから
dbutils.secrets.getで取得して利用。
# 参照例
sas = dbutils.secrets.get(scope="storage", key="my-sas")
key = dbutils.secrets.get(scope="storage", key="account-key")
IllegalArgumentException: Unsupported Azure Scheme: abfss の原因と解決
マネージド ID を用いた abfss:// アクセスやマウントで、次の例外が出るケースがあります。
java.lang.IllegalArgumentException: Unsupported Azure Scheme: abfss
主な原因
- ADLS Gen2 ではない(HNS 未有効の Blob を
abfss://で参照している) - クラスタ Runtime が古い/非互換(ABFS ドライバが未対応)
- 接続先のドメインと設定キーが不整合(
dfs.core.windows.netに対してblob.core.windows.netの設定を書いている等) - URL 構文ミス(末尾の
/がなくマウントに失敗、コンテナーやアカウント名のタイプミス) - RBAC 不足(MI に対して Storage Blob Data Contributor 等が付与されていない)
チェックリスト(上から順に確認)
- ストレージが ADLS Gen2 かを確認:アカウント設定で「階層名前空間(HNS)」が有効か。無効なら
abfss://は使えません(wasbs://+ SAS/キーで回避)。 - クラスタ Runtime:Databricks Runtime 7.3 LTS 以降(または同等の ABFS 対応版)を使用。古い Runtime を使っていないかを確認し、可能なら更新。
- URL と設定キーの整合:
abfss://<container>@<account>.dfs.core.windows.net/の末尾/を含め、fs.azure.account.*.<account>.dfs.core.windows.netのようにdfsドメインで設定。 - MI の権限:対象スコープ(アカウント/コンテナー)で Storage Blob Data Contributor 以上を付与。コンテナーだけに付けた場合、アカウント側の設定が必要なことがあります。
- ネットワーク制限:Private Endpoint/ファイアウォールでブロックされていないか。必要に応じて Databricks のサブネットや送信先を許可。
よくある誤設定と修正例
| 誤り | 症状 | 修正 |
|---|---|---|
abfss:// なのに blob.core.windows.net の設定を書いている | スキーム不一致で例外 | dfs.core.windows.net 用のキーに統一 |
末尾の / を忘れてマウント | マウント時にパス解釈ミス | source="abfss://.../ のように末尾 / を付与 |
HNS 無効のアカウントを abfss:// で参照 | Unsupported Scheme | HNS を有効化した Gen2 に移行、または wasbs:// + SAS/キー |
| クラスタ Runtime が古い | ABFS クラスが見つからない/非対応 | Runtime を更新(7.3 LTS 以降を基準に) |
動作する最小サンプル(MI + abfss)
spark.conf.set("fs.azure.account.auth.type.<account>.dfs.core.windows.net", "OAuth")
spark.conf.set("fs.azure.account.oauth.provider.type", "org.apache.hadoop.fs.azurebfs.oauth2.MsiTokenProvider")
# ユーザー割り当て MI の場合のみ指定
# spark.conf.set("fs.azure.account.oauth2.client.id", "")
dbutils.fs.mount(
source="abfss://@.dfs.core.windows.net/",
mount_point="/mnt/gen2",
extra_configs={}
)
display(dbutils.fs.ls("/mnt/gen2"))
どうしても abfss:// が使えない場合の代替
wasbs://+ SAS:HNS 機能(POSIX 風 ACL 等)は使えませんが、多くのバッチ処理は実行可能。- 一時的にアクセスキー:検証のみ。完了後は速やかにキーをローテーション。
運用設計・セキュリティ ベストプラクティス
方式別のセキュリティ/運用比較
| 方式 | 漏えい耐性 | 権限の最小化 | ローテーション容易性 | 監査容易性 | コメント |
|---|---|---|---|---|---|
| AAD パススルー | 高 | 高(ユーザー RBAC) | 不要(資格情報はユーザー) | 高(ユーザー操作を追跡) | ユーザー単位のきめ細かい制御に最適 |
| マネージド ID | 高 | 高(ワークロード単位 RBAC) | 不要(シークレットを持たない) | 中(MI 単位の監査) | パイプライン単位で権限分離しやすい |
| SAS | 中 | 高(スコープ・期限を絞れる) | 中(再配布が必要) | 中(SAS 自体の監査は限定的) | 期限付き配布に向く。最短ルート |
| アクセスキー | 低 | 低(アカウント全体) | 低(広範囲に影響) | 低 | 本番禁止。PoC のみ |
Unity Catalog を使う場合のポイント(アプリ登録なしで進めたい方向け)
- データアクセスはStorage Credential と External Location で管理可能。
- 「Azure Databricks Access Connector」のマネージド IDを用いれば、サービス プリンシパルを自作せずに RBAC 連携できます。
- ネットワーク制限(Private Endpoint/Firewall)と合わせ、権限の委譲主体を「ユーザー」か「MI」かで統一するのがコツ。
ネットワーク設計の落とし穴
- ストレージのファイアウォールで Selected networks を使う場合、Databricks のデータプレーン サブネット(顧客管理 VNet or 管理プレーンのアウトバウンド)から到達可能かを確認。
- Private Endpoint 経由にすると DNS 解決先が
privatelink.dfs.core.windows.net/privatelink.blob.core.windows.netになります。スキームとドメインの整合に注意。
シークレット運用の原則
- ノートブックやジョブ設定に資格情報を直書きしない。すべて Secrets で参照。
- Key Vault 連携スコープを使い、権限はスコープ単位で最小化。
- SAS は最短の有効期限と必要最小の権限で発行し、ローテーション手順をあらかじめ用意。
ローテーションの実践テンプレート(SAS の 2 本持ち)
- 同権限・異なる有効期限の SAS(A/B)を発行し、Secret を
sas_activeに向ける。 - 期限が近づいたら未使用側(B)を更新 → Secret の中身を切り替え → 動作確認 → 古い側(A)を失効。
- マウント方式の場合は再マウントが必要。可能なら「非マウント方式」に設計変更。
トラブルシュート早見表
| 症状 | 疑うポイント | 具体的対処 |
|---|---|---|
Unsupported Azure Scheme: abfss | HNS / Runtime / URL / RBAC | 前章チェックリストに従い順に切り分け |
| 認証は通るが 403 Forbidden | RBAC の不足・ACL の不一致 | MI/ユーザーに Storage Blob Data Contributor 以上、フォルダー ACL も確認 |
| タイムアウト・遅延 | ネットワーク制限・DNS・PE | Private Endpoint と DNS 解決先、NSG/Firewall を再確認 |
| SAS で突然失敗 | 期限切れ・権限不足 | 新規発行 → Secret 更新 →(マウントの場合)再マウント |
よくある質問(FAQ)
Q. 管理者権限がなく、ワークスペース設定も変えられません。最短でつなぐには?
最短は SAS。ポータルで発行してもらい、Secret に入れて abfss:// または wasbs:// で直接アクセスします(本番は MI / パススルーを推奨)。
Q. Blob(HNS 無効)から MI でアクセスしたい。
環境によっては非対応です。安定動作を優先するなら Gen2(HNS 有効)へ移行し abfss:// + MI を推奨します。難しい場合は wasbs:// + SAS を選択してください。
Q. ユーザー委任 SAS(UDSAS)は使える?
使えますが発行に追加の権限が要ります。発行者のロール設計と運用フローが整っている場合に有効です。
Q. マウントと直アクセスはどちらが良い?
運用の容易さと再現性の観点で、直アクセス(Secret → spark.conf.set → 読み書き)を推奨。マウントはパスの簡素化にメリットがありますが、資格情報ローテーションを考慮した追加作業が増えます。
Q. Unity Catalog と組み合わせるときの勘所は?
Storage Credential に MI を割り当て、External Location で場所を定義。サービス プリンシパルを作成せずに一貫した権限モデルを構築できます。
実務でそのまま使えるコード集(安全な書き方)
SAS(Gen2, abfss)直アクセス
sas = dbutils.secrets.get(scope="storage", key="sas-gen2")
spark.conf.set("fs.azure.sas.<container>.<account>.dfs.core.windows.net", sas)
src = "abfss://@.dfs.core.windows.net/raw/events"
dst = "abfss://@.dfs.core.windows.net/curated/events"
df = spark.read.parquet(src)
(df
.withColumnRenamed("time", "event_time")
.repartition(8)
.write.mode("overwrite")
.format("delta")
.save(dst))
アクセスキー(Gen2, abfss)直アクセス
key = dbutils.secrets.get(scope="storage", key="account-key")
spark.conf.set("fs.azure.account.key..dfs.core.windows.net", key)
display(spark.read.format("csv").option("header", True).load(
"abfss://@.dfs.core.windows.net/csv/"))
MI(Gen2, abfss)直アクセス
# システム割り当て MI
spark.conf.set("fs.azure.account.auth.type..dfs.core.windows.net", "OAuth")
spark.conf.set("fs.azure.account.oauth.provider.type", "org.apache.hadoop.fs.azurebfs.oauth2.MsiTokenProvider")
# ユーザー割り当て MI(必要に応じて)
# spark.conf.set("fs.azure.account.oauth2.client.id", "")
path = "abfss://@.dfs.core.windows.net/delta/orders"
spark.read.format("delta").load(path).createOrReplaceTempView("orders")
マウントを使う場合の共通注意
- マウントの
sourceは末尾/を含める:abfss://.../ - 資格情報を更新したら再マウントが必要(直アクセス設計なら不要)。
- マウントポイントはチームで共通化し、命名規則(例:
/mnt/<env>/<layer>/<source>)を定義。
まとめ(ベストプラクティス)
- 開発環境は SAS/アクセスキーで素早く、本番は AAD パススルーまたはマネージド ID を推奨。
- 秘密情報はすべて Databricks Secrets(Key Vault 連携)に格納し、ノートブックに直書きしない。
- HNS の有無で
abfss://(Gen2)とwasbs://(Blob)を使い分ける。 - エラー時は「ストレージ設定(HNS/ドメイン)」「クラスタ Runtime」「認可(RBAC/ACL)」の 3 点をまず確認。
- Unity Catalog を使うなら、MI ベースの Storage Credential + External Location でアプリ登録なしの安全設計が可能。
これらを押さえれば、アプリ登録の権限がなくても最小限の管理者調整で Databricks と Azure Storage を安全に連携できます。

コメント