Databricks Free EditionとAWS S3をつないで、外部Volumeと権限の挙動を確かめた
Databricks Free EditionからAWS S3へ、外部ロケーションの自動セットアップで接続。read_filesでの読み込み、招待ユーザーでの権限の違い、外部Volumeの範囲の効き方を検証した記録です。
目次 23項目
Databricks Free EditionからAWS S3のファイルを読めるのか、手元の環境で試してみました。
結論から書くと、外部ロケーションの「自動セットアップ」を使えば、Free EditionでもS3につながりました。IAMロールやストレージ認証情報を自分で作る必要はなく、画面の指示に沿ってAWSにログインするだけで済みました。
もう一つの収穫は、権限の挙動です。別のユーザーを招待して試したところ、外部ロケーションへの権限がなくても、外部Volumeの範囲内なら読めて、バケット直下は拒否されることを確認できました。
この記事では、接続までの手順と、外部ロケーションと外部Volumeの権限を検証した結果をまとめます。検証日は2026年10月29日です。
今回の構成
最終的な構成は次のとおりです。DatabricksとS3は、どちらもus-east-2(オハイオ)に置きました。
AWS(us-east-2)
S3バケット: databricks-test-xxxxxxxx
└─ raw/sales_sample.csv
IAMロール(自動セットアップで作成)
↑ 信頼関係
Databricks Free Edition(us-east-2)
ストレージ認証情報(自動セットアップで作成)
外部ロケーション s3_raw → s3://databricks-test-xxxxxxxx
外部Volume raw_files → s3://databricks-test-xxxxxxxx/raw/
(workspace.default.raw_files)
登場するオブジェクトを整理すると、次のようになります。
| オブジェクト | 作り方 | 役割 |
|---|---|---|
| IAMロール | 自動セットアップ | DatabricksがS3にアクセスするためのAWS側のロール |
| ストレージ認証情報 | 自動セットアップ | IAMロールをUnity Catalogに登録したもの |
| 外部ロケーション | 自動セットアップ | ストレージ認証情報とS3のパスの組み合わせ。ここではs3_raw |
| 外部Volume | SQLで作成 | S3のraw/だけを/Volumes/...のパスで扱えるようにしたもの |
事前に確認したこと
Free Editionの制限
Free Editionの制限には、次のような記載があります。
- コンピュートはサーバーレスのみ
- 外部へのインターネット接続は、信頼済みの一部のドメインに限られる
- ワークスペースの保存先を独自に指定することはできない
S3への接続ができるかどうかは、明記されていませんでした。そこで、実際に接続して確かめることにしました。
ワークスペースのリージョン
S3バケットは、Databricksのワークスペースと同じリージョンに作ります。リージョンをまたぐと、データ転送の料金がかかるためです。
ワークスペースのリージョンは、画面右上のワークスペース名をクリックすると確認できます。今回はus-east-2でした。

AWS側の準備
AWSアカウントの作成
AWSは、新しいアカウントを無料プランで作りました。作成後に、次の設定をしています。
- ルートユーザーのMFA(多要素認証)
- コンソールのリージョンをオハイオ(us-east-2)に切り替え
- 予算アラート
無料プランは、クレジットを使い切るか期間が終わると停止し、自動で有料に切り替わることはありません。期間の長さなどの条件は変わることがあるので、申し込み画面で確認してください。
S3バケットの作成
S3バケットは、次の設定で作りました。
| 項目 | 設定 |
|---|---|
| リージョン | us-east-2 |
| バケットタイプ | 汎用 |
| オブジェクト所有者 | ACL無効 |
| パブリックアクセス | すべてブロック(初期値のまま) |
| バージョニング | 無効 |
| 暗号化 | SSE-S3 |
バケットにraw/フォルダを作り、5行のテスト用CSV(sales_sample.csv)をアップロードしました。中身はorder_id、order_date、product、quantity、priceの5列です。
バケット名にドット(.)を含めると、自動セットアップで使えません。
なお、この記事ではバケット名の末尾を伏せてdatabricks-test-xxxxxxxxと表記し、スクリーンショットでもその部分をぼかしています。
外部ロケーションを自動セットアップで作る
Databricksの左のメニューから「カタログ」を開き、外部ロケーションの作成画面で「自動セットアップ」を選びます。入力する項目は次の3つです。
| 項目 | 入力値 |
|---|---|
| 外部ロケーション名 | s3_raw |
| S3バケットURL | s3://databricks-test-xxxxxxxx |
| 読み取り専用の使用に制限する | チェックしない |

事前に調べた解説では、「個人用アクセストークンを発行して、AWSのCloudFormationに貼り付ける」という手順でした。ところが、実際の画面にはトークンの入力欄がなく、「AWSにログインして外部ロケーションを作成」というボタンだけでした。
公式ドキュメントを確認すると、現在の自動セットアップは、AWS IAMの一時的な委任(temporary delegation)を使う方式になっていました。セットアップ用に委任した権限は、完了後に自動で失効します。その後のS3へのアクセスには、自動で作られたIAMロールを使います。
ボタンを押すと、AWSに作成されるリソースの確認ダイアログが表示されます。

