QuickSight のユーザーの作成とシステム利用者への割り当て

AWSクラウド

QuickSight とシームレスにつながるシステムの構築に際して、QuickSight ユーザーをどのようにシステム利用者に割り振るかの観点からインフラ設計を考えてみたいと思います。
なお、ここでの説明は、Enterprise Edition を使用したケースに特化しています。

参考: QuickSight のデータセットの作成と接続方法


システム要件
以下のような機能要件があるシステムを想定しています。

・システムのデータベースと QuickSight をつなげる
・システム画面より該当のダッシュボードへシームレスにアクセスできる
・利用者ごとに集計されたダッシュボードを参照する
・ダッシュボードは当該利用者自身の集計データのみ参照できる


ユーザーの種類
QuickSight では以下の3つのロールを持つユーザーが存在します。

管理者
QuickSight を管理するユーザーです。
作成者ができることすべて、およびアカウントの設定やサブスクリプションの購入、SPICE 容量の購入などができます。
AWS のルートユーザーは自動的に最初の管理者となり、このアカウントは削除もロール変更もできません。
管理者は複数設定することが可能ですが、一人につき月額 $24 かかります。

作成者
ダッシュボードと呼ばれるグラフを用いた分析画面の作成を行うユーザーです。
閲覧者ができることすべて、およびデータソースやデータセット、分析、ダッシュボードを作成できます。
作成者は複数設定することが可能ですが、一人につき月額 $24 かかります。

閲覧者
ダッシュボードの閲覧のみ可能なユーザーです。
従量課金制で 30 分を1セッションとし、1セッション当り $0.3 の料金がかかりますが、1人当り月額 $5 以上は請求されません
例えば閲覧者が1日1時間 QuickSight を参照すると、30日間で 60 セッションとなり $18 かかる計算になりますが、実際の請求額は $5 となります。


ユーザーの作成
画面ヘッダ部の右上のユーザーアイコンより「QuickSight を管理」を選択し、左メニューの「ユーザーを管理」をクリックします。
最初は AWS のルートユーザーが管理者として登録されています。

ユーザーを管理

ユーザーを招待」をクリックすると招待画面がでてきます。

ユーザーを招待

画面上部の検索ボックスに招待したい利用者のメールアドレスを入力し、+をクリックすると下のリストに登録されます(①)。
IAM ユーザーを招待したい場合は、検索ボックスに IAM ユーザー名を入力し、補完リストから該当のユーザーを選択します(②)。
リストよりメールアドレスを入力し、ロールを選択します。

招待」ボタンをクリックすると登録されたメールアドレスに招待メールが届きますので、メールの内容に従って手続きを行います。
登録が完了されたら以下の URL のログイン画面より、QuickSight にログインできるようになります。

URL: https://quicksight.aws.amazon.com/

QuickSightログイン画面


IAM ユーザーの場合は AWS マネジメントコンソールを経由してログインします。
QuickSight ユーザーが IAM ユーザーであるメリットは、ポリシーを設定することで細かなアクセス制限を儲けることができるところです。
例えば以下はResourceの指定により、特定のダッシュボードのみ操作できるように制限されています。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow"
			"Action": "quicksight:*",
			"Resource": "arn:aws:quicksight:us-west-2:111122223333:dashboard/1a1ac2b2-3fc3-4b44-5e5d-c6db6778df89"
		}
	]
}

ユーザー情報を後から編集したい場合は、コンソール画面からは直接編集できないため AWS コマンドを利用して行います。

>aws quicksight update-user --user-name JohnDoe --email john@example.com --aws-account-id 111122223333 --namespace default --role AUTHOR --region ap-northeast-1


AWS ドキュメント – Amazon QuickSight コンソールへのアクセスのカスタマイズ
https://docs.aws.amazon.com/ja_jp/quicksight/latest/user/customizing-permissions-to-the-quicksight-console.html


システム利用者と QuickSight ユーザーの割り当て
システム利用者ごとに利用者自身のフィルターをかけた状態でダッシュボードを閲覧させる場合について検討していきます。

通常、機能面・コスト面の観点から、システム利用者にはダッシュボード参照用に QuickSight ユーザーの閲覧者アカウントを割り当てます。
どの閲覧者アカウントでダッシュボードを閲覧させるかについては、以下の3パターンが考えられます。

a) システム利用者ごとに閲覧者アカウントを割り当てる
b) 1つの閲覧者アカウントを共有しダッシュボードを分ける
c) 匿名ユーザーで閲覧させる

匿名ユーザーとは、特定のユーザーアカウントに紐付けずにダッシュボードを公開・共有するための機能です。
誰でも参照できるためセキュリティリスクを伴いますが、システム利用者の追加に伴って閲覧者やダッシュボードを割り当てる必要がないため、開発コスト・運用コストは低くなるでしょう。
最も利用料金が低くなるのは b) になりますが、AWS SDK の問題でシームレスな連携が難しそうです。

