QuickSight + Athena から別アカウントの S3 に接続してみた
やりたいこと
本ブログでは上記の構成を作ります。
アカウント AAA の S3 バケットのデータをアカウント BBB の QuickSight + Athena で可視化します。
なお、権限設定が適切でないと以下のエラーが出ますが、本ブログではこのエラーが出ることも確認したいと思います。
com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied ...
S3 バケット作成 (アカウント AAA)
まず、S3 バケット(test-bucket-account-aaa)をデフォルト設定で作成します。
以下のサンプルデータをローカルで作成し、S3 にアップロードします。
UserName,Place
Takahashi,Tokyo
Kimura,Fukuoka
Nakamura,Tokyo
Satou,Osaka
アップロードできました。
Athena から S3 を可視化する (アカウント BBB)
まずは、Athena と S3 を繋いでいきます。
Athena クエリエディタから以下クエリを実行し、アカウント AAA の S3 を参照する Athena テーブルを作成します。
クエリ内容に記載されてはいますが、Athena の default データベースにテーブル名 test_table を作成するクエリになります。
また、LOCATION 句 にアカウント AAA の S3 バケット(test-bucket-account-aaa)を指定しています。
CREATE EXTERNAL TABLE IF NOT EXISTS `default`.`test_table` (`UserName` string, `Place` string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES ('field.delim' = ',')
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://test-bucket-account-aaa/'
TBLPROPERTIES (
'classification' = 'csv',
'skip.header.line.count' = '1'
);
※補足:上記クエリはコンソールからも作成できます。試される際は下記ブログなどをご参照ください。
上記クエリを実行後、default データベースに test_table が作成されていることが確認できました。
現時点で、 S3 バケット(test-bucket-account-aaa)に Athena からクエリが実行できるか確認してみますが、エラーとなります。
com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; ...
上記エラーの原因は、アカウント AAA の S3 バケットポリシーにアカウント BBB の Athena からのアクセス許可を設定していないためです。
そのため、公式ドキュメント-AthenaからクロスアカウントS3へのアクセスを許可するを参考に以下のようにアカウント AAA 側にて S3 バケットポリシーを設定します。
なお、Principal の部分はご自身が使用中の IAM ユーザーや IAM ロールに適宜変更してください。自分の場合は、IAM ユーザーでログインして Athena を実行しているため、IAM ユーザーからのアクセスを許可する設定にしています。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "MyStatementSid",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<アカウント BBB>:user/<ユーザー名>"
},
"Action": [
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListMultipartUploadParts",
"s3:AbortMultipartUpload"
],
"Resource": [
"arn:aws:s3:::test-bucket-account-aaa",
"arn:aws:s3:::test-bucket-account-aaa/*"
]
}
]
}
バケットポリシーを設定したら、再度 SELECT 文を実行します。今度は成功しました。
これで Athena から別アカウントの S3 のデータを参照するまでを実現できました。
QuickSight で可視化する
前項までで Athena と S3 が繋がったので、続いて QuickSight から Athena データソースを作成し可視化してみます。
QuickSight のデータセット作成から Athena を選び、テーブルは前項にて作成した test_table を選択します。
その後以下の画面にて「データの編集/プレビュー」をします。
データ編集画面に行くと、以下のようにエラーが発生し、現時点ではデータが取得できないことがわかります。
エラー文内の「詳細を表示」を選択すると先ほど、Athena のクエリエディタで確認した時と同様のエラーが出ています。
Query execution failed: com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied ...
上記エラーが発生する原因は、以下の 2 つの設定が適切にできていないためです。
- アカウント AAA の S3 バケットポリシーにて、アカウント BBB の QuickSight サービスロールからのアクセスを許可していない
- QuickSight の「セキュリティとアクセス許可」設定にてアカウント AAA にある S3 バケットが追加できていない
前項のように Athena から直接クエリが実行される場合は、アカウント BBB にログイン中の IAM ユーザーや IAM ロールの権限が使用されるため、その権限をバケットポリシーにて許可することで実行ができます。
一方、QuickSight から Athena を経由して別アカウントにある S3 バケットに接続する際は、デフォルトで QuickSight サービスロールが使用されるため、上記のエラーが発生します。
エラー改善するため、まずはアカウント AAA のバケットポリシーを修正します。
前提として、QuickSight は他サービスと通信する際、以下公式ブログにある通り、aws-quicksight-service-role-v0 の IAM ロールを使用します。
QuickSight が他の AWS サービスと通信する際、QuickSight はサービスロール aws-quicksight-service-role-v0 および aws-quicksight-s3-consumers-role-v0 を引き受け、ロールにマネージドポリシーをアタッチします。
QuickSight で発生する AWS リソースへのアクセス許可に関するエラーをトラブルシューティングする方法を教えてください。
そのため、IAM コンソールから本ロールの ARN をコピーし、以下のようにバケットポリシーの Principal に追加します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "MyStatementSid",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<アカウント BBB>:role/service-role/aws-quicksight-service-role-v0",
"arn:aws:iam::<アカウント BBB>:user/<ユーザー名>"
]
},
"Action": [
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListMultipartUploadParts",
"s3:AbortMultipartUpload"
],
"Resource": [
"arn:aws:s3:::test-bucket-account-aaa",
"arn:aws:s3:::test-bucket-account-aaa/*"
]
}
]
}
続いて、QuickSight の「セキュリティとアクセス許可」画面にて「管理」を選び、クロスアカウント先の S3 バケットを追加します。
「AWS 全体でアクセスできる S3 バケット」タブから、アカウント AAA のバケット(test-bucket-account-aaa) を追加します。
上記設定後、更新を保存したら、権限設定のエラーは無くなるはずです。
動作確認
先ほどのエラーが発生している状態の QuickSight データ編集画面から「今すぐ更新」をしてみます。
以下画像より、エラーが解消し S3 データを参照できていることがわかります。無事 QuickSight + Athena から別アカウントの S3 にあるデータに接続できました。
終わりに
今回は、QuickSight+Athena でクロスアカウントにある S3 データを参照してみました。
無事に動いてよかったです。エラーを出しながら進むことで、実際に権限周りがどのように働いているのか理解でき、とても勉強になりました。一番のポイントは QuickSight から他サービスアクセスする際は、QuickSight 独自のサービスロールが使われる点かなと思います。この辺りはやってみないと実感が湧かないので、実際に検証できて良かったと思いました。
本記事がどなたかのお役に立てば幸いです。
参考情報