「外部ロケーションの作成を開始」を押してAWSにログインし、アクセスを許可すると、IAMロールとストレージ認証情報、外部ロケーションが自動で作られました。公式ドキュメントによると、完了までに最大8分ほどかかることがあります。AWS側の権限が足りない場合は、AWSの管理者に承認を依頼する流れになります。
S3のファイルを読む
外部ロケーションができたら、SQLエディタでread_filesを実行して確認します。
SELECT * FROM read_files(
's3://databricks-test-xxxxxxxx/raw/',
format => 'csv',
header => true
);
アップロードしたCSVの5行が表示されました。

ここまでは、ワークスペースの管理者(外部ロケーションを作ったユーザー)で実行しています。
招待ユーザーで権限の挙動を確かめる
次に、同じワークスペースに別のユーザーを招待し、権限がどう効くのかを試しました。
外部ロケーションの権限がないと読めない
招待ユーザーで同じSQLを実行すると、エラーになりました。
PERMISSION_DENIED: Principal <招待ユーザー> does not have READ FILES on External Location 's3_raw'.

外部ロケーションs3_rawに対するREAD FILES権限がないためです。
外部Volumeを作り、READ VOLUMEを付与する
READ FILESを付与すれば読めるようになりますが、外部ロケーションはバケット全体を指しているので、バケットのすべてのファイルが読めてしまいます。
そこで、raw/だけを外部Volumeとして登録し、そのVolumeへの読み取り権限を付与しました。以下は管理者ユーザーで実行します。
CREATE EXTERNAL VOLUME workspace.default.raw_files
LOCATION 's3://databricks-test-xxxxxxxx/raw/';
GRANT USE CATALOG ON CATALOG workspace TO `<招待ユーザー>`;
GRANT USE SCHEMA ON SCHEMA workspace.default TO `<招待ユーザー>`;
GRANT READ VOLUME ON VOLUME workspace.default.raw_files TO `<招待ユーザー>`;
<招待ユーザー>は、招待したユーザーのメールアドレスに置き換えます。READ VOLUMEだけでなく、親のカタログとスキーマへのUSE CATALOGとUSE SCHEMAも必要です。
Volume経由なら読める
招待ユーザーで、Volumeのパスを指定して読み込みます。
SELECT * FROM read_files(
'/Volumes/workspace/default/raw_files/',
format => 'csv',
header => true
);
今度は5行が表示されました。
意外だったこと:S3のパスを直接指定しても読めた
ここで意外だったのが、招待ユーザーがs3://databricks-test-xxxxxxxx/raw/を直接指定した場合も読めたことです。外部ロケーションへのREAD FILESは付与していないので、引き続き拒否されると予想していました。

公式ドキュメントには、Unity Catalogは外部テーブルと外部Volumeに対して、クラウドストレージのURIによるパスベースのアクセスをサポートすると書かれています。そのうえで、Volumeのデータには/Volumesのパスでアクセスすることが推奨されています。
ただ、「Volumeの範囲内のパスであれば、外部ロケーションのREAD FILESではなく、VolumeのREAD VOLUMEで判定される」という判定の順序そのものは、公式ドキュメントでは見つけられませんでした。今回の結果からの私の解釈です。
解釈としては、s3://.../raw/と/Volumes/.../raw_files/は、同じ場所への別の入り口です。どちらから入っても、Volumeの権限で判定されているように見えます。
バケット直下を指定すると拒否された
では、Volumeの範囲外はどうか。バケットの直下を指定してみました。
SELECT * FROM read_files(
's3://databricks-test-xxxxxxxx/',
format => 'csv',
header => true
);
こちらはREAD FILESがないというPERMISSION_DENIEDになりました。