追記:(2024/03/01)
AWS の技術サポートの方に相談したところ、b) は推奨されない方法であり、AWS SDK で対応されることはないだろうということでした。

Amazon QuickSight の料金
https://aws.amazon.com/jp/quicksight/pricing/


以下、それぞれの解説になります。


システム利用者ごとに閲覧者アカウントを割り当てる
利用者ごとに閲覧者を分けることで1つのダッシュボードを共有できます。
閲覧者は1人当り月額 $5 なので、利用者数 × $5 が月額の最大利用料金となります。
月額コストが見積りやすい点がメリットですが、システム的にプログラム上からの QuickSight の操作が必要となるので開発の難易度は上がるでしょう。

QuickSight では、行レベルセキュリティ【Row Level Security】というユーザーベースのフィルタリングをデータセットに付与することができます。
このフィルタリングにより、同じダッシュボードを利用者ごとのデータに特化した形で閲覧させることができます。

シームレスな連携という観点においては、利用者の追加・削除に連動して QuickSight ユーザーの追加・削除が自動で行われるべきでしょう。
また、新規に追加した QuickSight ユーザーが正しくダッシュボードを参照できるようにするためには、ダッシュボードの共有および行レベルセキュリティの設定が必要です。

システム利用者ごとに閲覧者アカウントを割り当てる


これらの操作は、AWS 用のソフトウェア開発キット AWS SDK によってプログラム上から行うことが可能です。
ここではプログラム言語に PHP を使用します。

AWS ドキュメント – Amazon QuickSight を使用した開発
https://docs.aws.amazon.com/ja_jp/quicksight/latest/user/quicksight_dev.html

AWS SDK for PHP 3.x – QuickSightClient
https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.QuickSight.QuickSightClient.html

以上を踏まえて実際のプログラム例や設定手順を解説します。


システム側のプログラム例や QuickSight の設定方法
プログラムから QuickSight を操作する場合、操作可能な権限を持った IAM ユーザーのアクセスキーおよびシークレットキーが必要です。

参考: アクセスキーの作成

ここではプログラム上から閲覧者の作成・削除、ダッシュボードの権限の更新、データセットの更新を行うので、これらの権限を IAM ユーザーのポリシーに追加します。
ポリシーの追加は新規にポリシーを定義して IAM ユーザーに追加するか、インラインポリシーを定義することで行います。
AWS マネジメントコンソールの IAM の画面左メニュー「ユーザー」より当該ユーザーを選択し、許可タブの右上「許可を追加」するとプルダウンで「許可を追加」(ポリシーの作成)「インラインポリシーを作成」が出てくるのでどちらかを選択します。

ここで設定するポリシーは QuickSight を操作するプログラム側の権限です。
ダッシュボードを参照する「閲覧者」( QuickSight ユーザー)の権限ではありませんので注意してください。


以下はポリシーの記述例です。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "VisualEditor0",
			"Effect": "Allow",
			"Action": [
				"quicksight:RegisterUser",
				"quicksight:DeleteUser",
				"quicksight:UpdateDashboardPermissions",
				"quicksight:DescribeDataSet",
				"quicksight:UpdateDataSet"
			],
			"Resource": [
				"arn:aws:quicksight:ap-northeast-1:123456789012:user/default/*",
				"arn:aws:quicksight:ap-northeast-1:123456789012:dashboard/*",
				"arn:aws:quicksight:ap-northeast-1:123456789012:dataset/*"
			]
		},
	]
}

細かなポリシー設定が面倒であれば、セキュリティリスクを十分考慮した上で*(すべて)でも良いでしょう。

"Action": [
	"quicksight:*",
]


まずは閲覧者(QuickSight ユーザー)の追加です。
以下は AWS SDK for PHP を利用した PHP のソースコードの例です。

use Aws\QuickSight\QuickSightClient;
use Aws\Exception\AwsException;

define('C_AWS_REGION', 'ap-northeast-1'); # リージョン
define('C_AWS_ACCESS_KEY', 'XXXXXXXX'); # QuickSightを操作するIAMユーザーのアクセスキー
define('C_AWS_SECRET_ACCESS_KEY', 'XXXXXXXX'); # 対となるIAMユーザーのシークレットアクセスキー
define('C_AWS_ACCOUNT_ID', '0123456789012'); # AWS アカウントID(e.g. 123456789012)

class QuickSightTest{

	private $credentials_ = [
		'version' => 'latest',
		'region' => C_AWS_REGION,
		'credentials' => [
			'key'    => C_AWS_ACCESS_KEY,
			'secret' => C_AWS_SECRET_ACCESS_KEY
		]
	];

