2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

皆さん、AWSのBIツール「 QuickSight 」を使ったことはありますか?

QuickSightは、データソースからのダッシュボードを簡単に作成・共有できる便利なサービスです。しかし、2025年7月現在、QuickSightにはGUI上から構成設定をバックアップする機能が備わっておりません(※CLIやAPI経由では可能です)。

そこで今回は、AWS Lambdaを用いてQuickSightの設定情報(データソース、データセット、分析、ダッシュボード)を自動でS3にバックアップする仕組みを構築します。

システム構成

以下の図のような構成で実現します。

quicksight-backup-lambda.jpg

S3のバケットを準備

まずは、バックアップを保存するためのS3バケットを作成します。

  • バケット名は任意で作ってください
  • バージョニングを有効化 すると、過去バージョンの管理が可能になります。

IAMの設定

Lambdaの実行ユーザーに、QuickSightとS3の操作の権限を与えます。
バケット名は、作成したバケット名を設定してください。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Action": [
				"quicksight:ListAnalyses",
				"quicksight:DescribeAnalysis",
				"quicksight:ListDataSets",
				"quicksight:DescribeDataSet",
				"quicksight:ListDataSources",
				"quicksight:DescribeDataSource",
				"quicksight:ListDashboards",
				"quicksight:DescribeDashboard"
			],
			"Resource": "*",
			"Effect": "Allow",
			"Sid": "AllowQuickSightReadAccess"
		},
		{
			"Action": [
				"s3:PutObject"
			],
			"Resource": "arn:aws:s3:::{バケット名}/*", 
			"Effect": "Allow",
			"Sid": "AllowS3PutObjectForBackup"
		}
	]
}

Lambda関数

Python 3.13 を使用してLambda関数を作成しました。
QuickSightの各リソースに対して 「一覧取得」 → 「詳細を取得」 → 「S3に保存」 という流れで処理を行っています。

import boto3
import json
import os
import logging

# ロガー設定
logger = logging.getLogger()
logger.setLevel(logging.INFO)

# S3設定(環境変数から取得)
S3_BUCKET = os.environ.get("S3_BUCKET_NAME")
S3_PREFIX = os.environ.get("S3_PREFIX")
REGION = os.environ.get("AWS_REGION")
ACCOUNT_ID = os.environ.get("AWS_ACCOUNT_ID")

quicksight = boto3.client("quicksight", region_name=REGION)
s3 = boto3.client("s3")

def upload_to_s3(category, item_id, content, name):
    """
    指定されたQuickSightリソースの情報をS3バケットにJSON形式でアップロードする

    Parameters:
        category (str): リソースのカテゴリ(例: "datasource", "dataset", "analysis", "dashboard")
        item_id (str): リソースの一意なID
        content (dict): アップロード対象のJSONデータ(describe_xxxのレスポンス)
        name (str): 表示名

    Raises:
        boto3.exceptions.Boto3Error: S3アップロードに失敗した場合にログにエラーを記録する
    """
    key = f"{S3_PREFIX}{category}/{category}_{item_id}.json"
    try:
        s3.put_object(
            Bucket=S3_BUCKET,
            Key=key,
            Body=json.dumps(content, indent=2, default=str),
            ContentType="application/json"
        )
        logger.info(f"S3アップロード成功: [{category.capitalize()}] {name} (ID: {item_id}) -> s3://{S3_BUCKET}/{key}")
    except Exception as e:
        logger.error(f"S3アップロード失敗: [{category.capitalize()}] {name} (ID: {item_id}) - エラー内容: {e}")

def backup_quicksight_resource(category, list_func_name, list_key, describe_func_name, id_key, name_key="Name"):
    """
    QuickSightリソースの一覧取得とS3バックアップを行う

    Parameters:
        category (str): リソースの種類(例: 'dataset')
        list_func_name (str): 一覧取得API名(例: 'list_data_sets')
        list_key (str): 一覧レスポンスのキー(例: 'DataSetSummaries')
        describe_func_name (str): 詳細取得API名(例: 'describe_data_set')
        id_key (str): IDフィールドのキー(例: 'DataSetId')
        name_key (str): 名前フィールドのキー(例: 'Name'"""
    logger.info(f"▼▼ {category.capitalize()} のバックアップ開始 ▼▼")

    try:
        list_func = getattr(quicksight, list_func_name)
        describe_func = getattr(quicksight, describe_func_name)
    except AttributeError as e:
        logger.error(f"API関数取得エラー: {e}")
        return

    try:
        resources = list_func(AwsAccountId=ACCOUNT_ID).get(list_key, [])
    except Exception as e:
        logger.error(f"{category.capitalize()}一覧取得失敗: {e}")
        return

    for item in resources:
        item_id = item.get(id_key)
        item_name = item.get(name_key, "Unknown")
        try:
            response = describe_func(AwsAccountId=ACCOUNT_ID, **{id_key: item_id})
            upload_to_s3(category, item_id, response, item_name)
        except quicksight.exceptions.InvalidParameterValueException as e:
            logger.warning(f"スキップ:「{item_name}({item_id})」 - {e}")
        except Exception as e:
            logger.error(f"エラー: 「{item_name}({item_id})」 - {e}")
    logger.info(f"▲▲ {category.capitalize()} のバックアップ終了 ▲▲")


def lambda_handler(event, context):
    try:
        backup_quicksight_resource(
            category="datasource",
            list_func_name="list_data_sources",
            list_key="DataSources",
            describe_func_name="describe_data_source",
            id_key="DataSourceId"
        )
        backup_quicksight_resource(
            category="dataset",
            list_func_name="list_data_sets",
            list_key="DataSetSummaries",
            describe_func_name="describe_data_set",
            id_key="DataSetId"
        )
        backup_quicksight_resource(
            category="analysis",
            list_func_name="list_analyses",
            list_key="AnalysisSummaryList",
            describe_func_name="describe_analysis",
            id_key="AnalysisId"
        )
        backup_quicksight_resource(
            category="dashboard",
            list_func_name="list_dashboards",
            list_key="DashboardSummaryList",
            describe_func_name="describe_dashboard",
            id_key="DashboardId"
        )

        return {
            "statusCode": 200,
            "body": json.dumps("QuickSight backup completed.")
        }

    except Exception as e:
        logger.error(f"バックアップ処理中に予期せぬエラーが発生しました: {e}", exc_info=True)
        return {
            "statusCode": 500,
            "body": json.dumps(f"QuickSight backup failed: {str(e)}")
        }

環境変数をセット

下記のパラメータを、Lambdaの環境変数にセットしてください

パラメータ 内容
AWS_ACCOUNT_ID AWSアカウントID(12桁の数字)
REGION LambdaおよびS3のリージョン
(例:ap-northeast-1)
S3_BUCKET_NAME 作成したS3バケット名
S3_PREFIX S3内でのバックアップファイル保存プレフィックス
(例:quicksight_backup/)

Lambdaコンソールは以下のような感じです。

image.png

実行

Lambdaを手動実行、もしくはEventBridgeなどで定期実行することで、S3にQuickSightの設定情報が以下のようなJSONファイルとして保存されます。

image.png

image.png

まとめ

今回は、QuickSightの設定情報をLambdaで自動的にS3にバックアップする方法を紹介しました。

これで、QuickSightの内容を消してしまっても大丈夫ですね!

次回は、このLambdaコードをGitHubで管理・デプロイする方法について紹介予定です。

Gitリポジトリをも公開しており、随時更新しております。興味のある方は、参考までにどうぞ!

ここまで読んで頂きありがとうございました!

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?