バケット全体が読めるようになったわけではないことを確認できました。試したのはバケット直下だけですが、今回の結果からは、読める範囲がVolumeのraw/に限られているように見えます。
検証結果をまとめると、次のとおりです。
| 招待ユーザーが指定したパス | 付与した権限 | 結果 |
|---|---|---|
s3://.../raw/ |
なし | PERMISSION_DENIED |
/Volumes/workspace/default/raw_files/ |
READ VOLUMEなど |
読めた |
s3://.../raw/ |
READ VOLUMEなど |
読めた |
s3://.../(バケット直下) |
READ VOLUMEなど |
PERMISSION_DENIED |
外部ロケーションと外部Volumeの違い
検証を通じて、外部ロケーションと外部Volumeの役割の違いが分かりました。
| 外部ロケーション | 外部Volume | |
|---|---|---|
| 役割 | DatabricksがS3のどこにアクセスしてよいかの許可 | S3の特定のフォルダを扱う窓口 |
| 範囲 | バケット全体など広め | 例:raw/ |
| 名前 | メタストア直下のオブジェクト | カタログ.スキーマ.ボリューム |
| 主な権限 | READ FILES、CREATE EXTERNAL VOLUME(管理者向け) |
READ VOLUME、WRITE VOLUME(利用者向け) |
| パス | s3://... |
/Volumes/... |
今回の外部ロケーションはバケット全体を指しているので、ここにREAD FILESを付与すると、読める範囲をraw/だけに絞れません。権限の公式ドキュメントでも、クラウドストレージのファイルを直接読ませるのではなく、VolumeとREAD VOLUMEで読み取りを管理することが推奨されています。
Volumeを使うと、ほかにも次のような利点があります。
- パスを
/Volumes/...にそろえられるので、バケットを移しても利用者のコードを変えずに済む - 通常のファイルパスとして、Pythonやpandasから扱える
- カタログの画面から中身を見たり、ファイルをアップロードしたりできる
- 読み取りと書き込みの権限を分けられる
運用としては、利用者は/Volumes/...を使い、s3://を扱うのは管理者だけにするのがよさそうです。
検証中に整理したこと
同じパスにVolumeとテーブルを重ねられない
外部Volumeを作るときに指定するパスは、ほかのVolumeやテーブルの場所と重ならないようにする必要があります(CREATE VOLUME)。外部ロケーションの内側にVolumeを作るのは問題ありません。
たとえば、raw/にVolumeがある状態で、raw/やraw/sales/を外部テーブルの場所にすることはできません。curated/のように別のフォルダなら作れます。
S3にファイルを追加したらどうなるか
Volumeはファイルのコピーではなく、S3を見るための窓口です。S3のraw/にファイルを置けば、/Volumes/...からもそのまま見えます。
ただし、CREATE TABLE ... AS SELECTで作ったテーブルには反映されません。続けて取り込むには、COPY INTOを繰り返し実行する処理や、Auto Loaderを使う処理が必要です。ファイル到着トリガーは、こうした取り込み処理を実行するジョブを起動するために使います。今回の自動セットアップでは、外部ロケーションにファイルイベントが自動で設定されると公式ドキュメントに書かれていました。
データ取り込み画面のS3タブ
「データ取り込み」の画面には、S3のファイルからテーブルを作るタブもあります。外部ロケーションを選んでファイルを読み込み、マネージドテーブルを作る処理を、画面から1回きりで行うものです。

招待ユーザーは外部ロケーションのREAD FILESを持っていないので、S3タブではなく「ボリューム」タブから取り込むことになりそうです。テーブルを作るには、スキーマへのCREATE TABLE権限も必要です。
本番ではDABsでどこまでコード化できるか
手作業で作った構成を、本番ではコードで管理したくなります。Declarative Automation Bundles(DABs)のリソース一覧を確認したところ、次のようになっていました。
| リソース | DABsでの扱い |
|---|---|
外部ロケーション(external_locations) |
対応。Databricks CLI 0.289.0以降で、direct deployment engineが必要 |
Volume(volumes) |
対応。外部Volumeの場所はstorage_locationで指定(CLI 0.236.0以降) |
| ストレージ認証情報 | リソース一覧になし |
そのため、AWS側(IAMロール、S3)とストレージ認証情報はTerraformで作り、外部ロケーションとVolume、権限はDABsで管理する、という分担が考えられます。
YAMLにすると、たとえば次のような形です。この例では、利用者に対象カタログへのUSE CATALOGと、対象スキーマへのUSE SCHEMAを付与済みとしています。キーは公式ドキュメントで確認しましたが、実際のデプロイは試していないので、databricks bundle validateで確認してから使ってください。
bundle:
name: s3_ingest
engine: direct # 外部ロケーションにはdirect deployment engineが必要
resources:
external_locations:
s3_landing:
name: s3_landing_${bundle.target}
url: s3://databricks-test-xxxxxxxx/
credential_name: <ストレージ認証情報の名前>
volumes:
raw_files:
catalog_name: workspace
schema_name: default
name: raw_files
volume_type: EXTERNAL
storage_location: s3://databricks-test-xxxxxxxx/raw/
grants:
- principal: <招待ユーザー>
privileges:
- READ_VOLUME
あわせて、次の点に注意が必要です。
- 手作業で作ったリソースと同じ名前で定義すると、衝突する可能性がある(既存リソースを取り込めるかは未確認)
databricks bundle destroyを実行すると、定義したリソースも削除される。消したくないものはlifecycleで保護する- デプロイするユーザーやサービスプリンシパルに、外部ロケーションを作る権限(
CREATE EXTERNAL LOCATION)が必要
まとめ
- Databricks Free Editionでも、外部ロケーションの自動セットアップでAWS S3につなげた
- 自動セットアップは、トークンを貼り付ける方式ではなく、AWSにログインして許可する方式になっていた
- 利用者には外部ロケーションの
READ FILESではなく、外部VolumeのREAD VOLUMEを渡すと、読ませる範囲をフォルダ単位に絞れる - Volumeの範囲内なら
s3://の指定でも読めたが、バケット直下は拒否された。範囲内でどの権限から判定されるかは、公式ドキュメントでは確認できなかった
今回は、外部テーブルの作成とDROPしたときの挙動、COPY INTOやAuto Loaderでの継続的な取り込み、DABsでの実際のデプロイまでは試していません。次はこのあたりを確かめたいと思います。
検証が終わったら、AWS側のS3バケットやIAMロールは忘れずに片付けておきましょう。