	public function registerUser($email){
		$params = [
			'AwsAccountId' => C_AWS_ACCOUNT_ID, # AWSアカウントID
			'Namespace' => 'default',
			'IdentityType' => 'QUICKSIGHT',
			'UserName' => $email, # 追加するユーザーのユーザー名
			'Email' => $email, # 追加するユーザーのメールアドレス
			'UserRole' => 'READER' # 閲覧者
		];

		try{
			$client = new QuickSightClient($this->credentials_);
			$result = $client->registerUser($params);
			$userArn = $result['User']['Arn'];
			print 'userArn:'.$userArn."<br>\n";

		}catch(Exception $e){
			print $e->getMessage();
		}
	}
}

成功すると$email宛に招待メールが送信され、メール内の URL をクリックすることでユーザー登録が完了します。
なお、ユーザーを削除する場合は、deleteUser()を使用します。


続いてダッシュボードの共有です。
ここでのダッシュボードの共有とは、ダッシュボードに対して閲覧者アカウントを「表示者」として登録することです。
QuickSight コンソールでは、左メニュー「ダッシュボード」より当該ダッシュボードを選択し、右上「共有」アイコンより「ダッシュボードの共有」を選択して行う操作です。

以下は、表示者としてユーザーを登録するコード例です。
前述 QuickSightTest クラスに追記するメソッドのみの抜粋です。
※以降コード例は追記のメソッドの部分のみ記載します。

public function shareDashboard($dashboardId, $username){
	// username: 登録する閲覧者のユーザー名
	$arn = 'arn:aws:quicksight:'.C_AWS_REGION.':'.C_AWS_ACCOUNT_ID.':user/default/'.$username;

	$params = [
		'AwsAccountId' => C_AWS_ACCOUNT_ID, # AWSアカウントID(e.g. 123456789012)
		'DashboardId' => $dashboardId, # 閲覧者を登録するダッシュボードID
		'GrantPermissions' => [
			[
				'Principal' => $arn, # 登録する閲覧者のARN
				'Actions' => [
					'quicksight:QueryDashboard',
					'quicksight:DescribeDashboard',
					'quicksight:ListDashboardVersions'
				]
			]
		]
	];

	try{
		$client = new QuickSightClient($this->credentials_);
		$result = $client->updateDashboardPermissions($params);
		print_r($result);

	}catch(Exception $e){
		print $e->getMessage();
	}
}

なお、許可を取り消す場合は、updateDashboardPermissions()RevokePermissionsパラメタを指定します。

最後に行レベルセキュリティの追加です。
行レベルセキュリティは「QuickSight ユーザー名(もしくはグループ名)」と「データセットのフィールド値」との対応表によって定義します。
データセットのフィールドとは、データベースから取得した値を格納する場所で、データベースのカラムそのものに名前を付けたものであったり、カラム同士を計算した結果であったりします。
データセットの編集画面の左側で設定する項目ですね。

データセットのフィールド


例えば以下のような設定の場合、ユーザーuserAは社員名フィールドが「山田 太郎」かつ部署名フィールドが「総務部」の行のみデータを取得します。
adminは条件がないため、すべてのデータを取得します。
フィールドの条件は複数指定可能で、拒否の設定としても登録できます。
登録のないユーザーはデータが取得されません。

UserName, 社員名, 部署名
admin, "", ""
userA, 山田 太郎, 総務部
userB, 鈴木 次郎, 開発部
userC, 佐藤 三郎, 営業部

行レベルのセキュリティが機能するのは、テキストデータ (文字列、char、varchar など) が含まれるフィールドのみです。
現状、日付または数値フィールドでは機能しません。

行レベルセキュリティの設定は、上記の定義を CSV 形式で保存したファイルをデータセットとして登録し、これを行レベルセキュリティを設定したいデータセットに登録することで行われます。
QuickSight コンソールでの手順は以下を参照してください。

AWS ドキュメント – データセットへのアクセスを制限するためのユーザーベースのルールでの行レベルのセキュリティ (RLS) の使用
https://docs.aws.amazon.com/ja_jp/quicksight/latest/user/restrict-access-to-a-data-set-using-row-level-security.html

行レベルセキュリティの設定

ちなみに CSV ファイルによる行レベルセキュリティのデータセットの登録は、データソースの「ファイルのアップロード」より当該 CSV ファイルを選択することにより行います。
※CSV 以外にも登録方法はあります。

データソースの選択


以下は行レベルセキュリティの追加を行う PHP のソースコードの例です。

