Athenaで他アカウントのテーブルを参照するために必要な設定

awsetl

Redshift Serverlessと他のサーバーレス集計サービス、Glue Data Catalogのテーブルへのクエリ実行 - sambaiz-net

クエリを実行するBorrower Accountから、Data Catalogやデータが存在するOwner Accountのリソースにアクセスする必要がある。 他アカウントのリソースにアクセスする手段としてはアクセストークンやAssumeRoleによるものもあるが、 今回の場合クエリの実行に用いるRoleにBorrower AccountのAthenaの権限も必要なので、1つのRoleで両方のアカウントのリソースにアクセスできるようにする。

AWSのAssumeRole - sambaiz-net

Glue Data Catalogへのクロスアカウントアクセス

Owner AccountのData CatalogのSettingsからBorrower Accountに権限の付与を許可する。

{
  "Version" : "2012-10-17",
  "Statement" : [ 
    {
        "Effect" : "Allow",
        "Principal" : {
          "AWS" : "<Borrower Account ID>"
        },
        "Action" : "glue:*",
        "Resource" : [
            "arn:aws:glue:ap-northeast-1:<Owner Account ID>:catalog",
            "arn:aws:glue:ap-northeast-1:<Owner Account ID>:database/*",
            "arn:aws:glue:ap-northeast-1:<Owner Account ID>:table/*"
        ]
    } 
  ]
}

S3へのクロスアカウントアクセス

同様にData Catalogが指しているS3の権限も付与できるようにする。これはBucket Policyから設定できる。

{
   "Version": "2012-10-17",
   "Statement": [
      {
          "Effect": "Allow",
          "Principal": {
             "AWS": "<Borrower Account ID>"
          },
          "Action": [
             "s3:GetObject",
             "s3:ListBucket"
          ],
          "Resource": [
             "arn:aws:s3:::<Owner Bucket>/*",
             "arn:aws:s3:::<Owner Bucket>"
          ]
       }
    ]
}

Athenaのデータソースの作成

Borrower AccountのAthenaにOwner AccountのGlue Data Catalogのデータソースを作成する。

Policyのアタッチ

クエリの実行に必要な、両アカウントのリソースのPolicyをRoleにアタッチしクライアントで用いる。

{
    "Effect": "Allow",
    "Action": "athena:*",
    "Resource": "arn:aws:athena:ap-northeast-1:<Borrower Account ID>:workgroup/<workgroup_name>"
},
{
    "Effect": "Allow",
    "Action": "athena:GetDataCatalog",
    "Resource": "arn:aws:athena:ap-northeast-1:<Borrower Account ID>:datacatalog/<data_source_name>"
},
{
    "Effect": "Allow",
    "Action": [
        "s3:GetBucketLocation",
        "s3:GetObject",
        "s3:ListBucket",
        "s3:ListBucketMultipartUploads",
        "s3:ListMultipartUploadParts",
        "s3:AbortMultipartUpload",
        "s3:PutObject"
    ],
    "Resource": [
        "arn:aws:s3:::<athena_query_results_bucket>",
        "arn:aws:s3:::<athena_query_results_bucket>/*"
    ]
},
{
    "Effect": "Allow",
    "Action": "glue:*",
    "Resource": [
        "arn:aws:glue:ap-northeast-1:<Owner Account ID>:catalog",
        "arn:aws:glue:ap-northeast-1:<Owner Account ID>:database/*",
        "arn:aws:glue:ap-northeast-1:<Owner Account ID>:table/*"
    ]
},
{
    "Effect": "Allow",
    "Action": [
        "s3:GetObject",
        "s3:ListBucket",
    ],
    "Resource": [
        "arn:aws:s3:::<Owner Bucket>",
        "arn:aws:s3:::<Owner Bucket>/*"
    ]
},
{
    "Effect": "Allow",
    "Action": [
        "s3:GetBucketLocation",
        "s3:GetObject",
        "s3:ListBucket",
        "s3:ListBucketMultipartUploads",
        "s3:ListMultipartUploadParts",
        "s3:AbortMultipartUpload",
        "s3:PutObject"
    ],
    "Resource": [
        "arn:aws:s3:::<athena_query_results_bucket>",
        "arn:aws:s3:::<athena_query_results_bucket>/*"
    ]
}

これで他アカウントのGlue Data Catalogのテーブルを参照できるようになる。

SELECT * FROM <data_source_name>.<database>.<table>