QuickSightのデータセットで認証情報だけを更新

# はじめに
AWSのデータを可視化するサービス[QuickSight](https://aws.amazon.com/jp/quicksight/)。
Redshiftなどのデータソースと連携して、そのデータを可視化するのですが、
パスワードを変更したなどなどの理由により、データソースへの認証情報だけを変更したい。ということが発生します。

QuickSightのWebコンソール画面上で変更しようとすると、
認証情報だけを変更したいのに使用しているテーブルは何か？などを選択しなければならなくなり、
それをいちいち調べるのも面倒です。

AWSCLIから変更することでスムーズに対応できたので、その記録を残しておきます。

今回はデータソースがRedshiftの場合のを記載していますが、
別のタイプのデータソースであっても同じように対応できると思います。

# 手順
AWSCLIを実行する環境は、[CloudShell](https://aws.amazon.com/jp/cloudshell/)を使って作業しています。
namespaceはdefaultなので省略しています。

データセットから追っていって、データソースを特定し更新する手順となってます。

## データセットIDを求める
[list-data-sets](https://docs.aws.amazon.com/cli/latest/reference/quicksight/list-data-sets.html) でデータセットの一覧が取得できるので、その中から[jqコマンド](https://stedolan.github.io/jq/)で目的のデータセットを探します。

```shell
[cloudshell-user@ip-10-10-10-10 ~]$ aws quicksight list-data-sets --aws-account-id 111111111111 | jq '.DataSetSummaries[] | select(.Name == "データセット名") | {"Name": .Name, "DataSetId": .DataSetId}'
{
  "Name": "データセット名",
  "DataSetId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
}
[cloudshell-user@ip-10-10-10-10 ~]$ 
```

## データソースIDを求める

[describe-data-set](https://docs.aws.amazon.com/cli/latest/reference/quicksight/describe-data-set.html)でデータセットの詳細を見られるので、そこからデータセットに含まれるデータソースのデータソースIDを求めます

```shell
[cloudshell-user@ip-10-10-10-10 ~]$ aws quicksight describe-data-set --aws-account-id 111111111111 --data-set-id aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa | jq '.DataSet.PhysicalTableMap[].RelationalTable | {"DataSourceArn": .DataSourceArn, "Name": .Name}'
{
  "DataSourceArn": "arn:aws:quicksight:ap-northeast-1:111111111111:datasource/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
  "Name": "データソース名"
}
[cloudshell-user@ip-10-10-10-10 ~]$ 
```

DataSourceArnの後半bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbbがデータソースIDです。

## データソース詳細
データソースの更新に使うので、[describe-data-source](https://docs.aws.amazon.com/cli/latest/reference/quicksight/describe-data-source.html)で詳細情報を確認します。
Name、DataSourceParametersの部分を更新時に使うのでメモっておきます。

```shell
[cloudshell-user@ip-10-10-10-10 ~]$ aws quicksight describe-data-source --aws-account-id 111111111111 --data-source-id bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb
{
    "Status": 200,
    "DataSource": {
        "Arn": "arn:aws:quicksight:ap-northeast-1:111111111111:datasource/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
        "DataSourceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
        "Name": "データソース名",
        "Type": "REDSHIFT",
        "Status": "UPDATE_SUCCESSFUL",
        "CreatedTime": "2021-01-01T00:00:00.000000+00:00",
        "LastUpdatedTime": "2021-01-01T00:00:00.000000+00:00",
        "DataSourceParameters": {
            "RedshiftParameters": {
                "Host": "xxx.xxxx.ap-northeast-1.redshift.amazonaws.com",
                "Port": 5439,
                "Database": "データベース名",
                "ClusterId": "クラスターID"
            }
        },
        "SslProperties": {
            "DisableSsl": false
        }
    },
    "RequestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
[cloudshell-user@ip-10-10-10-10 ~]$
```

## 接続情報の準備
データソースの更新に使う認証情報のテンプレートファイルを用意します。
[update-data-source](https://docs.aws.amazon.com/cli/latest/reference/quicksight/update-data-source.html) をgenerate-cli-skeletonオプションをつけて実行するとテンプレートが出力されます。

```shell
aws quicksight update-data-source --generate-cli-skeleton > cred.txt
```

<details><summary>出力されたcred.txtがこちら。長いので折りたたんでいます</summary><div>

```json
{
    "AwsAccountId": "",
    "DataSourceId": "",
    "Name": "",
    "DataSourceParameters": {
        "AmazonElasticsearchParameters": {
            "Domain": ""
        },
        "AthenaParameters": {
            "WorkGroup": ""
        },
        "AuroraParameters": {
            "Host": "",
            "Port": 0,
            "Database": ""
        },
        "AuroraPostgreSqlParameters": {
            "Host": "",
            "Port": 0,
            "Database": ""
        },
        "AwsIotAnalyticsParameters": {
            "DataSetName": ""
        },
        "JiraParameters": {
            "SiteBaseUrl": ""
        },
        "MariaDbParameters": {
            "Host": "",
            "Port": 0,
            "Database": ""
        },
        "MySqlParameters": {
            "Host": "",
            "Port": 0,
            "Database": ""
        },
        "OracleParameters": {
            "Host": "",
            "Port": 0,
            "Database": ""
        },
        "PostgreSqlParameters": {
            "Host": "",
            "Port": 0,
            "Database": ""
        },
        "PrestoParameters": {
            "Host": "",
            "Port": 0,
            "Catalog": ""
        },
        "RdsParameters": {
            "InstanceId": "",
            "Database": ""
        },
        "RedshiftParameters": {
            "Host": "",
            "Port": 0,
            "Database": "",
            "ClusterId": ""
        },
        "S3Parameters": {
            "ManifestFileLocation": {
                "Bucket": "",
                "Key": ""
            }
        },
        "ServiceNowParameters": {
            "SiteBaseUrl": ""
        },
        "SnowflakeParameters": {
            "Host": "",
            "Database": "",
            "Warehouse": ""
        },
        "SparkParameters": {
            "Host": "",
            "Port": 0
        },
        "SqlServerParameters": {
            "Host": "",
            "Port": 0,
            "Database": ""
        },
        "TeradataParameters": {
            "Host": "",
            "Port": 0,
            "Database": ""
        },
        "TwitterParameters": {
            "Query": "",
            "MaxRows": 0
        }
    },
    "Credentials": {
        "CredentialPair": {
            "Username": "",
            "Password": "",
            "AlternateDataSourceParameters": [
                {
                    "AmazonElasticsearchParameters": {
                        "Domain": ""
                    },
                    "AthenaParameters": {
                        "WorkGroup": ""
                    },
                    "AuroraParameters": {
                        "Host": "",
                        "Port": 0,
                        "Database": ""
                    },
                    "AuroraPostgreSqlParameters": {
                        "Host": "",
                        "Port": 0,
                        "Database": ""
                    },
                    "AwsIotAnalyticsParameters": {
                        "DataSetName": ""
                    },
                    "JiraParameters": {
                        "SiteBaseUrl": ""
                    },
                    "MariaDbParameters": {
                        "Host": "",
                        "Port": 0,
                        "Database": ""
                    },
                    "MySqlParameters": {
                        "Host": "",
                        "Port": 0,
                        "Database": ""
                    },
                    "OracleParameters": {
                        "Host": "",
                        "Port": 0,
                        "Database": ""
                    },
                    "PostgreSqlParameters": {
                        "Host": "",
                        "Port": 0,
                        "Database": ""
                    },
                    "PrestoParameters": {
                        "Host": "",
                        "Port": 0,
                        "Catalog": ""
                    },
                    "RdsParameters": {
                        "InstanceId": "",
                        "Database": ""
                    },
                    "RedshiftParameters": {
                        "Host": "",
                        "Port": 0,
                        "Database": "",
                        "ClusterId": ""
                    },
                    "S3Parameters": {
                        "ManifestFileLocation": {
                            "Bucket": "",
                            "Key": ""
                        }
                    },
                    "ServiceNowParameters": {
                        "SiteBaseUrl": ""
                    },
                    "SnowflakeParameters": {
                        "Host": "",
                        "Database": "",
                        "Warehouse": ""
                    },
                    "SparkParameters": {
                        "Host": "",
                        "Port": 0
                    },
                    "SqlServerParameters": {
                        "Host": "",
                        "Port": 0,
                        "Database": ""
                    },
                    "TeradataParameters": {
                        "Host": "",
                        "Port": 0,
                        "Database": ""
                    },
                    "TwitterParameters": {
                        "Query": "",
                        "MaxRows": 0
                    }
                }
            ]
        },
        "CopySourceArn": ""
    },
    "VpcConnectionProperties": {
        "VpcConnectionArn": ""
    },
    "SslProperties": {
        "DisableSsl": true
    }
}
```
</div></details>

これを編集してRedshiftの認証情報だけにします。
先程のDataSourceParametersの値をもとに埋めます。
CredentialPairに新しいユーザーID/パスワードを記入します。

```json
{
    "DataSourceParameters": {
        "RedshiftParameters": {
            "Host": "xxx.xxxx.ap-northeast-1.redshift.amazonaws.com",
            "Port": 5439,
            "Database": "データベース名",
            "ClusterId": "クラスターID"
        }
    },
    "Credentials": {
        "CredentialPair": {
            "Username": "ユーザーID",
            "Password": "パスワード"
        }
    }
}
```


## 更新
[update-data-source](https://docs.aws.amazon.com/cli/latest/reference/quicksight/update-data-source.html) でデータソースの認証情報を更新するのですが、
認証情報は先ほどのjsonファイル(cred.txt)を読み込ませることで更新します。
nameオプションは必須オプションなので元と同じデータソース名を指定しておきましょう。

```shell
[cloudshell-user@ip-10-10-10-10 ~]$ aws quicksight update-data-source --aws-account-id 111111111111 --data-source-id bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb --name データソース名 --cli-input-json file:///home/cloudshell-user/cred.txt
{
    "Status": 202,
    "Arn": "arn:aws:quicksight:ap-northeast-1:111111111111:datasource/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
    "DataSourceId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
    "UpdateStatus": "UPDATE_IN_PROGRESS",
    "RequestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
[cloudshell-user@ip-10-10-10-10 ~]$ 
```

しばらくしてWebコンソールで確認すると、認証が正常に行われ、更新が正常終了したことが確認できます。