Lambda×API GatewayでQuickSightのGenerateEmbedUrlForRegisteredUserAPIを簡易的に試す

## はじめに
タイトルの通りです。
LambdaとAPI Gatewayを用いて、QuickSightのAPIの１つである「GenerateEmbedUrlForRegisteredUser」を簡易的に試用します。自分用の備忘録です。

※本記事の情報は2023年9月時点の情報を基にしています。
※本記事内で使用するデータ・分析は、QuickSightにおいて初期アセットとして用意されるテストデータ・テスト分析です。
参考資料：
[QuickSightユーザーガイド 埋め込み分析の使用](https://docs.aws.amazon.com/ja_jp/quicksight/latest/user/embedded-analytics.html)

## 目次
はじめに
目次
GenerateEmbedUrlForRegisteredUserについて
やりたいこと
全体の流れ
手順
表示確認
おわりに


## GenerateEmbedUrlForRegisteredUserについて
WEBページへの埋込み用ダッシュボードURLを発行するQuickSightAPIです。
QuickSightのAPIでには埋め込み用ダッシュボードURLを発行するものが4点あります。

|API|埋め込み対象|特記事項|
|---|:---|:-------|
|GenerateEmbedUrl<br>ForRegisteredUser|ダッシュボード・<br>QuickSightコンソール<br>(引数で指定)|ユーザー認証を前提とする。<br>QuickSightユーザーに対する公開|
|GenerateEmbedUrl<br>ForAnonymousUser|ダッシュボード|ユーザー認証不要で不特定多数に向けた<br>公開が可能。|
|GetDashboardEmbedUrl|ダッシュボード|古いAPI|
|GetSessionEmbedUrl|QuickSightコンソール|古いAPI|

古いAPIについては今後のメンテナンスが行われないことが明記されているため、使用は非推奨です。



今回は最上段に記載したGenerateEmbedUrlForRegisteredUserを取り扱います。
おそらくGenerateEmbedUrlForAnonymousUserは、QuickSightの料金形態がセッションキャパシティ式である必要があります。


またQuickSightでは、APIを使用せずに埋め込みダッシュボード用のURLを取得することも可能(=ワンクリック埋め込み)ですが、今回は触れません。


## やりたいこと
APIによってURLを生成し、当該URLをWEBページに埋め込み閲覧できることを確認します。

以下のようなイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/cf0c3915-4699-a492-dc62-9e73c3c748ca.png)
※APIはLambdaからboto3を使用


この埋め込みには、QuickSightアカウントにおいて、埋め込み先ドメインの登録が必要です。
設定にはQuickSightの管理者ロールが必要であり、埋め込み先はhttpsである必要があります。(API Gatewayは自動的にhttpsとなります)





















## 全体の流れ
大まかに次の通り進めます。

1【QuickSight】　分析作成、ダッシュボード化

2【Lambda】　関数作成(埋め込みURL生成用)

3-1.【API Gateway】API作成
3-2.【API Gateway】テキスト変換・マッピングテンプレート設定
3-3.【API Gateway】IP制限の設定
3-4.【API Gateway】デプロイ

4【QuickSight】　ドメイン登録

※QuickSightおよびLambdaの操作説明は簡素です。




## 手順

#### 1【QuickSight】　分析作成・ダッシュボード化
まずは分析を作成し、ダッシュボード化しておきます。
今回はQuickSightにデフォルトで生成される分析「People Overview」を使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/889f15b6-3283-dc69-7edb-60fd02cb8cdb.png)














後ほど使用するため、ダッシュボード化した際のURL末尾からダッシュボードIDを控えておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/36e921e8-f909-5bf8-f6e9-136b97dc4ed0.png)


#### 2【Lambda】　関数作成(埋め込みURL生成用)

QuickSightAPIの「generate_embed_url_for_registered_user」から、埋め込みURLを取得して返します。
以下を参考に、先程控えたダッシュボードIDなどを渡します。
[QuickSight - GenerateEmbedUrlForRegisteredUser (APIリファレンス)](https://docs.aws.amazon.com/ja_jp/quicksight/latest/APIReference/API_GenerateEmbedUrlForRegisteredUser.html)

[QuickSight - generate_embed_url_for_registered_user (boto3リファレンス)](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/quicksight/client/generate_embed_url_for_registered_user.html)


[QuickSight - generate-embed-url-for-registered-user (CLIリファレンス)](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/quicksight/generate-embed-url-for-registered-user.html)
※個人的にはCLIリファレンスが一番見やすいので掲載しています。

```
import boto3

def lambda_handler(event, context):

    quicksight_region = "ap-northeast-1"
    aws_account_id = "000000000000"
    user_arn = "arn:aws:quicksight:ap-northeast-1:000000000000:user/default/DemoUser01"
    session_minutes = 15
    dashboard_id = "ce3e45a2-e259-43a3-b12a-17b777ec4a60"

    quicksight = boto3.client('quicksight',region_name= quicksight_region)

    response = quicksight.generate_embed_url_for_registered_user(
            AwsAccountId = aws_account_id,
            UserArn = user_arn,
            SessionLifetimeInMinutes = session_minutes,
            ExperienceConfiguration = {'Dashboard':{'InitialDashboardId': dashboard_id}}
        )
        
    return_url = response['EmbedUrl']
        
    return {
        'return': return_url
    }
```

なお、今回AllowedDomainsは指定していません。






#### 3-1.【API Gateway】API作成
RestAPI
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/d148337a-9aa8-d324-a682-dbf3683fd0c0.png)


































