QuickSight埋め込みダッシュボードの検証をとりあえず行いたいときのために、S3静的Webサイトホスティングを使ってみました

2020.12.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

いわさです。

QuickSightのダッシュボードは外部Webサイトのページへ埋め込むことが出来ます。
どのような感じで埋め込まれるのか、オプションを変更するとどうなるのか、などの検証を行いたかったのですが、サーバーサイドを用意するのが少し面倒だなと感じていました。

今回、Amazon S3の静的ウェブサイトホスティングでHTML上に埋め込み、 ダッシュボードの公開URLはAWS CLIで随時発行することで検証用途には使えるだろうということで、構築手順を残しておきます。

前提

Embedding QuickSight Data Dashboards for Everyone

上記公式手順を参考にしていますが手順が少なくなるよう少し変更しています。
また、スイッチロール環境で一部うまくいかない箇所があったので認証をIAMからQUICKSIGHTに変更しています。

QuickSightアカウントとAWSCLI環境は以下を参考に準備してください。

Amazon S3設定

まずはWebサイトをホストする環境を用意します。

静的ウェブサイトホスティング用に S3 バケットを設定する方法

AmazonS3で任意の名前のバケットを作成します。
作成時に、「パブリックアクセスをすべてブロック」のチェックを外してください。

「静的ウェブサイトホスティング」設定を有効にします。
インデックスドキュメントにindex.html、エラードキュメントにerror.htmlを設定しておきます。

