RareJob Tech Blog

レアジョブテクノロジーズのエンジニア・デザイナーによる技術ブログです

Amazon QuickSightで作成したダッシュボードの埋め込みURL生成について

こんにちは、文教事業サービス開発部の塚本です。
私ですが、株式会社ボーダーリンク(株式会社レアジョブのグループ会社)が提供している「ボーダーリンク英会話」や「リップルキッズパーク」といった文教・子ども向けオンライン英会話サービスの開発ディレクションを担当しています。

今回は、直近導入したAmazon QuickSightについて、QuickSight内で作成したダッシュボードをプロダクト内の管理サイトに埋め込む方法について説明していこうと思います。 ダッシュボード本体の作成については今回触れず、作成したダッシュボードを運用している既存のサイトに埋め込む方法にフォーカスした内容となっています。

Amazon QuickSightとは

AWSが提供するBIサービスになります。ダッシュボードを作成することで、データの可視化や分析、共有が可能となります。 docs.aws.amazon.com

導入の目的

運用にかかる工数の削減が大きな目的になります。事業側からデータ抽出の依頼がほぼ日次で発生しており、中には同じSQLを毎回実行する形で対応することもありました。開発にかける工数を増やすためにも、運用にかける工数は削減したいと考えており、いくつか解決案を検討したところ、今回はAmazon QuickSightを導入し解決する形になりました。 具体的には、毎回実行していたSQLを元にデータセットを作成し、そのデータセットを元にダッシュボードを作成することで、必要な数値を可視化しました。結果として、事業側のメンバーがダッシュボードを参照することで、要望を満たせることが確認できました。

注意点

ただし、通常の利用方法ですとダッシュボードを作成・管理する開発エンジニア以外に、ダッシュボードを参照する事業側のメンバー分もQuickSightのアカウントを作成する必要があります。そのため、このまま導入すると、既存の業務に加えアカウント管理もプロダクトチームで行うことになります。チーム内で話し合ったところ、アカウント管理に工数をかけることは避け、別の方法で解決できないか探ることになりました。調査したところ、QuickSightのAPIであるGenerateEmbedUrlForAnonymousUserを利用することで、QuickSightのアカウントを持たないユーザーに対しても、ダッシュボードを共有・公開できることが分かりました。具体的な実装については後述しますが、追加の設定としてプランをユーザー単位の課金形態(デフォルト)から、セッション単位の課金形態である「キャパシティ価格」へ変更する必要があります。変更方法としては、Amazon QuickSightの右上にありますユーザーアイコンから「Manage QuickSight」を選択し、サイドメニュー「Manage pricing」から「Readers」のオプションをActiveにします。 「キャパシティ価格」に変更することで、ひと月500セッションあたり250ドルの料金がかかりますので、こちらも合わせてご注意ください。 (料金の詳細については、公式ドキュメントをご参照ください)

Readersのオプション
aws.amazon.com

実装

ここからは、ダッシュボードを埋め込むための実装について説明していきます。 前提として、今回は「ボーダーリンク英会話」の管理サイト(主に事業側のメンバーが利用するサイトで、レッスン・顧客管理などを行うサイト)に、ダッシュボード表示用ページを新規で作成し、そのページに開発側で作成したQuickSightダッシュボードを埋め込みます。 流れとしては、以下のようになります。

  1. ダッシュボード表示用ページにユーザーがアクセスする。
  2. バックエンド側でAPIを実行し、EmbedUrlという埋め込み用URLを動的に生成する。
  3. EmbedUrlをフロント側に渡し、ダッシュボードを表示させる。

基本的な手順としては、以下のドキュメントに沿う形で、IAMポリシーの設定とAPI実行処理を実装していきます。 docs.aws.amazon.com

AWS側の設定

IAMポリシーとしては、以下のようになります。

  • Action:APIが実行できるようGenerateEmbedUrlForAnonymousUserを記載します。
  • Resource:dashboardとnamespaceを指定し、ポリシーを適用するリソースを指定します。
  • Condition:指定したドメインからのみ、埋め込みURLの利用が許可されます。

