1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Unity Catalogでクロスアカウントの外部ロケーションと外部テーブルを作成する

Last updated at Posted at 2023-01-26

ハマったのでメモ。

外部ロケーションとはUnity Catalogでクラウドストレージにアクセスする際に使用するオブジェクトです。ストレージ資格情報と組み合わせて使用します。作成方法はこちら。

Databricksワークスペースとアクセス先のS3が同じAWSアカウントであれば上の手順でOKなのですが、クロスアカウントの際は?となった次第です。

結論は、

  1. S3があるAWSアカウントでS3にアクセスするためのIAMロールの信頼ポリシーにUnity Catalogの信頼関係を追加。
  2. 上記S3にアクセスするためのIAMロールのARNをコピー。
  3. Databricksワークスペースで上記ARNを用いてストレージ資格情報を作成。
  4. 上記ストレージ資格情報を用いて外部ロケーションを作成。

という流れでした。すなわち、DatabricksがデプロイされているAWSアカウントではAWSの設定変更は不要ということです。

S3があるAWSアカウントでの作業

  1. S3にアクセスするためのIAMロールがない場合には作成します。

  2. このIAMロールの信頼ポリシーに以下の内容を追加します。ここでは、<bucket-owner-acct-id>はS3のあるAWSアカウントのアカウントID、bucket-owner-acct-s3-access-roleはS3にアクセスするためのIAMロール、<DatabricksアカウントID>は、Unity Catalogが稼働しているDatabricksのアカウントIDです。

    JSON
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::414351767826:role/unity-catalog-prod-UCMasterRole-14S5ZJVKOTYTL",
          "arn:aws:iam::<bucket-owner-acct-id>:role/bucket-owner-acct-s3-access-role"
         ]
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "<DatabricksアカウントID>"
        }
      }
    }
    
  3. 上記IAMロールのS3へのアクセス権を適宜設定します。

  4. bucket-owner-acct-s3-access-roleのARNをコピーしておきます。

Databricksでの作業

ストレージ資格情報の作成

  1. メタストア管理者あるいはアカウント管理者でDatabricksにログインします。
  2. サイドメニューのデータを選択します。
    Screenshot 2023-01-26 at 20.41.20.png
  3. ストレージ資格情報をクリックします。
    Screenshot 2023-01-26 at 20.43.21.png
  4. 資格情報を作成ボタンをクリックします。
    • わかりやすい名称をつけます。
    • IAMロールには上のステップでコピーしたARNを貼り付けます。
    • コメントを入力します。
      Screenshot 2023-01-26 at 20.44.52.png
  5. 作成をクリックします。

外部ロケーションの作成

  1. 外部ロケーションをクリックします。
    Screenshot 2023-01-26 at 20.46.38.png
  2. ロケーションを作成ボタンをクリックします。
    • わかりやすい名称をつけます。
    • URLにはアクセス先のS3のURLを入力します。
    • ストレージ資格情報では、上で作成したストレージ資格情報を選択します。
    • コメントを入力します。
      Screenshot 2023-01-26 at 20.47.37.png
  3. 作成をクリックします。

これでクロスアカウントの外部ロケーションが作成できました。
Screenshot 2023-01-26 at 20.49.00.png

注意
外部ロケーションを作成する際には接続チェックが行われます。エラーになる場合にはIAMの設定を確認してください。

接続確認

  1. Unity Catalogにアクセスするためのクラスターを作成します。パーソナルコンピュートがお手軽でおすすめです。
    Screenshot 2023-01-26 at 20.51.16.png

  2. SQLノートブックを作成してクラスターにアタッチします。

  3. 外部ロケーションの詳細を確認します。

    SQL
    DESCRIBE EXTERNAL LOCATION `cross-account-s3-external-location`;
    
  4. メタデータを確認することができます。
    Screenshot 2023-01-26 at 20.52.15.png

  5. 外部ロケーションの中身を確認します。

    SQL
    LIST 's3://ty-databricks-cross-account-bucket';
    

    Screenshot 2023-01-26 at 20.53.08.png

クロスアカウントの設定をするよりもお手軽です。

さらにこれを活用してテーブルを作成していきます。

外部テーブルの作成

データ読み込み元として上で作成した外部ロケーションを利用できることに加え、外部ロケーションにテーブルを作成することができます。

なお、以前はDBFSマウントを使用していた方もいらっしゃると思いますが、現状の外部ロケーションではマウントポイントではなく、直パスを指定する形になります。

元データの準備