public function addRLS($datasetId, $datasetName, $RLSdatasetId){
	$params = [
		'AwsAccountId' => C_AWS_ACCOUNT_ID, # AWSアカウントID(e.g. 123456789012)
		'DataSetId' => $datasetId, # RLSを設定したいデータセットID
	];

	$params2 = [
		'AwsAccountId' => C_AWS_ACCOUNT_ID, # AWSアカウントID(e.g. 123456789012)
		'DataSetId' => $datasetId, # RLSを設定したいデータセットID
		'Name' => $datasetName, # RLSを設定したいデータセット名
		'ImportMode' => 'SPICE', # データセットがSPICEを利用する場合
		'RowLevelPermissionDataSet' => [
			'Arn' => 'arn:aws:quicksight:'.C_AWS_REGION.':'.C_AWS_ACCOUNT_ID.':dataset/'.$RLSdatasetId, # RLS定義のデータセットID
			'Namespace' => 'default',
			'PermissionPolicy' => 'GRANT_ACCESS', # 許可条件(拒否の場合:DENY_ACCESS)
			'Status' => 'ENABLED', # 有効(無効の場合:DISABLED)
		]
	];

	try{
		$client = new QuickSightClient($this->credentials_);
		$map = $client->describeDataSet($params);
		$params2['PhysicalTableMap'] = $map['DataSet']['PhysicalTableMap'];
		$params2['LogicalTableMap'] = $map['DataSet']['LogicalTableMap'];
		$result = $client->updateDataSet($params2);
		print_r($result);

	}catch(Exception $e){
		print $e->getMessage();
	}
}

なお、行レベルセキュリティの設定を無効にする場合は、updateDataSet()RowLevelPermissionDataSetのパラメタStatusDISABLEDを指定します。

行レベルセキュリティの自動追加が技術的に困難である場合、お客様から利用者の追加を報告していただき、手動で登録する運用形態が考えられます。


1つの閲覧者アカウントを共有しダッシュボードを分ける
システムで1つの閲覧者アカウントを使いまわす形であれば、全体で月額 $5 ですみます。
1人の閲覧者が同時並行的にダッシュボードを参照しても、QuickSight は問題なく動作します。

ただし QuickSight では、1人の閲覧者に対して個別のフィルタリングを適用することができません。
同じ内容のダッシュボードであっても、利用者ごとに異なるフィルターをかけたダッシュボードを作成する必要がでてきます。
ダッシュボードにコントロールを配置できるのでプルダウンメニューで選択させる方法もありますが、この方法が有効なのは他者が見えても問題ない場合のみです。
他の利用者もプルダウンから選択できてしまうため、本要件では利用できないでしょう。

QuickSight では URL にパラメータを設定できる仕組みが存在しますが、これはカスタム URL アクションでしか使用できません。
カスタムアクションはダッシュボード上での操作をトリガーとして動作するもので、例えばグラフをクリックしたときにダッシュボードを遷移させるといった使い方をします。

AWS ドキュメント – URL でのパラメータの使用
https://docs.aws.amazon.com/ja_jp/quicksight/latest/user/parameters-in-a-url.html


システムとシームレスに連動させたい場合は、システム上での利用者の新規追加に伴って当該利用者用のダッシュボードを作成します。
まずダッシュボードの原型となる分析を作成し、これを元に「テンプレート」と呼ばれるダッシュボードの雛形を作成します。
このとき、このテンプレートに当該利用者用のフィルターを搭載します。
できあがったテンプレートを元にしてダッシュボードを作成します。
最後にダッシュボードの共有(ユーザーを表示者として登録)を行って完了です。

1つの閲覧者アカウントを共有しダッシュボードを分ける


以上を踏まえて実際のプログラム例や設定手順を解説します。

追記:(2024/03/01)
AWS SDK を利用してテンプレートにフィルタをかけることができない問題について AWS の技術サポートの方に相談しましたが、1つの閲覧者アカウントを共有することは推奨されない方法であり、AWS SDK で対応されることはないだろうということでした。

やるとすればフィルタをかけた分析をダッシュボードごとに手動で作成する方法しかなさそうです。


システム側のプログラム例や QuickSight の設定方法
ここではプログラム上からテンプレートや分析、ダッシュボードの操作全般を行うので、これらの権限をプログラムで利用する IAM ユーザーのポリシーに追加します。
以下はポリシーの記述例です。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "VisualEditor0",
			"Effect": "Allow",
			"Action": [
				"quicksight:PassDataSet",
				"quicksight:ListTemplates",
				"quicksight:DescribeTemplate",
				"quicksight:CreateTemplate",
				"quicksight:UpdateTemplate",
				"quicksight:DeleteTemplate",
				"quicksight:ListAnalyses",
				"quicksight:DescribeAnalysis",
				"quicksight:RestoreAnalysis",
				"quicksight:CreateAnalysis",
				"quicksight:UpdateAnalysis",
				"quicksight:DeleteAnalysis",
				"quicksight:DescribeAnalysisPermissions",
				"quicksight:UpdateAnalysisPermissions",
				"quicksight:ListDashboards",
				"quicksight:DescribeDashboard",
				"quicksight:CreateDashboard",
				"quicksight:UpdateDashboard",
				"quicksight:DeleteDashboard",
				"quicksight:DescribeDashboardPermissions",
				"quicksight:UpdateDashboardPermissions",
				"quicksight:UpdateDashboardPublishedVersion"
			],
			"Resource": [
				"arn:aws:quicksight:ap-northeast-1:123456789012:dataset/*",
				"arn:aws:quicksight:ap-northeast-1:123456789012:template/*",
				"arn:aws:quicksight:ap-northeast-1:123456789012:analysis/*",
				"arn:aws:quicksight:ap-northeast-1:123456789012:dashboard/*",
				"arn:aws:quicksight:ap-northeast-1:123456789012:user/default/*"
			]
		},
	]
}


