CloudFormationを使ってQuickSightのデータセットをS3から作成してみた
いわさです。
以前、以下の記事にてQuickSightの分析とダッシュボードをCloudFormationを使って作成する方法をご紹介しました。
その際は、既にデータセットが作成されていることを前提に構築していましたが、CloudFormationではデータセットの作成も可能です。
そこで試してみたのですが、思ってた以上に苦労したのでつまづきポイントをまとめておきました。
公式ドキュメントにリファレンスは以下です。
AWS::QuickSight::DataSet - AWS CloudFormation
完成テンプレート
結論というか先に作成したテンプレートを載せておきます。
S3バケットにCSVファイルとマニフェストファイルをアップロードしている状態から、CloudFormationでデータを生成す場合の最小構成がおそらく以下のような感じになります。
AWSTemplateFormatVersion: 2010-09-09 Description: --- Resources: HogeDataSource: Type: AWS::QuickSight::DataSource Properties: AwsAccountId: !Ref AWS::AccountId Name: hoge-datasource DataSourceId: hoge-datasource-id Type: S3 DataSourceParameters: S3Parameters: ManifestFileLocation: Bucket: 20210327quicksightsampledata Key: hoge-manifest.json 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/hogeuser HogeDataSet: Type: AWS::QuickSight::DataSet Properties: Name: hoge-dataset AwsAccountId: !Ref AWS::AccountId DataSetId: hoge-dataset-id ImportMode: SPICE PhysicalTableMap: hoge-physical: S3Source: DataSourceArn: !GetAtt HogeDataSource.Arn InputColumns: - Name: hoge1 Type: STRING - Name: hoge2 Type: STRING LogicalTableMap: hoge-logical: Alias: hoge-logi DataTransforms: - CastColumnTypeOperation: ColumnName: hoge2 NewColumnType: INTEGER Source: PhysicalTableId: hoge-physical 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/hogeuser
ここから派生してRDSをデータソースとしたり、複数のデータソースから結合させたりなどさせると良いと思います。
ポイント・注意点・エラー例など
マニフェストファイルの参照方法と権限
以下のような形式のマニフェストファイルをS3バケットへアップロードしています。
が、CloudFormationを実行するとエラーになります。
Messages: - DataSource: Resource handler returned message: "Access denied for operation 'AWS::QuickSight::DataSource'." (RequestToken: 1c829f22-1773-ac71-d809-c1c315f705ca, HandlerErrorCode: AccessDenied)
こちらはシンプルにマニフェストファイルの指定方法が誤っていました。
ManifestFileLocation
のBucket
はバケット名で良いのですが、マニフェストファイルに引っ張られてs://
で記述してしまっていました。
Messages: - DataSource: Resource handler returned message: "Access denied for operation 'AWS::QuickSight::DataSource'." (RequestToken: 1c829f22-1773-ac71-d809-c1c315f705ca, HandlerErrorCode: AccessDenied)
こちらは、QuickSightからS3バケットへのアクセス権限がありませんでした。
QuickSightの管理画面からS3バケットアクセス時に対象バケットへのアクセス許可を追加しましょう。
PhysicalTableMapの宣言方法に注意
Messages: - HogeDataSet: Resource handler returned message: "Model validation failed (#: extraneous key [DataSourceArn] is not permitted)" (RequestToken: 0f174c20-a2fa-ad95-e919-4e727af6b0cf, HandlerErrorCode: InvalidRequest)
ここはかなりハマったのですが、マップ型なんですよね。
なので、以下のような構造になってしまっていないか確認してください。
HogeDataSet: Type: AWS::QuickSight::DataSet Properties: Name: hoge-dataset AwsAccountId: !Ref AWS::AccountId DataSetId: hoge-dataset-id ImportMode: SPICE PhysicalTableMap: S3Source: DataSourceArn: !GetAtt HogeDataSource.Arn
HogeDataSet: Type: AWS::QuickSight::DataSet Properties: Name: hoge-dataset AwsAccountId: !Ref AWS::AccountId DataSetId: hoge-dataset-id ImportMode: SPICE PhysicalTableMap: hoge-physical: S3Source: DataSourceArn: !GetAtt HogeDataSource.Arn
物理テーブルのカラム定義で許可されている列挙体文字列を確認する
Messages: - HogeDataSet: Properties validation failed for resource HogeDataSet with message: #/PhysicalTableMap/hoge/S3Source/InputColumns/0/Type: #: only 1 subschema matches out of 2 #/PhysicalTableMap/hoge/S3Source/InputColumns/0/Type: failed validation constraint for keyword [enum] #/PhysicalTableMap/hoge/S3Source/InputColumns/1/Type: #: only 1 subschema matches out of 2 #/PhysicalTableMap/hoge/S3Source/InputColumns/1/Type: failed validation constraint for keyword [enum] failed deploying stack 'hoge-datasource'
S3Source: DataSourceArn: !GetAtt HogeDataSource.Arn InputColumns: - Name: hoge1 Type: String - Name: hoge2 Type: Integer
InputColumnで許可されている値が以下のパターンのみなので、それに合っているか再確認しましょう。
気づかずに先頭大文字で記述してしまっていました。
AWS::QuickSight::DataSet InputColumn - AWS CloudFormation
S3Source: DataSourceArn: !GetAtt HogeDataSource.Arn InputColumns: - Name: hoge1 Type: STRING - Name: hoge2 Type: INTEGER
スタックの作成は出来たが、QuickSightの管理画面に表示されない
QuickSightはひとつひとつのリソースに権限設定が必要です。
APIから作成すると忘れやすいのですが明示的に許可する必要があります。
今回だとDataSetとDataSourceにそれぞれ以下のように設定を行ってやりましょう。
HogeDataSource: Type: AWS::QuickSight::DataSource Properties: : 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/hoge-user-name HogeDataSet: Type: AWS::QuickSight::DataSet Properties: : 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/hoge-user-name
S3でJSON以外のファイル形式の場合はSTRING以外許可されていない
Messages: - HogeDataSet: Resource handler returned message: "Invalid request provided: Input column hoge2 in physical table hoge has invalid type. Allowed types for S3 physical table are [String] (Service: QuickSight, Status Code: 400, Request ID: 4264a095-be59-4f52-8b0d-db819f3e3a68, Extended Request ID: null)" (RequestToken: 2bb9bbb9-3041-0743-cff7-90119cd16227, HandlerErrorCode: InvalidRequest)
今回だとCSVファイルをアップロードして使用したのですが、データセットの物理テーブルとしてはSTRING
以外許可されていないようです。
なので、ここではPhysicalTableMap
ではSTRING
ですべての列を定義する必要があります。
S3Source: DataSourceArn: !GetAtt HogeDataSource.Arn InputColumns: - Name: hoge1 Type: STRING - Name: hoge2 Type: STRING
これでエラーが出ずにデプロイ出来るようにはなるのですが、出来上がったデータセットを参照すると当然数値や日付としては利用出来ません。
対処方法として、LogicalTableMap
を使うことが可能です。
PhysicalTableMap
を変換や結合などを行って、実際に分析から利用する際にはLogicalTableMap
として扱います。
LogicalTableMap
へのマッピングは様々なオプションがあります。詳細は以下をご確認ください。
QuickSightのデータセット上で列を追加したり、加工や計算を行ったり、テーブル間で結合したりすることがありますが、データセット作成時に行うタイプのものは、このLogicalTableMap
で宣言します。
AWS::QuickSight::DataSet TransformOperation - AWS CloudFormation
ここでは以下のようにひとつの列を数値へ変換させました。
HogeDataSet: Type: AWS::QuickSight::DataSet Properties: : PhysicalTableMap: hoge-physical: S3Source: DataSourceArn: !GetAtt HogeDataSource.Arn InputColumns: - Name: hoge1 Type: STRING - Name: hoge2 Type: STRING LogicalTableMap: hoge-logical: Alias: hoge-logi DataTransforms: - CastColumnTypeOperation: ColumnName: hoge2 NewColumnType: INTEGER Source: PhysicalTableId: hoge-physical :
さいごに
本日はCloudFormationでQuickSightデータセットを作成する際につまづいたポイントをまとめました。
管理コンソールから手動操作したら数十秒で終わるデータセット作成ですが、CloudFormationとなると情報が少なくてほぼ自力でトライ&エラーしたのでえらい苦労しました。
この記事が同じように困った方の参考になると嬉しいです。