背景・目的
以前、こちらの記事に書いたように、Databricksでは、外部ロケーションを設定することで、UnityCatalogを介してクラウドテナント上のデータを読み書きできます。
本記事では、実際に外部ロケーション上のデータを読み書きしてみます。
まとめ
- Unity Catalogを介してクラウド上のデータを読み書きを行うには、外部ロケーションとストレージ資格情報を設定する
- 外部ロケーションは、下記が含まれる。
- クラウドストレージパス
- ストレージ資格情報
- IAMロールを使用してクラウドに保存されているデータにアクセスするための認証と承認メカニズム
- アカウント管理者である必要がある
- 下記の権限が必要である。
- メタストア管理者
- Create External Location権限を持つユーザ
概要
外部ロケーションとストレージ資格情報とは
外部ロケーションとストレージ資格情報を使用すると、Unity Catalogはユーザーに代わってクラウドテナント上のデータを読み書きできます。これらのオブジェクトは、次の目的で使用されます。
- Unity Catalogを介してクラウド上のデータを読み書きを行うには、外部ロケーションとストレージ資格情報を設定する
ストレージ認証情報 は、IAMロールを使用してクラウド テナントに保存されているデータにアクセスするための認証および承認メカニズムを表します。各ストレージ資格情報は、資格情報にアクセスできるユーザーとグループを制御する Unity Catalog アクセス制御ポリシーの対象となります。 ユーザーが Unity Catalogのストレージ資格情報にアクセスできない場合、要求は失敗し Unity Catalog ユーザーに代わってクラウド テナントに対する認証を試行しません。 ストレージ資格情報をread-only]としてマークして 、 ユーザーがストレージ資格情報を使用する外部ロケーションに書き込むことができないようにすることができます。
- ストレージ資格情報とは、IAMロールを使用してクラウドに保存されているデータにアクセスするための認証と承認メカニズムを指す。
- 各ストレージ資格情報は、資格情報にアクセスできるユーザーとグループを制御する Unity Catalog アクセス制御ポリシーの対象となる。
外部ロケーション は、クラウドストレージパスと、クラウドストレージパスへのアクセスを承認するストレージ資格情報を組み合わせたオブジェクトです。各ストレージの場所には、資格情報にアクセスできるユーザーとグループを制御する Unity Catalog アクセス制御ポリシーが適用されます。 ユーザーが Unity Catalogのストレージの場所にアクセスできない場合、要求は失敗し Unity Catalog ユーザーに代わってクラウド テナントに対する認証を試行しません。 外部ロケーションを read-only] としてマークすると、ユーザーはその場所に書き込めず、ユーザーはその場所にテーブルまたはボリューム (外部または管理対象) を作成できなくなります。
- 外部ロケーションとは、クラウドストレージパスと、クラウドストレージパスへのアクセスを承認するストレージ資格情報の組み合わせを指す。
- つまり、ストレージ資格情報が前提になる
要件
- ストレージ資格情報を作成するには、Databricksアカウント管理者である必要があります。ストレージ資格情報を作成するアカウント管理者は、所有権を別のユーザーまたはグループに委任して、そのアクセス許可を管理できます。
- 外部ロケーションを作成するには、メタストア管理者またはCREATE EXTERNAL LOCATION権限を持つユーザーである必要があります。
- ストレージ資格情報は、アカウント管理者である必要がある
- 外部ロケーションの作成には、下記が必要
- メタストア管理者
- Create External Location権限を持つユーザ
実践
ストレージ資格情報の管理
ストレージ資格情報の管理を元に試してみます。
ストレージ資格情報の作成
ストレージ認証情報を作成するには、S3 バケットパスへのアクセス (読み取りまたは読み取りと書き込み) を許可する IAMロールが必要です。 その IAMロールは、ストレージ認証情報を作成するときに参照します。
ステップ1: IAMロールを作成する
S3バケットへのアクセス許可するIAMロールを作成します。
-
AWSにログインします。
-
カスタム信頼ポリシーフィールドに下記のポリシーを貼り付けます。
- <DATABRICKS-ACCOUNT-ID>は、自分のDatabricksアカウントのIDをを入力します。
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::414351767826:role/unity-catalog-prod-UCMasterRole-14S5ZJVKOTYTL" ] }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "<DATABRICKS-ACCOUNT-ID>" } } }] }
-
このまま、次へをクリックしIAMロール名を入力し保存します。
-
下記のARNをPrincipalに追加します。
- IAMロールのARNに置き換えます。
"arn:aws:iam::<YOUR-AWS-ACCOUNT-ID>:role/<THIS-ROLE-NAME>"
-
インラインポリシーを追加を選択し、下記のポリシーをコピーします。
- KMSが不要な場合は、削除します。
- 作成したIAMロールに置き換えます。
- S3バケットを指定します。
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket", "s3:GetBucketLocation", "s3:GetLifecycleConfiguration", "s3:PutLifecycleConfiguration" ], "Resource": [ "arn:aws:s3:::<BUCKET>/*", "arn:aws:s3:::<BUCKET>" ], "Effect": "Allow" }, { "Action": [ "kms:Decrypt", "kms:Encrypt", "kms:GenerateDataKey*" ], "Resource": [ "arn:aws:kms:<KMS-KEY>" ], "Effect": "Allow" }, { "Action": [ "sts:AssumeRole" ], "Resource": [ "arn:aws:iam::<AWS-ACCOUNT-ID>:role/<AWS-IAM-ROLE-NAME>" ], "Effect": "Allow" } ] }
-
ポリシー名を入力し作成します。
ステップ 2:IAMロールの詳細をDatabricksに渡す
-
ワークスペースにログインします。
-
ポップアップが表示されるので、下記を入力し「Create」をクリックします。
外部ロケーションを管理する
外部ロケーションを管理するを元に試します。
外部ロケーションを作成する
-
次のクエリを実行し、外部ロケーションを作成します。
CREATE EXTERNAL LOCATION IF NOT EXISTS ext_location URL 's3://<bucket-path>' WITH (STORAGE CREDENTIAL <storage-credential-name>) [COMMENT <comment-string>];
-
External locationをクリックすすると、作成されていました。
-
ロケーション名をクリックし、「Test connection」をクリックします。
-
下記のクエリを実行し、外部ロケーションの詳細を確認します。
DESCRIBE EXTERNAL LOCATION ext_location
外部テーブルを作成する
-
下記のテストデータを準備し、S3バケットにアップロードする。
{"id":1,"value":"xxx"} {"id":2,"value":"yyy"} {"id":3,"value":"zzz"}
-
SQL Editorで下記のクエリを実行します。
SELECT * FROM json.`s3://XXXXX/test-json/`
-
「Create catalog」をクリックします。
-
下記を入力し、「Create」をクリックします。
-
SQL Editorで下記のクエリを実行します。
CREATE TABLE ext_catalog.default.test
-
COPY INTOを使用することで、作成したテーブルに読み込ませることが出来ます。
COPY INTO ext_catalog.default.test FROM ( SELECT * FROM 's3://XXXX/test-json/' ) FILEFORMAT = json COPY_OPTIONS ("mergeSchema" = "true");
-
SELECTします。読み込めました。
SELECT * FROM ext_catalog.default.test
考察
外部テーブルを使うことで、直接クラウドストレージからデータを読み込むことが出来ました。
参考