まずはテンプレートを作成します。
ダッシュボードの原型となる分析はあらかじめ QuickSight コンソールからビジュアルをデザインし作成しておきます。
以下は原型となる分析からテンプレートを作成する PHP のコード例です。

public function createTemplate($templateId, $analysisId, $datasetId, $datasetName){
	$tpId = $templateId; # 作成するテンプレートのID(任意の英数記号)
	$anId = $analysisId; # 元となる分析のID
	$dsId = $datasetId; # 元となる分析が接続するデータセットのID
	$dsNm = $datasetName; # 元となる分析が接続するデータセット名

	$template = [
		'SourceAnalysis' => [
			'Arn' => 'arn:aws:quicksight:'.C_AWS_REGION.':'.C_AWS_ACCOUNT_ID.':analysis/'.$anId,
			'DataSetReferences' => [
				[
					'DataSetPlaceholder' => $dsNm,
					'DataSetArn' => 'arn:aws:quicksight:'.C_AWS_REGION.':'.C_AWS_ACCOUNT_ID.':dataset/'.$dsId
				]
			]
		]
	];

	$params = [
		'AwsAccountId' => C_AWS_ACCOUNT_ID, # AWSアカウントID(e.g. 123456789012)
		'TemplateId' => $tpId, # テンプレートID(任意の英数記号)
		'Name' => $tpId, # テンプレート名(任意の文字列)
		'SourceEntity' => $template,
		'VersionDescription' => '1'
	];

	try{
		$client = new QuickSightClient($this->credentials_);
		$result = $client->createTemplate($params);
		print_r($result);

	}catch(Exception $e){
		print $e->getMessage();
	}
}

なお、テンプレートを更新する場合はupdateTemplate()、削除する場合はdeleteTemplate()を利用します。

本来であればこのテンプレートに利用者ごとのフィルターを設定すべきなのですが、現状 AWS SDK の問題によりうまく設定できないようでした。
したがってテンプレートを作成する前にあらかじめ原型となる分析にコンソール上からフィルタを設定するしか手がなさそうです。
(試してみたプログラムは本記事最後に載せておきます)

追記:(2024/03/01)
AWS SDK の問題というよりも、推奨されない方法のため、AWS SDK で対応されることはないだろうということでした。

フィルターの設定は、左メニュー「分析」より当該分析を選択し、左側「フィルター」アイコンをクリックします。
フィルターの追加」ボタンをクリックするとフィールドの一覧が表示されるので、フィルターをかけるフィールド(ここでは社員名)を選択し、フィルターを作成した後にその他のパラメタ(NULLの扱い等)を設定します。

フィルターの設定

上記手順でフィルタを設定した後にテンプレートを作成すると、うまくフィルタが搭載されるようでした。
この辺りプログラムからの自動連携はあきらめ、手動による運用にした方が良いかもしれません。

テンプレートは QuickSight コンソール上から参照することも操作することもできないため、テンプレートを手動で参照・操作する場合は、AWS コマンドを利用します。

AWS コマンドからの QuickSight リソースの操作は、以下を参照してください。

参考: AWS コマンドからの QuickSight の操作


次にこのテンプレートを利用してダッシュボードを作成します。
以下は PHP のソースコードの例です。

public function createDashboard($dashboardId, $username, $templateId, $datasetId, $datasetName){
	$dbId = $dashboardId; # 作成するダッシュボードのID(任意の英数記号)
	$tpId = $templateId; # 元となるテンプレートのID
	$dsId = $datasetId; # 元となるテンプレートが接続するデータセットのID
	$dsNm = $datasetName; # 元となるテンプレートが接続するデータセット名

	$source = [
		'SourceTemplate' => [
			'Arn' => 'arn:aws:quicksight:'.C_AWS_REGION.':'.C_AWS_ACCOUNT_ID.':template/'.$tpId,
			'DataSetReferences' => [
				[
					'DataSetPlaceholder' => $dsNm,
					'DataSetArn' => 'arn:aws:quicksight:'.C_AWS_REGION.':'.C_AWS_ACCOUNT_ID.':dataset/'.$dsId
				]
			]
		]
	];

	# 権限を設定
	$permissions = [
		# コンソールからの操作者に本ダッシュボードが参照・操作できるよう権限を設定
		# ここではadminグループに属する者に権限を与えている
		[
			'Principal' => 'arn:aws:quicksight:'.C_AWS_REGION.':'.C_AWS_ACCOUNT_ID.':group/default/admin',
			'Actions' => [
				'quicksight:QueryDashboard',
				'quicksight:DescribeDashboard',
				'quicksight:ListDashboardVersions',
				'quicksight:UpdateDashboard',
				'quicksight:DeleteDashboard',
				'quicksight:DescribeDashboardPermissions',
				'quicksight:UpdateDashboardPermissions',
				'quicksight:UpdateDashboardPublishedVersion'
			]
		],
		# 共有する閲覧者に本ダッシュボードが参照できるよう権限を設定(ダッシュボードの共有)
		[
			'Principal' => 'arn:aws:quicksight:'.C_AWS_REGION.':'.C_AWS_ACCOUNT_ID.':user/default/'.$username,
			'Actions' => [
				'quicksight:QueryDashboard',
				'quicksight:DescribeDashboard',
				'quicksight:ListDashboardVersions'
			]
		]
	];

	$params = [
		'AwsAccountId' => C_AWS_ACCOUNT_ID, # AWSアカウントID(e.g. 123456789012)
		'DashboardId' => $dbId, # ダッシュボードID(任意の英数記号)
		'Name' => $dbId, # ダッシュボード名(任意の文字列)
		'SourceEntity' => $source,
		'Permissions' => $permissions
	];

	try{
		$client = new QuickSightClient($this->credentials_);
		$result = $client->createDashboard($params);
		print_r($result);

	}catch(Exception $e){
		print $e->getMessage();
	}
}

