S3 Tablesのチュートリアルを試してみた

# 背景・目的
以前、下記の記事でS3 Tablesを整理しましたが今回は実際に試してみます。

https://qiita.com/zumax/items/3daa6cbde80676e76d3f

## Using Amazon S3 Tables with AWS analytics services
下記を基に整理します。

https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables-integrating-aws.html



### How the integration works
- コンソールでテーブルバケットを作成すると、S3は下記のアクションにより、選択したリージョン内のテーブルバケットをAWS分析サービスと統合する
    - Lake Formation（LFn）に全てのテーブルバケットへのアクセスを許可するIAMサービスロールを咲くショウする
    - サービスロールを使用してLFnは、現在のリージョンにテーブルバケットを登録する
    - 現在のリージョンのAWS Glueデータカタログに`s3tablescatalog`を追加する

- LFnはそのリージョンの現在、及び将来のすべてのテーブルバケットへのアクセス、権限、ガバナンスを管理できる
- 下記にs3tablescatalogが現在のリージョンのテーブルバケット、名前空間、テーブルをデータカタログ内の対応するオブジェクトとして自動的に入力する方法を示す
    - テーブルバケットはサブカタログとして入力される
    - テーブルバケット内の名前空間は、それぞれのサブカタログ内のDBとして入力される
    - テーブルは、それぞれのデータベース内のテーブルとして入力される

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/84c78ccf-aaa8-bdd4-86d3-b4259d28e6b9.png)

    ※出典：[How the integration works](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables-integrating-aws.html#how-table-integration-works)

### Prerequisites for integration
- 下記の前提条件が必要
    - テーブルバケットの作成
    - glue:PassConnection IAMプリンシパルが必要
    - AWSLakeFormationDataAdmin をIAMプリンシパルにアタッチして、そのユーザをデータレイク管理者にする
    - lakeformation:RegisterResourceオペレーションの権限を追加する



# 実践
下記を元に試します。

https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables-getting-started.html

1. AWSにサインインします
<!--
## 前提
1. VPCに移動します
1. 「VPCを作成」をクリックします
1. 「VPCなど」を選択し、下記の内容で「VPCを作成」をクリックします
    - パブリックサブネット：なし
    - プライベートサブネット：1つ
    - NATGW：なし
    - VPCe：S3ゲートウェイ
1. できました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/c937e647-d110-c4c0-2fb6-2da3ad134fb8.png)

-->

## 前提

### AWS CLIのセットアップ
下記を参考に、最新のAWS CLIをダウンロードしておきます。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

1. s3tablesのサブコマンドが認識されませんでした
    ```bash
    % aws s3tables create-namespace       
    
    usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
    To see help text, you can run:
    
      aws help
      aws <command> help
      aws <command> <subcommand> help
    
    aws: error: argument command: Invalid choice, valid choices are:
    ```

1. ダウンロードします
    ```bash
    % curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
    % ls -ltr AWSCLIV2.pkg                                              
    -rw-r--r--  1 XXXX  XXXX  40953488  2  2 09:05 AWSCLIV2.pkg
    % 
    ```

1. インストールします
    ```bash
    % sudo installer -pkg ./AWSCLIV2.pkg -target /
    Password:
    installer: Package name is AWS Command Line Interface
    installer: Upgrading at base path /
    installer: The upgrade was successful.
    % 
    ```

1. バージョンを確認します
    ```bash
    % which aws
    /usr/local/bin/aws
    % aws --version
    aws-cli/2.23.11 Python/3.12.6 Darwin/23.6.0 exe/x86_64
    %  
    ```

1. `s3tables`サブコマンドは認識されたようです
    ```bash
    % aws s3tables create-namespace
    
    usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
    To see help text, you can run:
    
      aws help
      aws <command> help
      aws <command> <subcommand> help
    
    aws: error: the following arguments are required: --table-bucket-arn, --namespace
    
    % 
    ```

### Athena Workspaceのセットアップ
クエリ結果の保存場所を保存するS3バケットを作成し、Athenaで設定します。
1. ①.「Location of query result」に上記で作成したS3バケットを選択し、「保存」をクリックします

#### S3バケットの作成

1. S3バケットに移動し、作成します

#### AthenaのWorkspaceの設定
1. Athenaに移動します
1. 「設定」タブをクリックします
1. 「管理」をクリックします
1. クエリを
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/e952ec8f-e2cd-8f58-01cd-45eca160e32c.png)

## Step 1: Create a table bucket and integrate it with AWS analytics services

1. S3に移動します
1. ナビゲーションペインで「テーブルバケット」にクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/18d40d79-65a8-52f4-7e2f-dccdbc0fe317.png)

1. 「テーブルバケットを作成」をクリックします
1. 下記を入力し、「テーブルバケットを作成」をクリックします
    - バケット名
    - 統合を有効にする
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/1741bc71-ccd6-4c7b-3c2f-410e83ac64d2.png)


## Step 2: Create a table namespace and a table using the AWS CLI
### namespaceの作成
1. テーブルバケットに新しいnamespaceを作成します
    ```json
    % aws s3tables create-namespace \    
    --table-bucket-arn arn:aws:s3tables:ap-northeast-1:XXXXXX:bucket/XXXXX \
    --namespace my_namespace
    {
        "tableBucketARN": "arn:aws:s3tables:ap-northeast-1:XXXXXX:bucket/XXXXXX",
        "namespace": [
            "my_namespace"
        ]
    }
    % 
    ```
