【Amazon QuickSight】共有フォルダのエクスポートとインポートについての検証

## はじめに
こんにちは。
株式会社ジールの@y_seimiya_zdhです。
2024年10月にアップデートが発表された「[Amazon QuickSight でプログラムによる共有フォルダのエクスポートとインポートがサポート開始](https://aws.amazon.com/jp/about-aws/whats-new/2024/10/amazon-quicksight-programmatic-export-import-shared-folders/)」について検証を行いました。

QuickSightではいくつかの方法で、アセットの移行やバックアップが可能ですが、今回のアップデートではAssetBundleJob系のAPIについて、共有フォルダを指定してフォルダ内のアセットを再帰的に取得することが可能になりました。

## 1.背景
### AssetBundleとは
ダッシュボードやデータセットなどのアセットを１つのファイルにまとめ、エクスポート・インポートを可能な状態にしたものです。AssetBundleを使用することにより、１度で複数のアセットを他のユーザーと共有や、異なる環境への移行が可能になり、効率的に移動や共有を行うことができます。

### AssetBundleJobとは
QuickSightAPIの一種であり、アセットの定義情報をjson形式で取得することが可能です。上記であればQuickSightのdescribe系のAPI(DescribeAnalysisDefinitionなど)でも可能ですが、AssetBundleJobは「依存するすべてのアセットをエクスポート」できる点が特徴です。

### AssetBundleJob関連のAPIについて
AssetBundleJob系のAPIは、ジョブを開始するものと、ジョブの詳細を取得するもの、過去のジョブ一覧を取得するものがあります。
#### ジョブ開始系API
* [StartAssetBundleExportJob](https://docs.aws.amazon.com/quicksight/latest/APIReference/API_StartAssetBundleExportJob.html#API_StartAssetBundleExportJob_RequestSyntax)：エクスポートジョブの開始
* [StartAssetBundleImportJob](https://docs.aws.amazon.com/quicksight/latest/APIReference/API_StartAssetBundleImportJob.html)：インポートジョブの開始

#### ジョブ詳細取得API(Describe系)
* [DescribeAssetBundleExportJob](https://docs.aws.amazon.com/quicksight/latest/APIReference/API_DescribeAssetBundleExportJob.html)：エクスポートジョブの詳細(実行状況・jsonのDL用URLの取得)
* [DescribeAssetBundleImportJob](https://docs.aws.amazon.com/quicksight/latest/APIReference/API_DescribeAssetBundleImportJob.html)：インポートジョブの詳細(実行状況・完了ステータス)

#### ジョブ一覧取得API
* [ListAssetBundleExportJobs](https://docs.aws.amazon.com/quicksight/latest/APIReference/API_ListAssetBundleExportJobs.html)：過去 14 日間のエクスポートジョブ一覧
* [ListAssetBundleImportJobs](https://docs.aws.amazon.com/quicksight/latest/APIReference/API_ListAssetBundleImportJobs.html)：過去 14 日間のインポートジョブ一覧

## 2.検証内容
### 検証１：フォルダ内の再帰的取得について
StartAssetBundleExportJobを実行し、共有フォルダ内の下層のアセットについても問題なくエクスポートできるかを確認します。

### 検証２：出力したアセットのインポートについて
出力したアセットに対してStartAssetBundleImportJobを実行し 、問題なくインポート可能か確認します。
    
### 検証３：複数アカウント間でのエクスポート・インポートについて
出力したアセットを、別アカウントにて問題なくインポート可能か確認します。

### 検証４：エクスポートされる「.qsファイル」とDescribe系APIとの差について
検証１にて出力した「.qsファイル」に対して手動で「.zip」に書き換えてjsonファイルとして解凍します。Describe系APIで取得した定義情報とどのような差があるか確認します。

## 3.検証手順・検証結果
### 検証１：フォルダ内の再帰的取得について
下記手順の元、QuickSightに共有フォルダを作成、各アセットを配置しStartAssetBundleExportJobを実行します。
IncludeFolderMembers=RECURSEとしているため、フォルダ内のすべてのアセットが問題なくエクスポートできることを確認できました。

<details><summary>検証手順</summary>

①QuickSight上に共有フォルダを作成し、共有フォルダ内にデータセット・分析・ダッシュボードを配置
![01. アセット配置.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/21ac7fad-8c1b-4df0-92ef-52f608331935.png)

②AWSのCloud Shellにて下記コマンドを実行し、共有フォルダのARNを確認
```
aws quicksight list-folders --aws-account-id [AWSアカウントID]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/ebae7d7a-8a76-4b12-a98f-6e83209ad683.png)


③以下のコマンドを実行し、アセットのエクスポートを開始
```
aws quicksight start-asset-bundle-export-job --aws-account-id [AWSアカウントID] --asset-bundle-export-job-id [ジョブ名] --resource-arns [②で確認したARN] --include-all-dependencies --include-folder-members RECURSE --export-format QUICKSIGHT_JSON
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/84781621-b4bd-4aea-a7e7-32145f72279f.png)
※設定値IncludeFolderMembersとIncludeFolderMembershipsの差異について
・IncludeFolderMemberships
　リソースに関連するメンバーシップ情報をエクスポートする
・IncludeFolderMembers
　「RECURSE」の場合、フォルダ下のアセットもExport対象になる

④以下のコマンドを実行し、アセットのダウンロードを実施
```
aws quicksight describe-asset-bundle-export-job --aws-account-id [AWSアカウントID] --asset-bundle-export-job-id [ジョブ名]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/c350002c-825a-4e27-ae67-0f025eba9ca4.png)

⑤Cloud Shell にダウンロードしたアセットをアップロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/1c3ffe04-6673-4275-9eef-c66f226db40d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/e18f9b38-420d-4991-b41b-3b59d2abed2b.png)

⑥以下のコマンドでアセットを解凍
```
unzip [ダウンロードファイル名]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/f26ac0af-d4ac-4a73-b504-b0461fffde09.png)

</details>

### 検証２：出力したアセットのインポートについて
下記手順の元、検証１にて出力されたアセットに対して、ImportJobを実行します。
実行後、共有フォルダ内にすべてのアセットがインポートされていることが確認できました。
また、一部のアセットのみインポートにつきましても可能であるようです。
ただし、依存関係となるアセットがインポート先のQuickSight上に存在している場合といった条件下においてインポートすることが可能です。
例えば、QuickSight上にanalysisの依存関係となるデータセットが存在している場合、analysisのみのインポートが可能になる、といった条件があります。

<details><summary>検証手順</summary>

①Quicksightから「検証①」で作成した共有フォルダを削除しておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/cc83587a-6d33-495c-9c17-0bebb07c28b4.png)
※共有フォルダが存在する状態で、ExportしたアセットをImportすると変化がないため、元のアセットが存在する場合、正常にImportが行われない。

②S3バケットに「検証1-1」でExportしたアセットをアップロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/ad81e73d-0bce-4408-bc25-0b1a6f30717f.png)

③以下のコマンドを実行し、アセットをインポート
```
aws quicksight start-asset-bundle-import-job --aws-account-id [AWSアカウントID] --asset-bundle-import-job-id [ジョブ名] --asset-bundle-import-source [S3バケットパス] --region [リージョン名]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/7edc1580-a2bd-495e-84ff-934f6ca4859b.png)


④以下のコマンドを実行し、インポートが実行されたことを確認
```
aws quicksight describe-asset-bundle-import-job --aws-account-id [AWSアカウントID] --asset-bundle-import-job-id [ジョブ名] --region [リージョン名]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/d5a6080a-08f5-49c2-87ee-76505ff75fb1.png)


⑤共有フォルダを確認するが、閲覧権限が無いためフォルダが表示されない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/87b19520-121c-4b7f-bc04-29a18db9b1af.png)

⑥設定から「QuickSightを管理」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/388c8719-04e0-4450-a667-edfc49e7e221.png)