![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/abd626d3-1c42-29d3-fb01-d2293699d5da.png)

































メソッドを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/ece34e1b-214f-70a9-aa5e-04627a30a029.png)


















Lambda関数とそのリージョンを指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/3a18e29d-7204-4cdf-6308-03679258c8e6.png)































#### 3-2.【API Gateway】テキスト変換・マッピングテンプレート設定
統合レスポンス・メソッドレスポンスのコンテンツタイプを「text/html」へ変更します。
また、統合レスポンスのマッピングテンプレートを設定します。



作成したメソッドの「統合レスポンス」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/3a648a09-e584-0318-ca53-616d92f74777.png)













デフォルトレスポンスを編集
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/1fef1074-9d67-ca15-33ae-21383915ab79.png)





























コンテンツの処理を、パススルーから「テキストに変換」へ変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/08088f4f-84bf-c307-851b-c125a887baae.png)























続いてマッピングテンプレートを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/0924e956-9377-57b3-7977-8af4a0b3893b.png)





























コンテンツタイプには「text/html」と入力
通常jsonで記載するためのでエラーが出るが、
今回は簡易的な表示確認が出来ればよいので「テンプレートの作成」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/3f48bc15-dbd4-ed87-5dd3-85ff7afd381a.png)



































メソッドレスポンスを編集
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/31e37e5c-96c5-38b6-027a-e4d211a54459.png)





























統合レスポンスと同様に、コンテンツタイプには「text/html」と入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/7731c006-e058-59d9-25e9-e0eb62aff827.png)



















#### 3-3.【API Gateway】IP制限の設定
必須ではありません。
IPアドレスによるアクセス制限を設定するための手順です。

作成したAPIを選択した状態で、画面左のメニューから「リソースポリシー」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/a28edc5a-5a21-0a56-a449-14de48a2a865.png)



























リソースポリシーを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/b1fafb72-8d9e-a18c-68bf-53379ad19893.png)













```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "000.000.000.000",
                        "000.000.000.000/0"
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/*"
        }
    ]
}
```
"aws:SourceIp"(上記000.000.000.000や000.000.000.000/0)で指定したIPアドレスのみを許可させます。
正確には、Allowで全トラフィックを許可した上で
"NotIpAddress"をDenyとすることで、「特定のIPアドレス以外を拒否」します。

"Resource"は"execute-api:/*"と記載することで、自動的に当該APIのARNが指定されます。

参考元：
[AWS 情報センター - 特定の IP アドレスのみが API Gateway REST API にアクセスすることを許可するにはどうすればよいですか?](https://repost.aws/ja/knowledge-center/api-gateway-resource-policy-access)

#### 3-4.【API Gateway】デプロイ
作成したAPIを選択してデプロイします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/d886e20f-e523-fcea-0286-23d0bc9aa9b5.png)






















初回のデプロイでは「\*New stage*」を選択し、ステージを作成します。(ステージ名は任意)
※APIに加えた変更を適用する際には、都度デプロイが必要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/c2cb8990-e975-d8dc-474a-15aecec211ed.png)




























ステージからURLを確認できるようになります。
このURLは後ほど使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/47c79664-cb5b-f6fd-5a8a-f0d5ddcb61c2.png)





















現時点でURLを開くと、ダッシュボード埋め込み用の枠だけが表示される状態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/7efb9f1e-9535-7539-e1fa-2306755199fe.png)







































#### 4【QuickSight】　ドメイン登録

ダッシュボードが表示される為には、QuickSight側でドメイン登録が必要となります。
この際、ドメインの登録にはQuickSightの管理者ロールが必要です。
また、登録する埋め込み先はhttpsである必要があります。

QuickSightコンソール右上から、「QuickSightを管理」を選択
※「QuickSightを管理」が存在しない場合は、QuickSightユーザロールが「管理者(admin)」ではない可能性があります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/84914089-5a39-6328-8df3-9bee2700374c.png)
















左メニューから「ドメインと埋め込み」を選択し、デプロイしたAPIのドメインを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/2573f549-c604-7621-b77a-0d0a19306451.png)





















## 表示確認

先ほどのAPIエンドポイントにアクセスすることで、
WEBページに埋め込まれたQuickSightダッシュボードが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/a5c319a9-9228-1bc7-970e-9af516bb936a.png)


















例外1：
IP制限を掛けている場合、対象外のIPアドレスからは以下のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/1f321270-60ac-8a57-5fc5-230660a689b5.png)

















例外2：
GenerateEmbedUrlForRegisteredUser実行時に指定したユーザーにダッシュボードの閲覧権が無い場合、以下のように表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743306/e305b10c-7d03-faaa-5969-1cda12d62bab.png)

















## おわりに

今回は表示確認が目的のためREST APIを使用しました。
この数カ月でAWSコンソールが変わっていたため、手順の整理と覚書きを兼ねて記事化しました。