はじめに
前回、QuickSightをCloudFormationで操作した内容を記事にしました。
"分析"や"ダッシュボード"に関しても試してみたので記事にします。
概要
- CloudFormationでは、"分析"や"ダッシュボード"をゼロから構築することはできない。
- GUIで作成した"分析"をテンプレートにして、それを基に"分析"と"ダッシュボード"を作成することは、CloudFormationで出来る。
- "分析"のテンプレートから、"分析"と"ダッシュボード"の両方が複製できます。
- そのため今回は「複製する」というテーマで、複製元でテンプレートを作って複製先に配布する、という内容。
参考
構築
複製元
1.共通部分作成
まずは複製元で環境を作っていきます。
前の記事と同様に、共通部分から作ります。
コードは前回とほぼ同じものですので説明は省きます。
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Env:
Type: String
Resources:
RawDataBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub raw-data-${AWS::AccountId}-${AWS::Region}-${Env}
BucketEncryption:
ServerSideEncryptionConfiguration:
-
ServerSideEncryptionByDefault:
SSEAlgorithm: 'AES256'
BucketKeyEnabled: false
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
AthenaQueryResultBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub query-result-${AWS::AccountId}-${AWS::Region}-${Env}
BucketEncryption:
ServerSideEncryptionConfiguration:
-
ServerSideEncryptionByDefault:
SSEAlgorithm: 'AES256'
BucketKeyEnabled: false
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
LifecycleConfiguration:
Rules:
-
Id: 'auto-delete'
Status: 'Enabled'
ExpirationInDays: 7
AthenaWorkGroup:
Type: AWS::Athena::WorkGroup
Properties:
Name: !Sub athena-work-group-${Env}
RecursiveDeleteOption: true
WorkGroupConfiguration:
ResultConfiguration:
OutputLocation: !Sub s3://${AthenaQueryResultBucket}/data
EncryptionConfiguration:
EncryptionOption: 'SSE_S3'
EnforceWorkGroupConfiguration: true
PublishCloudWatchMetricsEnabled: true
GlueDatabase:
Type: AWS::Glue::Database
Properties:
CatalogId: !Ref AWS::AccountId
DatabaseInput:
Name: !Sub glue-database-${Env}
Outputs:
RawDataBucket:
Value: !Ref RawDataBucket
Export:
Name: !Sub "${Env}-RawDataBucket-Name"
AthenaQueryResultBucket:
Value: !Ref RawDataBucket
Export:
Name: !Sub "${Env}-AthenaQueryResultBucket-Name"
AthenaWorkGroup:
Value: !Ref AthenaWorkGroup
Export:
Name: !Sub "${Env}-AthenaWorkGroup-Name"
GlueDatabase:
Value: !Ref GlueDatabase
Export:
Name: !Sub "${Env}-GlueDatabase-Name"
2.QuickSightからのアクセス許可を設定
やり方は前回と同じです。
3.データを格納
前回と同じデータを使っています。
4.個別部分作成
Athenaテーブルや、DataSetを作っていきます。
コードは前回を手直ししています。
- 複製元でも複製先でも使えるようにしています。
- 複製元の場合:DataSet作成まで
- 複製先の場合:DataSetを作成し、"分析"と"ダッシュボード"も作成
- パラメータ
SourceTemplateArn
の指定の有無で、作成する/しないを制御
- パラメータ
Analysis
やDashboard
についてパラメータ化が中途半端ですがご容赦ください。「どういうDataSetを、どういう風に参照するか」等の設定はパラメータ化するのが難しいので、直接コードを変更してください。
DataSetPlaceholder
は、のちの分析テンプレート作成時と同じ文字列を指定してください。(詳細はテンプレート作成コードのところで)
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Env:
Type: String
TableName:
Type: String
Description: Table name must not contain uppercase characters.
QuickSightAdminUser:
Type: String
Description: user must not be asterisk(*).
SourceTemplateArn:
Type: String
Default: ''
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: User Setting.
Parameters:
- Env
- TableName
- QuickSightAdminUser
- SourceTemplateArn
# SourceTemplateArnが空文字なら作らない
Conditions:
CreateAnalysis:
!Not [!Equals [ !Ref SourceTemplateArn , '']]
Resources:
# Athena Table
GlueTable:
Type: AWS::Glue::Table
Properties:
CatalogId: !Ref AWS::AccountId
DatabaseName:
Fn::ImportValue:
!Sub "${Env}-GlueDatabase-Name"
TableInput:
Name: !Ref TableName
TableType: EXTERNAL_TABLE
Parameters:
skip.header.line.count: 1
has_encrypted_data: false
serialization.encoding: utf-8
EXTERNAL: true
StorageDescriptor:
OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
Columns:
- Name: source
Type: string
- Name: destination
Type: string
InputFormat: org.apache.hadoop.mapred.TextInputFormat
Location:
Fn::Join:
- ''
- - 's3://'
- Fn::ImportValue: !Sub "${Env}-RawDataBucket-Name"
- '/data'
SerdeInfo:
Parameters:
field.delim: ","
serialization.format: ","
SerializationLibrary: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
# QuickSight DataSource
AthenaDataSource:
Type: AWS::QuickSight::DataSource
Properties:
AwsAccountId: !Ref AWS::AccountId
Name: !Sub "${Env}-Athena"
DataSourceId: !Sub "${Env}-Athena-Id"
Type: ATHENA
DataSourceParameters:
AthenaParameters:
WorkGroup:
Fn::ImportValue:
!Sub "${Env}-AthenaWorkGroup-Name"
Permissions:
- Actions:
- quicksight:UpdateDataSourcePermissions
- quicksight:DescribeDataSource
- quicksight:DescribeDataSourcePermissions
- quicksight:PassDataSource
- quicksight:UpdateDataSource
- quicksight:DeleteDataSource
Principal: !Sub arn:aws:quicksight:${AWS::Region}:${AWS::AccountId}:user/default/${QuickSightAdminUser}
# QuickSight DataSet
RepDataSet:
Type: AWS::QuickSight::DataSet
Properties:
AwsAccountId: !Ref AWS::AccountId
Name: !Sub "Select-${GlueTable}"
DataSetId: !Sub "Select-${GlueTable}-Id"
ImportMode: SPICE
PhysicalTableMap:
rep-physical:
RelationalTable:
DataSourceArn: !GetAtt AthenaDataSource.Arn
# Set Database Name
Schema:
Fn::ImportValue:
!Sub "${Env}-GlueDatabase-Name"
# Set Table Name
Name: !Ref GlueTable
InputColumns:
- Name: source
Type: STRING
- Name: destination
Type: STRING
Permissions:
- Actions:
- quicksight:UpdateDataSetPermissions
- quicksight:DescribeDataSet
- quicksight:DescribeDataSetPermissions
- quicksight:PassDataSet
- quicksight:DescribeIngestion
- quicksight:ListIngestions
- quicksight:UpdateDataSet
- quicksight:DeleteDataSet
- quicksight:CreateIngestion
- quicksight:CancelIngestion
Principal: !Sub arn:aws:quicksight:${AWS::Region}:${AWS::AccountId}:user/default/${QuickSightAdminUser}
Analysis:
Type: AWS::QuickSight::Analysis
Condition: CreateAnalysis
Properties:
AwsAccountId: !Ref AWS::AccountId
AnalysisId: 'Sample-Analysis-From-Temp-Id'
Name: 'Sample-Analysis-From-Temp'
SourceEntity:
SourceTemplate:
Arn: !Ref SourceTemplateArn
DataSetReferences:
-
DataSetPlaceholder: 'DataSet001Placeholder'
DataSetArn: !GetAtt RepDataSet.Arn
Permissions:
-
Principal: !Sub arn:aws:quicksight:${AWS::Region}:${AWS::AccountId}:user/default/${QuickSightAdminUser}
Actions:
- quicksight:RestoreAnalysis
- quicksight:UpdateAnalysisPermissions
- quicksight:DeleteAnalysis
- quicksight:DescribeAnalysisPermissions
- quicksight:QueryAnalysis
- quicksight:DescribeAnalysis
- quicksight:UpdateAnalysis
Dashboard:
Type: AWS::QuickSight::Dashboard
Condition: CreateAnalysis
Properties:
AwsAccountId: !Ref AWS::AccountId
DashboardId: 'Sample-Dashboard-From-Temp-Id'
Name: 'Sample-Dashboard-From-Temp'
DashboardPublishOptions:
AdHocFilteringOption:
AvailabilityStatus: ENABLED
ExportToCSVOption:
AvailabilityStatus: DISABLED
SheetControlsOption:
VisibilityState: EXPANDED
SourceEntity:
SourceTemplate:
Arn: !Ref SourceTemplateArn
DataSetReferences:
-
DataSetPlaceholder: 'DataSet001Placeholder'
DataSetArn: !GetAtt RepDataSet.Arn
Permissions:
-
Principal: !Sub arn:aws:quicksight:${AWS::Region}:${AWS::AccountId}:user/default/${QuickSightAdminUser}
Actions:
- quicksight:DescribeDashboard
- quicksight:ListDashboardVersions
- quicksight:UpdateDashboardPermissions
- quicksight:QueryDashboard
- quicksight:UpdateDashboard
- quicksight:DeleteDashboard
- quicksight:DescribeDashboardPermissions
- quicksight:UpdateDashboardPublishedVersion
5."分析"の作成
QuickSightにアクセスして、見せたいビジュアルを作成してください。
今回は名称変換的なデータなので、サンキーダイアグラムで表してみました。(グラフ的には無価値です)
6.分析テンプレートの作成
分析テンプレートはCloudFormationから作ります。
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
TemplateId:
Type: String
DataSet001Arn:
Type: String
TargetAnalysisArn:
Type: String
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: User Setting.
Parameters:
- TemplateId
- DataSet001Arn
- TargetAnalysisArn
Resources:
AnalysisTemplate:
Type: AWS::QuickSight::Template
Properties:
AwsAccountId: !Ref AWS::AccountId
Name: !Sub "${TemplateId}-Analysis-Template"
TemplateId: !Sub "${TemplateId}-Analysis-Template-Id"
SourceEntity:
SourceAnalysis:
Arn: !Ref TargetAnalysisArn
DataSetReferences:
-
DataSetPlaceholder: 'DataSet001Placeholder'
DataSetArn: !Ref DataSet001Arn
# ここは手作成
Permissions:
-
Principal: 'arn:aws:iam::123456789012:root'
Actions:
- quicksight:DescribeTemplate
Outputs:
AnalysisTemplate:
Value: !GetAtt AnalysisTemplate.Arn
Export:
Name: !Sub "${TemplateId}-Analysis-Template-Arn"
パラメータについては以下を指定してください。
- TemplateId
- 任意の文字列
- DataSet001Arn
- "分析"で使用しているデータセットのリソースネームを指定
- TargetAnalysisArn
- "分析"のリソースネームを指定
リソースネームを取得するコマンドはそれぞれ以下になります。
# データセットのリソースネームを取得
aws quicksight list-data-sets --aws-account-id 123456789012
# "分析"のリソースネームを取得
aws quicksight list-analyses --aws-account-id 123456789012
# 作成したテンプレートを確認
aws quicksight list-templates --aws-account-id 123456789012
Permissions
は、同アカウント内に複製する場合は設定する必要ありません。
別アカウントで複製する場合は参照できるよう権限を設定する必要があります。
QuickSightの分析テンプレートで定義するDataSetPlaceholder
について
- 分析で用いるデータセットを指定するKeyのように用いられているようです
- 用いるデータセットが2つ以上ある場合はわかりやすい名前を付けるのがいいと思います
-
01_createDataSet.yaml
で、”同じ名前と、同じ使われ方をするデータセット”のペア、を指定する必要があります - プレースホルダー名の例
- purchaseData / customerMaster
- cmData / programData / companyData
-
- 複製先で
DataSetPlaceholder
の与え方を間違えると、以下のようなエラーに
Invalid request provided: Given placeholders [HogeHogePlaceholder] are not part of template (Service: QuickSight, Status Code: 400, Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
複製先
7.共通部分作成~データを格納
複製先のアカウントで、1.共通部分作成、2.QuickSightからのアクセス許可を設定、3.データを格納を行ってください。
8.個別部分、"分析"と"ダッシュボード"の作成
4.個別部分作成と同じコードで、今回はパラメータに6.分析テンプレートの作成で作成された分析テンプレートのARNを指定して実行してください。
"分析"と"ダッシュボード"に、同じサンキーダイアグラムができているはずです。
削除
作成順と逆順で削除されます。"分析"と"ダッシュボード"もちゃんと消えてくれます。
おわりに
今回はビジュアルもIaCで作成してみました。
「ベースのダッシュボードをテンプレート化しておき、他アカウントに複製した後、個別のカスタマイズをする」などの用途で使えるのではないでしょうか。