top of page
検索
  • 執筆者の写真mon

QuickSightアセットのクロスアカウントでのデプロイ(CloudFormation版)

以前の記事ではシンプルに分析をコピーする方法が紹介されています。


この記事ではdevelop環境でQuickSightのアセット(データセット・分析・ダッシュボードなど)をproduction環境にCloudFormationでデプロイする方法を紹介します。


実現したいこと


  • developで作成したQuickSightのデータセット・分析・ダッシュボードをproductionに複製したい

  • developでの修正を【継続的に】productionに反映したい

  • できるだけ個別のファイルを編集したくない


概要


  1. developから start-asset-bundle-export-job でCloudFormation形式でエクスポートする

  2. productionでCloudFormationを使ってデプロイする


シンプルにこれだけなのですが、productionで使えるようにするまでに細々とやることがあったのでそちらも紹介します。


develop環境にはCloudFormationでデプロイしないの?


Templateをゼロから書けばおそらくできるのですが、以下の理由からdevelopは手作業として運用しています。


  • 分析をつくる人はエンジニアとは限らない

  • QuickSightの分析を手書きで定義するのはしんどい


手順

データソースのデプロイ


develop環境もproduction環境もデータソースはGUIで作成せずに、CLIやCloudFormationなどでIDを指定して作成してください。

なぜかというと、データセットが参照するデータソースのIDを外部から与えることができず、productionとdevelopで同じデータソースIDを参照させる必要があるためです。


すでにデータセットを作成済みの場合、新しく固定のIDのデータソースをデプロイしてからデータセットの update-data-set で更新することができます。


CloudFormationでRedshiftに接続するデータソースを作成するCloudFormationテンプレートです。

  RedshiftDatasource:
    Type: AWS::QuickSight::DataSource
    Properties:
      DataSourceId: !Ref DataSourceId
      AwsAccountId: !Ref AWS::AccountId
      Credentials:
        CredentialPair:
          Username: !Sub "{{resolve:secretsmanager:${QuickSightRedshiftUserCredentialsArn}:SecretString:username}}"
          Password: !Sub "{{resolve:secretsmanager:${QuickSightRedshiftUserCredentialsArn}:SecretString:password}}"
      DataSourceParameters:
        RedshiftParameters:
          ClusterId: !Ref RedshiftClusterId
          Database: !Ref RedshiftDatabase
          Host: !Ref RedshiftHost
          Port: !Ref RedshiftPort
      Name: !Sub "Redshift"
      SslProperties:
        DisableSsl: false
      Type: REDSHIFT
      VpcConnectionProperties:
        VpcConnectionArn: !GetAtt VPCConnection.Arn

DataSourceId がとても重要です。ここに設定する値をdevelopとproductionで同じにしてください。


データセット・分析・ダッシュボードをdevelopで作成する


GUIでそれぞれ作成してください。ここでは、データセットのデータソースを上記で作成したデータソースにすること以外は特に注意・制限事項はありません。


developからアセットのエクスポート


start-asset-bundle-export-job コマンドでアセットをエクスポートします。

aws quicksight start-asset-bundle-export-job \
    --no-include-all-dependencies \
    --aws-account-id "${AWS_ACCOUNT_ID}" \
    --asset-bundle-export-job-id "${JOB_ID}" \
    --resource-arns "${QUICKSIGHT_RESOUCE_ARN}" \
    --export-format CLOUDFORMATION_JSON
  • --no-include-all-dependencies : これを指定しないと、依存するリソースがすべてファイルに含まれてしまいます。 例えば複数分析が参照しているデータセットがある場合に、分析をエクスポートするとそれぞれにデータセットが含まれてしまうのでこれを防ぎます。

  • --asset-bundle-export-job-id : 任意の文字列です。このあとファイルをダウンロードするときに使用します。

  • --resource-arns : 対象のリソースのARNです。

  • --export-format : CloudFormation形式かQuickSight独自のjson形式かを選択します。今回はCloudFormationを使います。


このコマンドを実行するとエクスポートのJOBが開始されるだけなので、結果は describe-asset-bundle-export-job コマンドで確認します。


aws quicksight describe-asset-bundle-export-job \
        --aws-account-id "${AWS_ACCOUNT_ID}" \
        --asset-bundle-export-job-id "${JOB_ID}" \
        --output text \
        --query JobStatus

--asset-bundle-export-job-id で start-asset-bundle-export-job と同じJOB IDを指定するとエクスポートJOBの状態が取得できます。

上記コマンドで "SUCESSFUL" が返ってきたら、今度は同じコマンドで DownloadUrl を取得します。(シェルスクリプトで使う関係でこの様になっていますが、同時に取得しても問題ありません)


aws quicksight describe-asset-bundle-export-job \
    --aws-account-id "${AWS_ACCOUNT_ID}" \
    --asset-bundle-export-job-id "${JOB_ID}" \
    --output text \
    --query DownloadUrl

DownloadUrlに設定されているS3のPresignedUrlからファイルをダウンロードします。


productionに持っていくものをすべて上記コマンドでCloudFormationテンプレート形式でダウンロードします。


ダウンロードされたデータセットのテンプレート