ここでは、デモの目的もありサンプルデータを外部ロケーションに作成します。直パスs3://ty-databricks-cross-account-bucket/testParquetを指定して、Parquetを保存します。

Scala
%scala 
 
case class MyCaseClass(key: String, group: String, value: Int, someints: Seq[Int], somemap: Map[String, Int])
val dataframe = sc.parallelize(Array(MyCaseClass("a", "vowels", 1, Array(1), Map("a" -> 1)),
  MyCaseClass("b", "consonants", 2, Array(2, 2), Map("b" -> 2)),
  MyCaseClass("c", "consonants", 3, Array(3, 3, 3), Map("c" -> 3)),
  MyCaseClass("d", "consonants", 4, Array(4, 4, 4, 4), Map("d" -> 4)),
  MyCaseClass("e", "vowels", 5, Array(5, 5, 5, 5, 5), Map("e" -> 5)))
).toDF()
// now write it to disk
dataframe.write.mode("overwrite").parquet("s3://ty-databricks-cross-account-bucket/testParquet")

クロスアカウントのS3でディレクトリが作成されていることを確認できます。
Screenshot 2023-01-27 at 8.27.48.jpeg

外部ロケーションに格納されているファイルに直接クエリーを行うことも可能です。

SQL
SELECT * FROM parquet.`s3://ty-databricks-cross-account-bucket/testParquet`

Screenshot 2023-01-27 at 8.06.12.png

Python(PySpark)でも同じことができます。

Python
%python
display(spark.read.format("parquet").load("s3://ty-databricks-cross-account-bucket/testParquet"))

SQLがメインのワークロードの場合、毎回直パスを指定するのは面倒ですし、可読性も低下します。DWHと同じようにデータベース、テーブルのパラダイムでデータを活用できるように、Unity Catalogにテーブルに登録します。DBMS同様、CREATE TABLE、行のインサートという流れになります。

なお、Unity Catalogにおいては3レベルの名前空間を使用します。カタログ.スキーマ(データベース).テーブルという形式でテーブルにアクセスします。

カタログの作成

  1. サイドメニューのデータをクリックして、データエクスプローラに移動します。
    Screenshot 2023-01-27 at 8.14.44.png
  2. カタログを作成をクリックしてカタログの情報を入力します。
    • カタログ名はexternal_catalogとします。
    • マネージドロケーションには、カタログに格納されるテーブルデータを格納するロケーションを指定します。ここでは、上のステップで作成した外部ロケーションのパスを指定します。
      Screenshot 2023-01-27 at 8.22.06.png
  3. 作成をクリックするとカタログが外部ロケーションに作成されます。
    Screenshot 2023-01-27 at 8.23.42.png

カタログを作成すると、その配下にデフォルトスキーマ(データベース)defaultが作成されるので、以降ではこちらを使用します。なお、別途スキーマを作成することも可能です。

テーブルの作成

ノートブックに戻って、以下のコマンドを実行します。testという空のテーブルがexternal_data.defaultに作成されます。

SQL
CREATE TABLE external_catalog.default.test;

以下のCOPY INTOコマンドを実行することで、s3://ty-databricks-cross-account-bucket/testParquetをテーブルexternal_catalog.default.testに読み込みます。

SQL
COPY INTO external_catalog.default.test
FROM (
  SELECT *
  FROM 's3://ty-databricks-cross-account-bucket/testParquet'
)
FILEFORMAT = parquet COPY_OPTIONS ("mergeSchema" = "true");

クロスアカウントのS3バケットを確認すると、ディレクトリが作成されていることを確認することができます。
Screenshot 2023-01-27 at 8.27.48.jpeg

これで、external_catalog.default.testでテーブルにアクセスできるようになります。

SQL
SELECT * FROM external_catalog.default.test;

Screenshot 2023-01-27 at 8.34.24.png

データエクスプローラでも確認できます。
Screenshot 2023-01-27 at 8.38.22.png
Screenshot 2023-01-27 at 8.39.05.png

権限の設定

この状態では作成したテーブルに他のユーザーがアクセスできません。

  1. カタログを選択し、権限を開き、付与をクリックします。
    Screenshot 2023-01-27 at 12.13.48.png
  2. ここではすべてのユーザーに読み取り権限を与えるものとします。ユーザーとグループではaccount usersを選択し、権限プリセットではデータリーダーを選択します。
    Screenshot 2023-01-27 at 12.13.00.png
  3. 付与をクリックすることで権限が付与されます。
    Screenshot 2023-01-27 at 12.16.17.png

Databricks 無料トライアル

Databricks 無料トライアル

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?