クロスアカウントでDynamoDBをS3バケットへエクスポートする

DynamoDBはテーブル全体または特定の期間のデータをS3へエクスポートする機能があります。

エクスポートしたデータはそのまま別テーブルとしてインポートをしたり、エクスポートしたデータをAthenaでクエリしたりできます。

エクスポートの目的が長期保存するアーカイブ用だったりデータ分析用だったりする場合、DynamoDBが稼働している本番環境とは別の開発用環境にエクスポートしたいと思う場面が多いのではないかと思います。

そこで今回は、DynamoDBテーブルを別アカウントのS3バケットへエクスポートする方法を紹介します。

方法

結論としては以下の公式ドキュメントに書いてある通りです。

ただ今回はAWSアカウントAAAAAAAAAAAAのDynamoDBからアカウントBBBBBBBBBBBBのS3へエクスポートする方法にフォーカスして紹介します。

別アカウントのDynamoDBからS3へエクスポートする

基本的には以下を実施します。

  • DynamoDBのポイントインタイムリカバリを有効にする
  • エクスポート元(AAAAAAAAAAAA)でユーザーに対して権限を付与する
  • エクスポート先(BBBBBBBBBBBB)でAAAAAAAAAAAAに対してバケットへアクセスを許可するバケットポリシーを付与する
  • CLIやコードからエクスポートする場合は引数で bucket owner を指定する(← ここでハマりました)
    • AWS CLI では --s3-bucket-owner
    • boto3 (Python) では S3BucketOwner

ポイントインタイムリカバリ(PITR)の有効化

DynamoDBにはポイントインタイムリカバリ(PITR)という仕組みがあります。

ここでは詳しくは説明しませんが、これが有効化されていることがS3エクスポートをする上で必須条件です。

Terraformの場合

resource "aws_dynamodb_table" "example" {
  # 〜〜省略〜〜
  point_in_time_recovery = "enabled"
}

参考: Resource: aws_dynamodb_table - Terraform Registry

CoudFormationの場合

---
Type: "AWS::DynamoDB::Table"
Properties:
  # 〜〜省略〜〜
  PointInTimeRecoverySpecification:
    PointInTimeRecoveryEnabled: true

参考: AWS::DynamoDB::Table - AWS CloudFormation

エクスポート元で設定するIAMポリシー

エクスポートを実行する主体に対してIAMポリシーをアタッチします。コンソールから人がエクスポートするならばそのユーザーへ、LambdaからエクスポートするならばそのLambdaのIAMロールへ、というイメージです。

公式ドキュメントからコピペですが、以下のポリシーを付与すればよいです(DynamoDBテーブルやS3バケットのARNは適宜変えてください)。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowDynamoDBExportAction",
            "Effect": "Allow",
            "Action": "dynamodb:ExportTableToPointInTime",
            "Resource": "arn:aws:dynamodb:us-east-1:111122223333:table/my-table"
        },
        {
            "Sid": "AllowWriteToDestinationBucket",
            "Effect": "Allow",
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::your-bucket/*"
        }
    ]
}

エクスポート先で設定するバケットポリシー

クロスアカウントでエクスポートする場合はS3バケットに対してエクスポート元からのアクセスを許可する必要があります。以下のポリシーをS3バケットに設定します(公式ドキュメントからのコピペです)。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ExampleStatement",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:user/Dave"
            },
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::awsexamplebucket1/*"
        }
    ]
}

上記は Dave というユーザーに権限を与える例ですが、Lambdaなどロールを割り当てる場合はこれではできません。

Principal にroleのARNを指定すればできそうなものですが、実はそうではないので注意です。なぜできないのかとどうすればできるかについては以下の記事にまとまっています。

特定ユーザーと特定のロールの両方を許可したい場合はこちらでできるそうです(試していません)。

ロールのID (ARNではなく) を調べる必要があったりと結構面倒なのでアカウント全体を許可する方が無難かもしれません(セキュリティ要件次第ですね)。その場合は root を指定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ExampleStatement",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::AAAAAAAAAAAA:root"
            },
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::dynamodb-export-bucket/*"
        }
    ]
}

バケットオーナーの指定

ただのクロスアカウントアクセスだと思っていると気づかないのですが、DynamoDBのS3エクスポート時にはバケットオーナーを明示する必要があります。

AWS CLI の場合:

aws dynamodb export-table-to-point-in-time \
  --table-arn arn:aws:dynamodb:ap-northeast-1:AAAAAAAAAAAA:table/TableName \
  --s3-bucket dynamodb-export-bucket \
  --s3-bucket-owner BBBBBBBBBBBB

2024年2月時点で最新のaws-cli 2.15.22で確認済みです。より正確な情報は最新のドキュメントでご確認ください。

参考: export-table-to-point-in-time - AWS CLI Command Reference

boto3の場合

dynamodb_client.export_table_to_point_in_time(
    TableArn='arn:aws:dynamodb:ap-northeast-1:AAAAAAAAAAAA:table/TableName',
    S3Bucket='dynamodb-export-bucket',
    S3BucketOwner='BBBBBBBBBBBB'
)

2024年2月時点で最新のBoto3 1.34.47で確認済みです。より正確な情報は最新のドキュメントでご確認ください。

参考: export_table_to_point_in_time - Boto3 documentation

まとめ

DynamoDBから別アカウントへのS3バケットへエクスポートする方法をまとめました。特に最後の「バケットオーナーの指定」は見落としやすいポイントなのでご注意ください。

最終更新 2024-03-21

広告

本記事はお役に立てたでしょうか。本ブログでは匿名でのコメントや少額から(15円~)の寄付などを受け付けております。もしお役に立てたのであればご支援いただけると大変励みになります。

Built with Hugo
テーマ StackJimmy によって設計されています。