はじめに
この記事はシーエー・アドバンス9日目の記事です!
今回はバックエンドに利用しているrailsから、QuickSightSDKのGenerateEmbedUrlForRegisteredUserを利用して、QuickSightの埋め込み用URLを発行し画面にグラフ(ダッシュボード)を表示させてみます。
QuickSight自体、グラフのURLを全体公開にしてサイトに埋め込むことはできるのですが、それではURLさえわかれば誰でもグラフを見れる状態でよくないので、埋め込みURLを発行して表示させる方法をとります。
前提条件
- AWSアカウントを所持していること
- QuickSightでアカウント登録していること
- 24$/月ぐらいかかります
- 9$/月のSTANDARD EDITIONでは動作確認してないです
- 登録時ユーザー作成方法を選択でき、既存IAMユーザーを利用してQuickSightアカウント作成することもできます。
- QuickSight内でダッシュボードを公開していること
ダッシュボードの公開方法は、分析の作成後右上の公開ボタンを押して、新しいダッシュボードとしてダッシュボードを公開してください。
その後ダッシュボードの画面が開かれます。URLを確認すると
https://ap-northeast-1.quicksight.aws.amazon.com/sn/dashboards/"英数字で書かれたダッシュボードID"
になっています。
後ほどこのダッシュボードIDを利用するので、メモしておくか再度ダッシュボードを開いて確認してください。
実行環境
- バックエンド
- ruby 3.2.2
- rails6.1
- aws-sdk-quicksight 1.79.0
- フロント
- Angular v15
- Typescript 4.8.4
- node v18.18.0
実装
実装するにあたってrailsのAPIサーバーとなんでもいいので表示用のフロントを用意します。
また今回の登録済みユーザー向けの埋め込みURL発行には、QuickSightに登録済みのIAMユーザーが必要なため、その準備も行います。
IAMユーザー
QuickSightアカウント登録したIAMユーザーのポリシーに、以下を追記してください。
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "quicksight:RegisterUser",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "quicksight:DescribeUser",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": [
"quicksight:GenerateEmbedUrlForRegisteredUser"
],
"Resource": "arn:aws:quicksight:<YOUR_AWS_ACCOUNTID>:user/${aws:userid}"
"Effect": "Allow",
}
]
}
詳細に設定したい場合は、こちらのドキュメントを参考に設定してください。
rails
gem追加
rails環境にgemを追加します
gem install aws-sdk-quicksight
定数設定
インストール後settings.yml内部でregionやaccess_keyなどの定数を設定します。
漏れちゃいけないkeyは.envなどで管理しておくと良いです。
#settings.yml
quicksight:
region: "ap-northeast-1"
aws_account_id: "account_id"
session_lifetime_in_minutes: 15
dashboard_id: "表示させたいダッシュボードID"
user_arn: "arn:aws:quicksight:<YOUR_AWS_ACCOUNTID>:user/${aws:userid}"
access_key_id: <%=ENV['ACCESS_KEY'] %>
secret_access_key: <%=ENV['SECRET_ACCESS_KEY'] %>
allowed_domains:
- http://localhost:4200(許可したいドメイン)
module追記
lib配下のmodule内にclassとqsclientを定義して呼び出せるようにします。
class Aws
@qsclient = nil
def self.qsclient
return @qsclient if @qsclient.present?
@qsclient = ::Aws::QuickSight::Client.new(region: Settings.quicksight.region, access_key_id: Settings.quicksight.access_key_id, secret_access_key: Settings.quicksight.secret_access_key)
@qsclient
end
end
controller
# QuickSightsController.rb
module V1
class QuickSightsController < ApplicationController
before_action :set_dashbord_options
def graph
@options[:experience_configuration][:dashboard][:initial_dashboard_id] = Settings.quicksight.dashboard_id
response = qsclient.generate_embed_url_for_registered_user(@options)
render json: response, status: :ok
end
private
def qsclient
Mpv::Aws.qsclient
end
def set_dashbord_options
@options = {
aws_account_id: Settings.quicksight.aws_account_id,
allowed_domains: Settings.quicksight.allowed_domains,
session_lifetime_in_minutes: Settings.quicksight.session_lifetime_in_minutes,
user_arn: Settings.quicksight.user_arn,
experience_configuration: {
dashboard: {
initial_dashboard_id:'',
feature_configurations: {
state_persistence: {
enabled: false,
},
bookmarks: {
enabled: false,
},
},
},
},
}
end
end
end
ルーティング設定
# routes.rb
get 'quicksights/graph', to: 'quicksights#graph'
画面
今回はAngularとTypeScriptを利用しているため、それに合わせてmodelとservice, componentを作成します。
QuickSight用のmodel
export interface QuickSight {
embed_url: string;
status: number;
request_id: string;
}
QuickSight用のservice
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { QuickSight } from 'Models/custom/QuickSight';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class QuickSightAccessService {
constructor(private http: HttpClient) {}
getEmbedUrl = (): Observable<QuickSight> => this.http.get<QuickSight>(`api/v1/quicksights/graph`);
}
埋め込みグラフ表示用のcomponent
import { Component } from '@angular/core';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { QuickSightAccessService } from 'Services/quicksight-access.service';
import { map } from 'rxjs/operators';
@Component({
selector: 'app-graph',
templateUrl: './graph.component.html',
styleUrls: ['./graph.component.sass'],
})
export class GraphComponent {
readonly embedUrl$ = this.quickSightAccessService.getEmbedUrl();
readonly safeEmbedUrl$ = this.embedUrl$.pipe(map(({ embed_url }) => this.getSafeUrl(embed_url)));
constructor(private quickSightAccessService: QuickSightAccessService, private sanitizer: DomSanitizer) {}
getSafeUrl(url: string): SafeResourceUrl {
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
}
埋め込みグラフ表示用のhtml
<ng-container *ngIf="safeEmbedUrl$ | async as url">
<iframe [src]="url" frameborder="0" height="1080px" width="100%"></iframe>
</ng-container>
結果
これでQuickSightで作成したダッシュボードを埋め込むことができるようになりました!
ですがQuickSightの埋め込みではiframeを利用するため、そこだけ考慮しておいてください。
参考
Amazon QuickSight を使用した開発 - Amazon QuickSight
GenerateEmbedUrlForRegisteredUserrRequest(AWS SDK for Rubyのドキュメント)
GenerateEmbedUrlForRegisteredUserResponse
登録済みユーザー向けの QuickSight データダッシュボードの埋め込み