なお、ダッシュボードを更新する場合はupdateDashboard()、削除する場合はdeleteDashboard()を利用します。


参考までに分析を作成する場合の PHP のコード例を載せておきます。

public function createAnalysis($analysisId, $templateId, $datasetId, $datasetName){
	$anId = $analysisId; # 作成する分析のID(任意の英数記号)
	$tpId = $templateId; # 元となるテンプレートのID
	$dsId = $datasetId; # 元となるテンプレートが接続するデータセットのID
	$dsNm = $datasetName; # 元となるテンプレートが接続するデータセット名

	$source = [
		'SourceTemplate' => [
			'Arn' => 'arn:aws:quicksight:'.C_AWS_REGION.':'.C_AWS_ACCOUNT_ID.':template/'.$tpId,
			'DataSetReferences' => [
				[
					'DataSetPlaceholder' => $dsNm,
					'DataSetArn' => 'arn:aws:quicksight:'.C_AWS_REGION.':'.C_AWS_ACCOUNT_ID.':dataset/'.$dsId
				]
			]
		]
	];

	# コンソールからの操作者に本分析が参照・操作できるよう権限を設定
	# ここではadminグループに属する者に権限を与えている
	$permissions = [
		[
			'Principal' => 'arn:aws:quicksight:'.C_AWS_REGION.':'.C_AWS_ACCOUNT_ID.':group/default/admin',
			'Actions' => [
				'quicksight:QueryAnalysis',
				'quicksight:DescribeAnalysis',
				'quicksight:RestoreAnalysis',
				'quicksight:UpdateAnalysis',
				'quicksight:DeleteAnalysis',
				'quicksight:DescribeAnalysisPermissions',
				'quicksight:UpdateAnalysisPermissions'
			]
		]
	];

	$params = [
		'AwsAccountId' => C_AWS_ACCOUNT_ID, # AWSアカウントID(e.g. 123456789012)
		'AnalysisId' => $anId, # 分析ID(任意の英数記号)
		'Name' => $anId, # 分析名(任意の文字列)
		'SourceEntity' => $source,
		'Permissions' => $permissions
	];

	try{
		$client = new QuickSightClient($this->credentials_);
		$result = $client->createAnalysis($params);
		print_r($result);

	}catch(Exception $e){
		print $e->getMessage();
	}
}

なお、分析を更新する場合はupdateAnalysis()、削除する場合はdeleteAnalysis()を利用します。


コンソール上で分析からダッシュボードを作成する場合は左メニュー「分析」より当該分析を選択し、右上「共有」アイコンの「ダッシュボードの公開」を選択し、ダッシュボード名を入力して「ダッシュボードの公開」ボタンをクリックします。

ダッシュボードの作成


匿名ユーザーで閲覧させる
閲覧者もダッシュボードも増やさない唯一の方法は匿名ユーザーを利用することです。
QuickSight の管理画面もすっきりしますし、最もシンプルな構成設計となるでしょう。
利用者ごとのフィルターは、タグベースの行レベルセキュリティで行います。
ダッシュボードの URL 取得時にタグを指定することにより、同じダッシュボードをタグごとのデータに特化した形で閲覧させることができます。
タグを「利用者」という属性だけではなく、あらゆる属性にあてはめることで、部署ごとや閾値ごとなど様々な”ごと”に対応できます。
このようにタグベースの行レベルセキュリティは非常に便利ですが、残念ながら匿名ユーザーによる閲覧でしか利用できません

匿名ユーザーで閲覧させる