このIAMポリシーですが、管理サイトが稼働しているEC2用に作成されたIAMロールに追加します。それにより、アプリケーションからAPIを実行できるようになります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "quicksight:GenerateEmbedUrlForAnonymousUser"
            ],
            "Resource": [
                "arn:aws:quicksight:{{region}}:{{accountId}}:dashboard/*",
                "arn:aws:quicksight:{{region}}:{{accountId}}:namespace/default"
            ],
            "Condition": {
                "ForAllValues:StringEquals": {
                    "quicksight:AllowedEmbeddingDomains": [
                        "https://sample.domain.com"
                    ]
                }
            }
        }
    ]
}

管理サイト側の処理

ダッシュボード表示用ページにアクセスした際に、Controllerから呼び出されるService部分にAPI実行処理を実装します。 Controllerについてはシンプルで、Service内に定義した埋め込みURL生成メソッドを呼び出し、そのレスポンスである埋め込み用URL(EmbedUrl)をViewに渡すだけになります。 Viewでは、埋め込み用URL(EmbedUrl)をiframe内で表示させます。 Serviceについては、generateEmbedURLメソッド内でAPIを実行します。実行に必要なパラメータとしては、以下になります。

  • AllowedDomains:埋め込み可能なURLが使用できるドメイン。管理サイトのドメインが該当。
  • AuthorizedResourceArns:埋め込みに利用するダッシュボードのARN。
  • AwsAccountId:AWSのアカウントID。AWS STSのGetCallerIdentity APIを実行して取得。
  • ExperienceConfiguration - Dashboard:埋め込みアセットの種類。今回はダッシュボード(Dashboard)を利用。
  • Namespace:QuickSightの名前空間。特に指定がなければ、defaultを利用。
  • SessionLifetimeInMinutes:埋め込み可能なURLの有効期間。

実装例

<?php

# インポート部分は省略

class QuickSightService
{
    private $client;

    # QuickSightクライアントの生成
    public function __construct()
    {
        $this->client = new QuickSightClient([
            'version' => 'latest',
            'region'  => env('DEFAULT_REGION')                     
        ]);
    }

    # EmbedURLの生成
    # 環境変数からAPI実行に必要なパラメータを取得
    public function generateEmbedURL()
    {
        $result = [];
        try {
            $account_id = $this->getAccountId();
            $result = $this->client->generateEmbedUrlForAnonymousUser([
                'AllowedDomains' => [env('URL')],
                'AuthorizedResourceArns' => [env('RESOURCES')],
                'AwsAccountId' => $account_id,
                'ExperienceConfiguration' => [
                    'Dashboard' => [
                        'InitialDashboardId' => env('DASHBOARD_ID'),
                    ],
                ],
                'Namespace' => 'default',
                'SessionLifetimeInMinutes' => 30,
            ]);
            return $result;  // 生成したURLをControllerに返す
        } catch (QuickSightException $e){
            Log::error($e);
        }
        
    }

    # API実行に必要なAWSアカウントIDの取得
    public function getAccountId() {
        
        $client = new StsClient([
            'version' => 'latest',
            'region'  => env('DEFAULT_REGION')
        ]);
        $profile = $client->getCallerIdentity([]);
        
        return $profile['Account'];
    }
}

実装の説明は以上になります。 細かい部分は一部省略したところもありますが、上記の流れで埋め込み用URLの生成が可能となります。

最後に

ダッシュボード本体の作成だけではなく、ダッシュボードの既存Webサイトへの埋め込みについても無事に実現できました。実現にあたり、複数のドキュメントを読みつつ、試行錯誤する過程でQuickSightの理解も深まり良い経験となりました。 この記事がQuickSightの導入、ダッシュボードの埋め込み実現のお役に立てれば幸いです。

We're hiring! 弊社では、一緒に働いてくださるエンジニアを募集しています。

rarejob-tech.co.jp