1. 作成後、確認します
    ```json
    % aws s3tables list-namespaces \
    > --table-bucket-arn arn:aws:s3tables:ap-northeast-1:XXXXXX:bucket/XXXXXX
    {
        "namespaces": [
            {
                "namespace": [
                    "my_namespace"
                ],
                "createdAt": "2025-02-02T00:33:09.477910+00:00",
                "createdBy": "XXXXXX",
                "ownerAccountId": "XXXXXX"
            }
        ]
    }
    % 
    ```
### テーブルの作成
1. mytabledefinition.jsonを作成します
    ```json
    % cat mytabledefinition.json 
    {
        "tableBucketARN": "arn:aws:s3tables:ap-northeast-1:XXXXXX:bucket/XXXXXX",
        "namespace": "my_namespace",
        "name": "my_table",
        "format": "ICEBERG",
        "metadata": {
            "iceberg": {
                "schema": {
                    "fields": [
                         {"name": "id", "type": "int","required": true},
                         {"name": "name", "type": "string"},
                         {"name": "value", "type": "int"}
                    ]
                }
            }
        }
    }
    % 
    ```
1. `mytabledefinition.json`を基に、テーブルを作成します
    ```json
    % aws s3tables create-table --cli-input-json file://mytabledefinition.json
    {
        "tableARN": "arn:aws:s3tables:ap-northeast-1:XXXXXX:bucket/XXXXXX/table/XXXXXX",
        "versionToken": "XXXXXX"
    }
    % 
    ```
1. 作成されたテーブルをlistで確認します
    ```json
    % aws s3tables list-tables --table-bucket-arn arn:aws:s3tables:ap-northeast-1:XXXXXX:bucket/XXXXXX
    {
        "tables": [
            {
                "namespace": [
                    "my_namespace"
                ],
                "name": "my_table",
                "type": "customer",
                "tableARN": "arn:aws:s3tables:ap-northeast-1:XXXXXX:bucket/XXXXXX/table/XXXXXX",
                "createdAt": "2025-02-02T00:40:19.209543+00:00",
                "modifiedAt": "2025-02-02T00:40:19.209543+00:00"
            }
        ]
    }
    % 
    ```
1. テーブルの詳細を確認します
    ```json
    % aws s3tables get-table --table-bucket-arn arn:aws:s3tables:ap-northeast-1:XXXXXX:bucket/XXXXXX \
    > --namespace my_namespace \
    > --name my_table
    {
        "name": "my_table",
        "type": "customer",
        "tableARN": "arn:aws:s3tables:ap-northeast-1:XXXXXX:bucket/XXXXXX/table/XXXXXX",
        "namespace": [
            "my_namespace"
        ],
        "versionToken": "XXXXXX",
        "metadataLocation": "s3://XXXXXX/metadata/XXXXXX.metadata.json",
        "warehouseLocation": "s3://XXXXXX",
        "createdAt": "2025-02-02T00:40:19.209543+00:00",
        "createdBy": "XXXXXX",
        "modifiedAt": "2025-02-02T00:40:19.209543+00:00",
        "ownerAccountId": "XXXXXX",
        "format": "ICEBERG"
    }
    % 
    ```


## Step 3: Grant Lake Formation permissions on your table
1. Lake Formationに移動します
1. 最初にポップアップが表示されるので、「Get started」をクリックします
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/31528834-cfa5-c8b6-636f-0f09cd117384.png" width=400 />

1. ナビゲーションペインで「Data permissions」をクリックします
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/dd4078cd-7ed4-bed1-7229-a01fb60f7c4d.png"  width=200 />

1. 「Grant」をクリックします
1. 下記を指定します
    - ①.Principal:IAM users and roles
    - ②.IAM users and roles: IAMロールにクエリを実行するユーザのロールを指定
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/c00551ba-b545-96ad-fc4c-9b219ec4860d.png)
1. 下記を指定します
    - ③.Named Data Catalog resourcesを指定
    - ④.Ctalogs:データカタログを指定します
    - ⑤.Databases: 作成したnamespace
    - ⑥.Tables:作成したtable
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/4937aca8-b823-a16d-1f9c-0d53f8c4f878.png)

1. ⑦.SUperを指定し、「Grant」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/fe579650-0bea-e3e2-fa1e-a91adb5121a5.png)

1. できました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/a623b442-b601-63f4-aaf9-85f2cac870ae.png)


## Step 4: Query data with SQL in Athena

1. Athenaに移動します
1. 「エディタ」タブをクリックします
1. データで下記を指定できるようになっていました
    - データソース：AWSDataCatalog
    - カタログ：作成したカタログ（S3バケット）
    - データベース：my_namespace
    - テーブルとビュー：my_table
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/8641528d-ceb9-57ad-cfb4-75dd8b00f61e.png" width=200 />

1. クエリエディタに、下記のクエリを指定し実行します。クエリ自体は成功しました
    ```sql
    select * from my_table
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/1f7df60a-a098-9e4b-7dae-d056204eb7a8.png)

1. 下記のクエリを実行し、データを登録します
    ```sql
    INSERT INTO my_namespace.my_table
    VALUES 
        (111, 'ABC', 100),
        (222, 'XYZ', 200);
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/164b350a-71d6-6a25-4420-b17058726313.png)


1. 下記のクエリを実行し、あらためて確認します
    ```sql
    select * from my_table
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/d1c5c63c-5172-04e3-7c23-b2700c52b920.png)

# 考察
今回、S3 Tablesのチュートリアルを試してみました。
次回以降は、S3 metadataをあわせて利用してみたいと思います。

# 参考
https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables-getting-started.html

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html