難点は匿名ユーザーの利用料金です。
匿名ユーザーの利用料金は月間あるいは年間プランとなっており、最低額の月間プランでも月 $250 とかなりの運用コスト増となります。
また閲覧者のような上限がなく(500 セッション以上で超過料金が発生)、利用状況によって料金が上下するので月額コストが見積りにくいという問題があります。
また、匿名ユーザーの閲覧は認証を通さないため、URL さえわかれば誰でも参照できてしまいます。
この辺りはセキュリティ要件にひっかかってしまうケースが多いでしょう。

Amazon QuickSight の料金
https://aws.amazon.com/jp/quicksight/pricing/

認証については、利用者側がプロキシ経由の固定 IP アドレスであるならば、IP アクセス制限を設けることで解決できるかもしれません。
画面ヘッダ部の右上のユーザーアイコンより「QuickSight を管理」を選択し、左メニューの「セキュリティとアクセス権限」をクリックします。
画面下の方に「IP 制限」の項目があるので「Manage」ボタンをクリックし、ルールをオンにしたのちに許可したい IP アドレスを入力します。

IP制限


以上を踏まえて実際のプログラム例や設定手順を解説します。


システム側のプログラム例や QuickSight の設定方法
ここではプログラム上からデータセットの更新を行うので、これらの権限をプログラムで利用する IAM ユーザーのポリシーに追加します。
以下はポリシーの記述例です。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "VisualEditor0",
			"Effect": "Allow",
			"Action": [
				"quicksight:DescribeDataSet",
				"quicksight:UpdateDataSet"
			],
			"Resource": [
				"arn:aws:quicksight:ap-northeast-1:123456789012:dataset/*"
			]
		},
	]
}


シームレスな連携では、利用者の追加・削除に連動して行レベルセキュリティを追加・削除するだけとなります。
タグベースの行レベルセキュリティでは、データセットのフィールドにタグ名を設定することで定義します。

例えばフィールド「社員名」に「uname」というタグを設定します。
ダッシュボードの URL 取得の際(ダッシュボードの閲覧)、unameタグに「山田 太郎」を指定すると、社員名フィールドが「山田 太郎」の行のみデータを取得します。

QuickSight コンソールでの手順では、左メニュー「データセット」より該当のデータセットを選択し、概要タブの下部「行レベルセキュリティ」の「編集」をクリックします。
タグベースのルールを開くと以下のような設定画面が表示されます。

列を選択」で行レベルセキュリティを設定するフィールド名を選択し、タグの欄にタグ名を入力し「追加」ボタンをクリックします。
タグを設定し終わったら「適用」ボタンをクリックします。

プログラム上から自動で更新する場合は、以下のようなコードになります。

public function addRLS_tag($datasetId, $datasetName){
	$params = [
		'AwsAccountId' => C_AWS_ACCOUNT_ID, # AWSアカウントID(e.g. 123456789012)
		'DataSetId' => $datasetId, # RLSを設定したいデータセットID
	];

	$params2 = [
		'AwsAccountId' => C_AWS_ACCOUNT_ID, # AWSアカウントID(e.g. 123456789012)
		'DataSetId' => $datasetId, # RLSを設定したいデータセットID
		'Name' => $datasetName, # RLSを設定したいデータセット名
		'ImportMode' => 'SPICE', # データセットがSPICEを利用する場合
		'RowLevelPermissionTagConfiguration' => [
			'Status' => 'ENABLED',
			'TagRules' => [
				['ColumnName'=>'社員名', 'TagKey'=>'uname'] # フィールド名とタグ名の対応表
			]
		]
	];

	try{
		$client = new QuickSightClient($this->credentials_);
		$map = $client->describeDataSet($params);
		$params2['PhysicalTableMap'] = $map['DataSet']['PhysicalTableMap'];
		$params2['LogicalTableMap'] = $map['DataSet']['LogicalTableMap'];
		$result = $client->updateDataSet($params2);
		print_r($result);

	}catch(Exception $e){
		print $e->getMessage();
	}
}

なお、行レベルセキュリティの設定を無効にする場合は、updateDataSet()RowLevelPermissionTagConfigurationのパラメタStatusDISABLEDを指定します。


ダッシュボードの閲覧
ダッシュボードには参照用の URL があり、ブラウザで当該 URL にアクセスすることでダッシュボードを参照できます。
自システムの画面に埋め込む場合は、この URL をiframeで表示させます。

URL の埋め込みには表示側ドメインの許可が必要です。
手順としては、右上ユーザーアイコンより「QuickSight の管理」を選択、左メニューの「ドメインと埋め込み」をクリックします。
入力欄にドメイン名を入力し「追加」ボタンをクリックします。

URL は QuickSight のコンソールで確認できます。
左メニュー「ダッシュボード」より当該ダッシュボードを選択し、右上「共有」アイコンより「ダッシュボードを共有」を選択します。
リンクをコピー」をクリックすると URL がクリップボードにコピーされ、「埋め込みコードをコピー」をクリックするとiframeのコードを含めた HTML タグがクリップボードにコピーされます。

ダッシュボード参照URLの取得