⑦メニューから「アセットの管理」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/bf9119f3-fb71-462f-88fd-54b676c30150.png)

⑧共有フォルダの共有を行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/01c7e22d-1e38-43b1-8488-d29338e0010f.png)

⑨設定後、共有フォルダを再度確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/9426d086-2746-409c-8d35-8d38140b8cb6.png)

問題なくインポートが行われています。
</details>

### 検証３：複数アカウント間でのエクスポート・インポートについて
下記手順にて環境Aのアセットをエクスポートし、環境Bにインポートを行いました。
ただし、インポート先環境のアセットと連携する項目は、コマンド実行時に--override-parametersによる設定値の上書きが必要になります。

<details><summary>検証手順</summary>

環境Aのアセットをエクスポートし、環境Bにインポートを行います。

①環境Aにデータセット・分析・ダッシュボードを含む共有フォルダを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/8642aee5-a443-454c-8f39-90ae7b43cfd6.png)

②AWSのCloud Shellにて下記コマンドを実行し、共有フォルダのARNを確認
```
aws quicksight list-folders --aws-account-id [AWSアカウントID]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/589c8190-be8e-4760-bd70-7ce9bb9e27d4.png)

③下記コマンドを実行し、エクスポートを開始
```
aws quicksight start-asset-bundle-export-job --aws-account-id [AWSアカウントID] --asset-bundle-export-job-id [ジョブ名] --resource-arns [3.で確認したARN] --include-all-dependencies --include-folder-members RECURSE --export-format QUICKSIGHT_JSON
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/952f571e-10e8-4a78-bf5e-e9301b9065cb.png)


