Unity Catalog 外部ロケーションの登録 (AWS) 


# はじめに

Databricks Unity Catalogを利用すると、DefaultのS3 Bucket 以外のバケットにアクセスするために、外部ロケーションを資格情報とともに登録することができます。これによってAccess Tokenなどを指定せずにバケットに安全にアクセスすることが可能になります。
もちろん、[従来通りの Access Keyベースや、Instance Profileを用いたアクセス](https://qiita.com/maroon-db/items/f91165612c4d43e53c87)も可能です。

外部ロケーションの登録には、[こちらのマニュアル](https://docs.databricks.com/data-governance/unity-catalog/manage-external-locations-and-credentials.html)も併せてご覧ください

# 要件
1. ストレージ資格情報を作成するには、**Databricks アカウント管理者**である必要があります。ストレージ資格情報を作成したアカウント管理者は、その所有権を他のユーザーまたはグループに委譲し、その権限を管理することができます。
1. 外部ロケーションを作成するには、メタストア管理者またはCREATE EXTERNAL LOCATION権限を持つユーザーである必要があります。
1. 外部ロケーションまたはストレージ クレデンシャルを作成または管理するには、ストレージにアクセスするUnityカタログ対応ワークスペースの**ワークスペース管理者**である必要があります。
1. ユーザーに読み取りと書き込みをさせる S3 バケットの名前には、ドット記法を使用できません（たとえば、incorrect.bucket.name.notation）バケットの命名に関する詳しいガイダンスについては、AWS バケット命名規則を参照してください。

Unity Catalogのセットアップについては[こちらをご覧](https://qiita.com/maroon-db/items/57cee03cef202c839b94)ください。


# S3 Bucketの作成

まずは、S3バケットを用意します。すでに作成済みの場合はスキップしてください。


今回は、以下のようなバケットを用意しました。

- バケット名：　`db-uc-external (任意)`
- AWS リージョン : `東京(ap-northeast-1)`
- オブジェクト所有者：`ACL無効`
- バケットのバージョニング : `有効にする (無効設定も可能）`
- デフォルトの暗号化： `有効にする(SSE-S3)`  
  --> 無効にすることも可能です。またSSE-KMSを利用する場合はマニュアルをご覧ください。

# IAM Role & Policy の作成

次に作成したS3バケットへアクセスできる IAM Role & Policyを準備します。

### 1) IAM Role作成
ロール名：`uc-external-role` (任意)

IAMロールの作成、または既存のロールの更新を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/3c965c44-555b-4205-a7cb-621a908ea97e.png)

新規のロールを作成し**Trust Relationship**にてJSONモードで以下にアップデートします。

\<AWS_ACCOUNT_ID>:  S3作成のAWS Account ID
\<AWS_IAM_ROLE_NAME>: 先ほど作成したIAM Role
\<DATABRICKS_ACCOUNT_ID> を変更。
```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
            "arn:aws:iam::414351767826:role/unity-catalog-prod-UCMasterRole-14S5ZJVKOTYTL",
            "arn:aws:iam::<AWS_ACCOUNT_ID>:role/<AWS_IAM_ROLE_NAME>"
        ]
      },
 
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "<DATABRICKS_ACCOUNT_ID>"
        }
      }
    }
  ]
}

```

### 2) IAM policyを作成し上記のロールに追加します。

\<AWS_ACCOUNT_ID>:  `S3作成者のAWS Account ID`
\<AWS_IAM_ROLE_NAME>: `uc-external-role` (先ほど作成したロール名)

```
{
 "Version": "2012-10-17",
 "Statement": [
     {
         "Action": [
             "s3:GetObject",
             "s3:GetObjectVersion",
             "s3:PutObject",
             "s3:DeleteObject",
             "s3:ListBucket",
             "s3:GetBucketLocation"
         ],
         "Resource": [
             "arn:aws:s3:::<BUCKET>/*",
             "arn:aws:s3:::<BUCKET>"
         ],
         "Effect": "Allow"
     },
     {
         "Action": [
             "sts:AssumeRole"
         ],
         "Resource": [
             "arn:aws:iam::<AWS_ACCOUNT_ID>:role/<AWS_IAM_ROLE_NAME>"
         ],
         "Effect": "Allow"
     }
   ]
}
```


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

ワークスペースにログインし、「データ」- [ストレージ資格情報]を選択。右上の[資格情報を作成]をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/9c3fd472-bb4b-ce1a-b624-0cacd22f5724.png)

先ほど作成したIAM Roleを登録します。
ストレージ資格情報名：`uc-external-rol` (任意)
IAMロール(ARN): `先ほど作成したIAMロール ARN`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/edbef872-679e-238a-3950-6c970c050e29.png)


他のユーザーに付与する場合は、資格情報の権限設定にて付与します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/f8527e94-07da-6645-9ffe-6c618b705020.png)


# ストレージロケーション（外部の格納場所）を登録
ワークスペースにログインし、「データ」- [外部の格納場所]を選択。右上の[格納場所の作成]をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/bb1717ed-48a2-d2f0-bdd5-e74c1b9a12d3.png)

外部の格納場所：`db-uc-external` (任意）
URL: `s3://db-uc-external` 
ストレージ資格情報: `uc-external-role` 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/5c97ee28-fbb7-8c42-1fd8-44902f489a30.png)

ストレージへのアクセス権を付与します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/16c509cd-9110-4264-636c-d172552fa59c.png)

右上の「接続テスト」にてパスすればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/a1e7b009-f5f7-cee2-cf37-d851d07b9432.png)


# ノートブックで外部テーブル作成を実行してみよう

こちらの[サンプルノートブック](https://sajpstorage.blob.core.windows.net/maruyama/Documents/UnityCatalog/uc_create_external-table.html)をインポートして、外部テーブルを作成出来るかご確認ください。

クラスター実行する際には、クラスターは `DBR11.1以降`＆アクセスモードは`Single User`であることを確認してください。

サンプルノートブックでは以下を実行しサンプルデータを使って、新しい外部テーブル(table1)を作成しております。

```
-- Create an example catalog and schema to contain the new table
CREATE CATALOG IF NOT EXISTS ext_catalog;
USE CATALOG ext_catalog;
CREATE SCHEMA IF NOT EXISTS ext_schema;
USE ext_schema;
```

```
CREATE TABLE ext_catalog.ext_schema.table1
LOCATION 's3://db-uc-external/table1'
AS SELECT * from samples.nyctaxi.trips;
```

以下のように、テーブルタイプが External として登録され、ストレージロケーションが外部のバケットになっていれば成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/efab6a3e-621f-206a-e7de-15e400ff3ead.png)


# さいごに

UnityCatalogセットアップについてはこちらもご覧ください。
https://qiita.com/maroon-db/items/57cee03cef202c839b94