ダッシュボードのビジュアル単位にも URL が存在し、ビジュアル単体で参照することも可能です。
URL はダッシュボード内の各ビジュアルの右上にあるメニューオプション()をクリックし、「埋め込みビジュアル」を選択します。
画面右側に埋め込みコードが表示されますので、「コードのコピー」をクリックしてクリップボードにコピーします。

ビジュアル参照URLの取得

URL の構成は以下のようになっています。

#ダッシュボードの参照URL
{リージョン}.quicksight.aws.amazon.com/sn/accounts/{アカウントID}/dashboards/{ダッシュボードID}?directory_alias={QuickSightアカウント名}

#ビジュアルの参照URL
{リージョン}.quicksight.aws.amazon.com/sn/accounts/{アカウントID}/dashboards/{ダッシュボードID}/views/{ビジュアルID}?directory_alias={QuickSightアカウント名}

匿名ユーザーでアクセスする場合はこの URL にてそのままアクセスできます。
閲覧者でアクセスする場合は、QuickSight のログインを経由してアクセスすることができます。

閲覧者のアクセスでログインを経由させたくない(シングルサインオン)場合は、AWS SDK にて一時的にアクセス可能な URL を取得します。
この URL は5分間有効で、得られたセッションは最大10時間有効です。

以下はシングルサインオンの参照 URL を取得する PHP のコード例です。
ダッシュボードのページに飛ばしたい場合はここで取得した URL にリダイレクトし、ページに埋め込みたい場合はiframeで表示させます。

public function getEmbedUrl($dashboardId, $username){
	$userArn = 'arn:aws:quicksight:'.C_AWS_REGION.':'.C_AWS_ACCOUNT_ID.':user/default/'.$username;
	$params = [
		'AllowedDomains' => ['https://exaple.com'], # 埋め込みダッシュボードを許可するドメイン
		'AwsAccountId' => C_AWS_ACCOUNT_ID, # AWSアカウントID(e.g. 123456789012)
		'Namespace' => 'default',
		'UserArn' => $userArn, # 閲覧者のARN
		'ExperienceConfiguration' => [
			'Dashboard' => ['InitialDashboardId'=>$dashboardId] # 最初に表示するダッシュボード
		]
	];

	try{
		$client = new QuickSightClient($this->credentials_);
		$result = $client->generateEmbedUrlForRegisteredUser($params);
		$embed_url = $result['EmbedUrl'];
		print $embed_url;

	}catch(Exception $e){
		print $e->getMessage();
	}
}

プログラムで利用する IAM ユーザーに必要なポリシーの記述例です。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "VisualEditor0",
			"Effect": "Allow",
			"Action": [
				"quicksight:GenerateEmbedUrlForRegisteredUser"
			],
			"Resource": [
				"arn:aws:quicksight:ap-northeast-1:123456789012:user/default/*"
			]
		},
	]
}


匿名ユーザーでのアクセス時にタグを指定したい場合も同様に AWS SDK にて URL を取得します。
この URL の有効期限はパラメータで指定できます。
以下はタグを指定した参照 URL を取得する PHP のコード例です。

public function getEmbedUrlForAnonymous($dashboardId, $tags){
	$dboardArns = ['arn:aws:quicksight:'.C_AWS_REGION.':'.C_AWS_ACCOUNT_ID.':dashboard/'.$dashboardId];
	$params = [
		'AllowedDomains' => ['https://exaple.com'], # 埋め込みダッシュボードを許可するドメイン
		'AwsAccountId' => C_AWS_ACCOUNT_ID, # AWSアカウントID(e.g. 123456789012)
		'Namespace' => 'default',
		'SessionLifetimeInMinutes' => 15, # セッションの有効時間 [分]
		'AuthorizedResourceArns' => $dboardArns, # 閲覧を許可するダッシュボードのARN
		'ExperienceConfiguration' => [
			'Dashboard' => ['InitialDashboardId'=>$dashboardId] # 最初に表示するダッシュボード
		],
		'SessionTags' => [
			# ['Key'=>'uname', 'Value'=>'山田 太郎'] # 指定するタグとその値
		]
	];

	# タグを指定する
	foreach($tags as $key=>$value){
		$params['SessionTags'][] = ['Key'=>$key, 'Value'=>$value];
	}

	try{
		$client = new QuickSightClient($this->credentials_);
		$result = $client->generateEmbedUrlForAnonymousUser($params);
		$embed_url = $result['EmbedUrl'];
		print $embed_url;

	}catch(Exception $e){
		print $e->getMessage();
	}
}

プログラムで利用する IAM ユーザーに必要なポリシーの記述例です。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "VisualEditor0",
			"Effect": "Allow",
			"Action": [
				"quicksight:GenerateEmbedUrlForAnonymousUser"
			],
			"Resource": [
				"arn:aws:quicksight:ap-northeast-1:123456789012:dashboard/*"
			]
		},
	]
}

コメント