{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Description" : "Generated by AWS QuickSight for 001 started at 2024-06-13 07:58:38 UTC",
  "Resources" : {
    "3eeff8a3b0284cbdb7eb2E3731" : {
      "Properties" : {
        "AwsAccountId" : {
          "Fn::Sub" : "${AWS::AccountId}"
        },
        "DataSetId" : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "DataSetUsageConfiguration" : {
          "DisableUseAsDirectQuerySource" : false,
          "DisableUseAsImportedSource" : false
        },
        "FieldFolders" : { },
        "ImportMode" : "DIRECT_QUERY",
        "LogicalTableMap" : {
          "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" : {
            "Alias" : "table1",
            "DataTransforms" : [ {
              "ProjectOperation" : {
                "ProjectedColumns" : [ "col1", "col2" ]
              }
            } ],
            "Source" : {
              "PhysicalTableId" : "xxxxxxxx-xxxx-xxxx-xxxx
xxxxxxxxxxxx"
            }
          }
        },
        "Name" : "サンプルデータセット",
        "PhysicalTableMap" : {
          "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" : {
            "RelationalTable" : {
              "DataSourceArn" : {
                "Fn::Sub" :
"arn:${AWS::Partition}:quicksight:${AWS::Region}:${AWS::AccountId}:datasource/RedshiftDataSource"
              },
              "InputColumns" : [ {
                "Name" : "col1",
                "Type" : "STRING"
              }, {
                "Name" : "col2",
                "Type" : "STRING"
              } ],
              "Name" : "hashi_table1",
              "Schema" : "ofk"
            }
          }
        }
      },
      "Type" : "AWS::QuickSight::DataSet"
    }
  }
}

ここで DataSourceArnが定義されています。RegionとAcountIdは変数になっていますが、最後のDataSourceIdの部分が変更できません。そのため、DataSourceIdをdevelopとproductionで同一にしています。


ここでひと工夫

Descriptionプロパティには start-asset-bundle-export-job の実行時刻が入っています。

このままではQuickSight上で変更していないのに常にテンプレートに差分が発生してしまうので、jqコマンドなどで除外しておいたほうが良いです。


start-asset-bundle-export-jobの--cloud-formation-override-property-configurationオプションは使えるか?

--cloud-formation-override-property-configurationオプションは、指定したプロパティをCloudFormationテンプレート化時のパラメータにしてくれるものです。

DataSourceIdを可変=CloudFormationテンプレートパラメータにすれば、前述のようにDataSourceIdを固定化する必要はなさそうに見えます。

しかしながら、パラメータ化可能なものは決まっていて任意のプロパティのみをパラメータ化することはできませんでした。



productionへのデプロイ


start-asset-bundle-export-job でCloudFormation形式で出力したので、productionへの反映はテンプレートをデプロイするだけです。


Permissionの設定


CloudFormationでデプロイしただけではPermissionが設定されていないため誰からも参照できません。管理画面から明示的に共有する必要があります。

この操作は初回のみでOKです。


分析とダッシュボードの紐づけ


分析を更新して公開するとき通常はダッシュボードと紐づけがされていますが、CloudFormationで作成した直後はこのひも付けが無いために、ダッシュボードを書き換えることができません。

以下のコマンドを使って分析とダッシュボードを紐づけます。


aws quicksight update-dashboard-links \
    --aws-account-id "${AWS_ACCOUNT_ID}" \
    --dashboard-id "${DASHBOARD_ID}"
    --link-entities "${ANALYSIS_ARN}"
  • --dashboard-id : 対象のダッシュボードのID

  • --link-entities : 対象の分析のARN


IDとARNが混在していることに注意してください。


ここでハマったときにわかったのですが、ダッシュボード自体は分析に依存していないようです。

start-asset-bundle-export-job で得られたダッシュボードのテンプレートを見ると丸ごと分析の定義が含まれていることがわかります。


おそらくダッシュボードは、分析が公開された時点でその実態を内包して完結しているのだと思います。

さらに分析をダッシュボードとして公開するときには update-dashboard-links で設定されているリンク対象から「既存のダッシュボードを置き換える」の対象を決定しているようです。



まとめ


以上でdevelopで作成したQuickSightのアセットをproductionにデプロイできるようになりました。

以降はエクスポート → CloudFormationのStack更新で変更を反映できます。

CLIとCloudFormationでデプロイできるということは継続的デプロイメントのパイプラインに載せることも可能になってくると思います。



閲覧数:20回0件のコメント

最新記事

すべて表示

Quick Sightの分析のクロスアカウントコピー

はじめに 今回のブログではQuick Sightで作成した分析をクロスアカウントコピーするための方法を紹介します。 開発環境で作成した分析を本番環境にコピーしたい時などにこの方法が使えるのではないかと思います。 2024/07/12追記 QuickSightでアセット(データセット・分析・ダッシュボードなど)を管理する機能が追加されました。この機能を使って、アセットを複製する記事はこちらで紹介され

Amazon Redshiftのクエリがなぜかたまに遅くなる原因

始めに 弊社では、膨大なデータの夜間バッチ処理にRedshiftを採用しています。 適材適所でサービスを選択しており、夜間以外はお役御免で停止しておき、費用面を抑えるよう工夫しています。 メンテナンスウィンドウも設けて運用していて概ね問題なく稼働しています。 しかし、稀に全体的にクエリが遅くなってしまう謎の事象に悩まされていました。 今回この事象の原因を突き止めたので、その内容を共有したいと思いま

Comments


bottom of page