更に、バケットポリシーの追加を行います。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<バケット名>/*"
        }
    ]
}

バケット概要にて、パブリックにアクセス可能」が表示されてればOKです。

試しに以下のHTMLファイルを作成して、アップロードしておきます。

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    hoge
  </body>
</html>

バケットの静的Webサイトホスティングの設定から、パブリックウェブサイトエンドポイントを控えておきます。

CloudFront設定

このままでも静的Webサイトとしては最低限機能しますが、HTTPSに対応出来ていません。
さらにQuickSightのダッシュボード埋め込み先はHTTPSドメインでなければならない制約があります。

CloudFrontを使うことでS3静的ウェブサイトのHTTPS化を行うことが出来るので対応します。

マネジメントコンソールからCloudFrontを選択し、"Create Distribution"を選択します。

Web の "Get Started" で進めます。

"Origin Domain Name" をフォーカスするとバケット候補が表示されるので、先程作成したバケットを選択します。
ただし、このままだとCDNドメインでアクセスした際にオリジンにリダイレクトされてしまうことがあります。

以下を参考に、先程控えたS3バケットのFQDNを入力しましょう。
S3+CloudFrontでS3のURLにリダイレクトされてしまう場合の対処法

作成されたら、CDNのDomain NameにHTTPSでアクセスしてみましょう。

先程作成した、サンプルHTMLが表示されればOKです。

QuickSightの埋め込みダッシュボード設定

QuickSightのダッシュボードは初期状態では埋め込みできるようになっていません。
今回は初期サンプルの分析結果を使って、ダッシュボードの作成と埋め込みのための設定を行っていきます。

"分析"で任意のサンプルを選択してください。

分析画面に遷移したら右上のメニューから "ダッシュボード追加" を選択してください。

任意のダッシュボード名を入力します。

"このアカウントのすべてのユーザーと共有する" のチェックを外します。

作成されたダッシュボードのURLの末尾のID(ダッシュボードID)を控えておきます。

埋め込みダッシュボードは埋め込み先をホワイトリストで管理しなければならない制約があります。
メニューの「QuickSightの管理」から管理画面へ遷移し、"ドメインと埋め込み"セクションで先程CloudFrontにて作成したドメインを入力します。

埋め込み作業

ダッシュボードを埋め込んだHTMLを作成し、S3コンテンツを更新します。
実際の実装時にはまずはこれ以降の作業をサーバーサイドで実装することになると思います。

AWS CLIにて以下のコマンドを実行します。
aws-account-id, region, profileは環境にあわせて適宜変更してください。

dashboard-idは先程控えたダッシュボードのIDです。

list-usersでUserArnを確認し、get-dashboard-embed-urlで使用しています。

iwasa.takahito@iwasa quicksightembed1225 % aws quicksight list-users --aws-account-id 111222333444 --namespace default --region ap-northeast-1 --profile iwasa
{
    "Status": 200,
    "UserList": [
        {
            "Arn": "arn:aws:quicksight:ap-northeast-1:111222333444:user/default/cm-iwasa.takahito/cm-iwasa.takahito",
            "UserName": "cm-iwasa.takahito/cm-iwasa.takahito",
            "Role": "ADMIN",
            "IdentityType": "IAM",
            "Active": true,
            "PrincipalId": "federated/iam/AROAYANTVHXID7QJ5BJH2:cm-iwasa.takahito"
        }
    ],
    "RequestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
iwasa.takahito@iwasa quicksightembed1225 % aws quicksight get-dashboard-embed-url --aws-account-id 111222333444 --dashboard-id "ffffffff-ffff-ffff-ffff-ffffffffffff" --identity-type QUICKSIGHT --user-arn "arn:aws:quicksight:ap-northeast-1:111222333444:user/default/cm-iwasa.takahito/cm-iwasa.takahito" --profile iwasa
{
    "Status": 200,
    "EmbedUrl": "https://ap-northeast-1.quicksight.aws.amazon.com/embed/d3ea2f13f53d4cb0842e3c641e004476/dashboards/17ee7de2-ce26-40dc-9086-bf6d20ad5cad?code=AYABeIlccLb8hLR5I9wKYvl0jS8AAAABAAdhd3Mta21zAFBhcm46YXdzOmttczphcC1ub3J0aGVhc3QtMTozNjcwOTQ1NjE4OTQ6a2V5LzkyZDU3MjEzLTc0MjItNGNhOC1iYWZiLTg2MDFjNGZkODgyNwC4AQIBAHirSky28MTsQkRRkQnrWly9-KCD9GJ1rJU8zazSG85WsgGRXbTrWq16-ZJrZQLMhVeSAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMsUDSJPN5W5huHj2GAgEQgDs-vFHuw-H1RfZKXFFjantjNmjWYOhr9BZEYv1FTanoLY5qWQRpS2ObjDicIZHLJ_OMCWIed5XSNW0U2AIAAAAADAAAEAAAAAAAAAAAAAAAAACceAmAKsaK1Eb7KiSUbZ_M_____wAAAAEAAAAAAAAAAAAAAAEAAADqEK6dgbNT2aX_mbX572Qndejaz6bmHBH9V7MTSN5YCaMNEv9bYFMjZg7KgQMrcdaPeDrs5cjqvn3j2h2WcC2S4qboaPu0F_RIINJcMBCT9a3pRtYbCYTaDCToWpFhlMKf-mF7BVjFOx8eGHvRkdwnjVXGD2rbg33r3BXizT0NZWgLgs38oMGp6AB9ABp85hEtIBpGY2QXOG85MJoLxfqyR883YQ8uW2eOpmCAfMjHFmBgzHC3V9tGimKPB0G4QmNxrSvIn3zlrkdn0bo6dWY0zseHGRpBhI3lP5RRSTnlzpT636UvFH_4mBOcEut-Ai7fR2EUUpekVxIoSQ%3D%3D&identityprovider=quicksight&isauthcode=true",
    "RequestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
iwasa.takahito@iwasa quicksightembed1225 %

上記レスポンスの、EmbedUrlをコピーしてindex.htmlを更新します。(optionsのurl部分)

<!DOCTYPE html>
<html>
<head>
    <title>Basic Embed</title>
    <script src="https://unpkg.com/amazon-quicksight-embedding-sdk@1.0.12/dist/quicksight-embedding-js-sdk.min.js"></script>
    <script type="text/javascript">
        var dashboard;

        function embedDashboard() {
            var containerDiv = document.getElementById("embeddingContainer");
            var options = {
                url: "https://ap-northeast-1.quicksight.aws.amazon.com/embed/d3ea2f13f53d4cb0842e3c641e004476/dashboards/17ee7de2-ce26-40dc-9086-bf6d20ad5cad?code=AYABeIlccLb8hLR5I9wKYvl0jS8AAAABAAdhd3Mta21zAFBhcm46YXdzOmttczphcC1ub3J0aGVhc3QtMTozNjcwOTQ1NjE4OTQ6a2V5LzkyZDU3MjEzLTc0MjItNGNhOC1iYWZiLTg2MDFjNGZkODgyNwC4AQIBAHirSky28MTsQkRRkQnrWly9-KCD9GJ1rJU8zazSG85WsgGRXbTrWq16-ZJrZQLMhVeSAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMsUDSJPN5W5huHj2GAgEQgDs-vFHuw-H1RfZKXFFjantjNmjWYOhr9BZEYv1FTanoLY5qWQRpS2ObjDicIZHLJ_OMCWIed5XSNW0U2AIAAAAADAAAEAAAAAAAAAAAAAAAAACceAmAKsaK1Eb7KiSUbZ_M_____wAAAAEAAAAAAAAAAAAAAAEAAADqEK6dgbNT2aX_mbX572Qndejaz6bmHBH9V7MTSN5YCaMNEv9bYFMjZg7KgQMrcdaPeDrs5cjqvn3j2h2WcC2S4qboaPu0F_RIINJcMBCT9a3pRtYbCYTaDCToWpFhlMKf-mF7BVjFOx8eGHvRkdwnjVXGD2rbg33r3BXizT0NZWgLgs38oMGp6AB9ABp85hEtIBpGY2QXOG85MJoLxfqyR883YQ8uW2eOpmCAfMjHFmBgzHC3V9tGimKPB0G4QmNxrSvIn3zlrkdn0bo6dWY0zseHGRpBhI3lP5RRSTnlzpT636UvFH_4mBOcEut-Ai7fR2EUUpekVxIoSQ%3D%3D&identityprovider=quicksight&isauthcode=true",  
                container: containerDiv,
                scrolling: "no",
                height: "700px",
                width: "1000px",
                footerPaddingEnabled: true
            };
            dashboard = QuickSightEmbedding.embedDashboard(options);
        }
    </script>
</head>

<body onload="embedDashboard()">
    <div id="embeddingContainer"></div>
</body>

</html>

更新したindex.htmlをS3にアップロードします。

CloudFrontのキャッシュをクリアします。
Distribution Settingsを選択します。

Invalidationsタブで Create Invalidationを選択します。

Objects Pathsに "/*" を入力します。

キャッシュクリアされるので、CloudFrontのURLへアクセスしてみます。

ダッシュボードが埋め込まれました!

おまけ:失敗パターン

以下はCLIで発行したURLの有効期間が失効してしまった場合です。
URLの有効期間は、なんと5分です。

以下は、ダッシュボードIDが間違っているなど、QuickSight上で権限の問題などでオブジェクトにアクセスできない場合です。

さいごに

発行URLが5分しか有効ではないので、サーバーサイドで都度動的に埋め込みURLを管理することが前提となっていそうです。
とはいえ、サーバーサイドのSDKの利用を前提としているわけではないのでS3静的Webサイトホスティングも検証用には使えるかなと思いました。