④下記コマンドを実行し、ダウンロード
```
aws quicksight describe-asset-bundle-export-job --aws-account-id [AWSアカウントID] --asset-bundle-export-job-id [ジョブ名]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/3e5a846a-d79c-4ffd-bb27-987445eeb023.png)


⑤環境BのS3にデータソースとマニフェストファイルをアップロード
※アセットは環境Aのデータソース・マニフェストファイルを参照しているが、環境Bより閲覧する権限がないためエラーが発生する。そのため環境Bにも同様のデータソース・マニフェストファイルを配置し、参照させる必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/b9b2621f-8f3b-408d-b599-17c4e4790335.png)

⑥下記コマンドを環境Bにて実行し、インポート
```
aws quicksight start-asset-bundle-import-job --aws-account-id [AWSアカウントID] --asset-bundle-import-job-id [ジョブ名] --asset-bundle-import-source [S3バケットパス] --override-parameters '{"DataSources": [{"DataSourceId": [データソースID], "DataSourceParameters":{ "S3Parameters": {"ManifestFileLocation": {"Bucket": [S3バケット名], "Key": [マニフェストファイルのパス]}}}}]}' --region [リージョン名]
```
※「DatasourceId」はエクスポートしたqsファイルを展開し、「datasource」フォルダを確認する

⑦下記コマンドを実行し、インポートされたことを確認
```
aws quicksight describe-asset-bundle-import-job --aws-account-id [AWSアカウントID] --asset-bundle-import-job-id [ジョブ名] --region [リージョン名]
```

⑧QuickSightにてインポートしたアセットに閲覧許可をかける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/0c4b084c-37b2-4046-b138-b3eaea4f9491.png)

⑨共有フォルダを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/a2b9851e-f742-4666-bd70-b2acfc7ceb37.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/1d0c9841-6000-44e4-b589-a17d9b360329.png)

複数アカウント間でのインポート・エクスポートが確認できました。

</details>

### 検証４：エクスポートされる「.qsファイル」とDescribe系APIとの差について
下記手順にて検証を行い、それぞれの確認結果は以下の通りとなりました。

#### 分析・ダッシュボード
- definition内の構造は同一である
- folderArns：jsonファイルには含まれているが、describeAPI出力には含まれていない
- validationStrategy：jsonファイルには含まれているが、describeAPI出力には含まれていない

#### データセット
- 物理テーブル(physicalTableMap)と論理テーブル(logicalTableMap)は同一である
- folderArns：jsonファイルには含まれているが、describeAPI出力には含まれていない
- DataSetUsageConfiguration：jsonファイルはfalseとなっているが、describeAPI出力ではDisableUseAsDirectQuerySourceとDisableUseAsImportedSourceと記載されている

#### データソース
- dataSourceParametersは同一である
- jsonファイルでは、Status、CreatedTime、LastUpdatedTime、RequestIdが含まれていない
- describeAPI出力では、Status、CreatedTime、LastUpdatedTime、RequestIdが含まれている
    
#### フォルダ
- folderID、name、folderType、sharingModelは同一である
- jsonファイルでは、作成時間(CreatedTime)や更新時間(LastUpdatedTime)に関する情報が含まれていない
- describeAPI出力では、作成時間(CreatedTime)や更新時間(LastUpdatedTime)が含まれている

<details><summary>検証手順</summary>

①検証１でエクスポートしたアセットの拡張子を「.zip」に変更し展開
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/67da4eeb-38fa-47e6-93ea-49004f6c9794.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/48eaed65-bafe-4a22-9789-7c36c1dd3a80.png)

②フォルダの中身がjsonファイルになっていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3987323/cf87562e-3656-49b7-87d9-ecbf4feda55c.png)


③DescribeAPIにて定義情報を取得

「analysis」の部分を下記アセットに変更し、各IDを取得
- 各ID確認
    - analysis
    - dashboards
    - data-sets
    - data-sources
    - folders
```
aws quicksight list-analysis --aws-account-id [AWSアカウントID]
```


- 定義情報取得
上記にて取得した各IDにて、各定義情報取得
```
aws quicksight describe-analysis --analysis-id [ANALYSISID] --aws-account-id [AWSアカウントID]
```

</details>

## おわりに
今回はAWS QuickSightの共有フォルダのエクスポートとインポートについて検証を行いました。複数環境でのエクスポート・インポートを活用することで、複数チームやアカウント間で同じ環境を再現することが可能となり、業務効率化に対して有効であると考えられます。

## 参考資料
[1][Amazon QuickSight でプログラムによる共有フォルダのエクスポートとインポートがサポート開始](https://aws.amazon.com/jp/about-aws/whats-new/2024/10/amazon-quicksight-programmatic-export-import-shared-folders/)
[2][StartAssetBundleExportJob](https://docs.aws.amazon.com/quicksight/latest/APIReference/API_StartAssetBundleExportJob.html#API_StartAssetBundleExportJob_RequestSyntax)
[3][StartAssetBundleImportJob](https://docs.aws.amazon.com/quicksight/latest/APIReference/API_StartAssetBundleImportJob.html)
[4][DescribeAssetBundleExportJob](https://docs.aws.amazon.com/quicksight/latest/APIReference/API_DescribeAssetBundleExportJob.html)
[5][DescribeAssetBundleImportJob](https://docs.aws.amazon.com/quicksight/latest/APIReference/API_DescribeAssetBundleImportJob.html)
[6][ListAssetBundleExportJobs](https://docs.aws.amazon.com/quicksight/latest/APIReference/API_ListAssetBundleExportJobs.html)
[7][ListAssetBundleImportJobs](https://docs.aws.amazon.com/quicksight/latest/APIReference/API_ListAssetBundleImportJobs.html)

---
株式会社ジールでは、「ITリテラシーがない」「初期費用がかけられない」「親切・丁寧な支援がほしい」「ノーコード・ローコードがよい」「運用・保守の手間をかけられない」などのお客様の声を受けて、オールインワン型データ活用プラットフォーム「ZEUSCloud」を月額利用料にてご提供しております。
ご興味がある方は是非下記のリンクをご覧ください。

https://www.zdh.co.jp/products-services/cloud-data/zeuscloud/?utm_source=qiita&utm_medium=referral&utm_campaign=qiita_zeuscloud_content-area