QuickSightのDefinitionを使ってみた

# はじめに
11月末に、QuickSightの分析やダッシュボードの設定をJson化（Definition）して管理できる新機能が追加されました。
[(BI トランスフォーメーションを加速する新しい Amazon QuickSight API 機能)](https://aws.amazon.com/jp/blogs/aws/new-amazon-quicksight-api-capabilities-to-accelerate-your-bi-transformation/)
今までは中身を見ることのできないTemplateファイルで管理をしていたため、ようやくQuickSightでもIaCが可能になった形になります。
今回はこの機能を試してみたので、メモとして残しておこうと思います。

# 使ってみた
## とりあえずDefinitionを取得してみる

元となる分析はこちら（URL適当なのはご愛嬌）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658635/8fda3ed1-a633-344b-3bba-d494b58c4115.png)

今回はpythonのboto3で操作していきます。
新しく追加された describe_analysis_definitionを使ってdefinitionが取得できます。（使えない場合は、boto3をアップデートしてみてください）
```py
import boto3

client = boto3.client('quicksight')
res = client.describe_analysis_definition(
    AwsAccountId='123456789012',
    AnalysisId='test_analysis'
)
definition = res['Definition']
```

definitionの中身はこちら。結構複雑なので、かなり端折ってます。
```sh
{
    "DataSetIdentifierDeclarations": [
        {
            "Identifier": "test_data",
        }
    ],
    "Sheets": [
        {
            "SheetId": "a562c4c6-d3ad-413d-a708-6c4720f65a88",
            "Name": "シート 1",
            "Visuals": [
                {
                    "TableVisual": {},
                }{
                    "CustomContentVisual": {
                            "ChartConfiguration": {
                                "ContentUrl": "https://test_definition.com"
                            }
                    }
                }
            ],
            "Layouts": [],
            "ContentType": "INTERACTIVE"
        }
    ],
    "CalculatedFields": [],
    "ParameterDeclarations": [],
    "FilterGroups": [],
    "AnalysisDefaults": {}
}
```
Sheetが1枚有り、その中にVisualが2種類あるという構造は見て取れると思います。


## 取得したDefinitionを使って、新しく分析を作ってみる
ひとまず、全く同じ見た目の分析を作成してみます。
create_analysisでdefinitionを指定できるようになったので、それを使います。
```py
client.create_analysis(
    AwsAccountId='123456789012',
    AnalysisId='copy_analysis',
    Name='copy_analysis',
    Definition={先ほど取得したdefinition}
)
```
全く同じ見た目の分析が出来上がりました。
ちなみに、上のcreate_analysisコマンドだと誰にも権限がつかないため、別途自分で見れるように権限を付ける必要があることにはご注意を
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658635/d2417b3c-a62b-40a6-fe3b-b93716836d6e.png)


新しく作った分析のdefinitionを見てみると各種Idが元となった分析と同じため少し不安になりましたが、それぞれの分析は独立して連動したりすることはありませんでした。（当たり前ですが一安心）

## カスタムビジュアルコンテンツのURLを書き換えて上書きしてみる
ちょっと場所の特定が面倒ですが、definitionの中に埋め込んだURLも記述されているため、その中身を書き換えます。
そして、書き換えたdefinitionを使って分析をアップデート。
```py
definition['Sheets'][0]['Visuals'][1]['CustomContentVisual']['ChartConfiguration']['ContentUrl'] = 'https://new_test_definition.com'
client.update_analysis(
    AwsAccountId='123456789012',
    AnalysisId='copy_analysis',
    Name='copy_analysis',
    Definition=definition
)
```
URLが書き換わりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658635/78d8e2a0-6624-d2e4-d80a-4a9fdd31e244.png)
URLを埋め込むときに環境に応じて
https://dev~ -> https://prod~
と書き換えたい時があったのですが、今までは手作業でやってました。
今回のアップデートで自動化できそうなのでありがたいです。

## 一部のビジュアルだけ削除して、ダッシュボードを作成してみる
先ほどURLを書き換えたカスタムビジュアルコンテンツを今度は消してみましょう。
definitionから、該当のビジュアルの設定を削除します。
（実は端折ったLayoutsの中身にも設定がいるので、そちらも削除してます。）
```sh
{
    "DataSetIdentifierDeclarations": [
        {
            "Identifier": "test_data",
        }
    ],
    "Sheets": [
        {
            "SheetId": "a562c4c6-d3ad-413d-a708-6c4720f65a88",
            "Name": "シート 1",
            "Visuals": [
                {
                    "TableVisual": {},　#ビジュアルが1つになってます。
                }
            ],
            "Layouts": [],
            "ContentType": "INTERACTIVE"
        }
    ],
    "CalculatedFields": [],
    "ParameterDeclarations": [],
    "FilterGroups": [],
    "AnalysisDefaults": {}
}
```

そのdefinitionを使って、ダッシュボードを作成。
create_dashboardでもdefinitionを指定できます。
```py
client.create_dashboard(
    AwsAccountId='123456789012',
    DashboardId='test_dashboard',
    Name='test_dashboard',
    Definition={上で書き換えたdefinition}
)
```
ビジュアルが1つだけになりました。
座標の設定はいじってないので、もともとカスタムビジュアルがいた場所は空欄になってますね。
ちなみに、上のcreate_dashboardコマンドだと誰にも権限がつかないため、（以下略）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658635/cc8f072d-ef2d-5057-85c3-10f148c218f3.png)

流石に１から新しいビジュアルをJsonで用意するのは厳しそうですが、特定のビジュアルを削除するくらいなら簡単にできそうですね。

## 結論
Definitionを使って、思いついた簡単な使い方を試してみました。

Jsonがそこそこ大きいので管理するのが大変そうですが、他にも色々と使い方はありそうです。
QuickSightもどんどんアップデートされているので、今後より使いやすくなるかもしれません。
さらなる体験の向上に期待ですね!