AWS DataSync でクロスアカウントの Amazon S3 ロケーションとの間でデータを転送してみた

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

アノテーションのスライマンです。

今回は AWS DataSync でクロスアカウントの Amazon S3 ロケーションとの間でデータを転送してみました。
下記のナレッジセンターを参考に追加の設定や変更を加えて、検証した結果をご紹介できればと思います。

AWS DataSync を使用して、クロスアカウントの Amazon S3 ロケーションとの間でデータを転送する方法を教えてください。

注意事項

クロスアカウントでのデータ転送をする際には、送信元のアカウントと送信先のアカウントを指定して、それぞれに必要なリソースやポリシーを設定致します。
まずはじめに、ナレッジセンターにも記載されている注意事項を含め、検証した際に実際に発見した注意事項をご紹介致します。

  • 送信元アカウントと送信先アカウントを決めた後、S3 ロケーションを送信元アカウントか送信先アカウントのどちらかに作成するか決める必要がございます。
    今回は S3 ロケーションを送信先アカウントに作成しますので、全ての DataSync のリソース(送信元のロケーション、送信先のロケーション、タスク)は送信先アカウントで作成します。

  • クロスアカウントパスロールを使用して、クロスアカウント S3 ロケーションにアクセスすることはできません。
    例として、送信先アカウントにログインした状態で、AWS CLI で S3 ロケーションを作成する際にバケットアクセスロールを送信元アカウントのロールを指定すると下記のエラーが発生します。

Cross-account pass role is not allowed

そのため、送信先アカウントにログインした状態で、AWS CLI で送信元の S3 ロケーションを作成する際にはバケットアクセスロールは送信先アカウントのロールを指定して、S3 バケットを送信元バケットを選択すると正常に作成することができます。

  • 送信元のS3バケットのバケットポリシーには、s3:ListBucket アクションを送信先アカウントで S3 ロケーションを作成する際に利用する IAMユーザー/ロールを指定する必要がございます。
    こちらの設定をしない場合に、送信先アカウントにログインした状態で、AWS CLI で送信元の S3 ロケーションを作成する際に下記のエラーが発生します。
An error occurred (InvalidRequestException) when calling the CreateLocationS3 operation: DataSync location access test failed: 
could not perform s3:HeadBucket on bucket XXX. Access denied. Ensure bucket access role has s3:ListBucket permission.
  • S3 バケットの ACL の設定は無効にしてください。

必要なリソース

送信元アカウント(A):

  • 送信元のS3バケット(バケットポリシー設定)

送信先アカウント(B):

  • 送信先のS3バケット(バケットポリシー設定不要)
  • IAM ロール:datasync-config-role (送信先バケットを指定)
  • IAM ロール:datasync-transfer-role(送信元バケットを指定)
  • 送信元のロケーション (AWS CLI で作成)
  • 送信先のロケーション(マネジメントコンソールで作成)
  • タスク(マネジメントコンソールで作成)

実際にやってみた

以下の流れで作業を進めていきます。

  • 送信元アカウント(A)で送信元の S3 バケットを作成して、転送するファイルをアップロードする
  • 送信先アカウント(B)で送信先の S3 バケットを作成する
  • 送信先アカウント(B)で IAM ロール datasync-config-role と datasync-transfer-role を作成する
  • 送信元アカウント(A)で送信元の S3 バケットのバケットポリシー設定する
  • 送信先アカウント(B)で送信元のロケーションを AWS CLI で作成する
  • 送信先アカウント(B)で送信先のロケーションをで作成する
  • 送信先アカウント(B)でタスクを作成して、実行する

送信元アカウント(A)で送信元の S3 バケットを作成して、転送するファイルをアップロードする

送信元アカウント(A)にログインして送信元の S3 バケットを作成します。
名前を入力して、残りの設定はそのままとして作成します。
後ほど、バケットポリシーを設定します。

転送するファイルをアップロードします。

送信先アカウント(B)で送信先の S3 バケットを作成する

送信先アカウント(B)にログインして送信元の S3 バケットを作成します。
名前を入力して、残りの設定はそのままとして作成します。
こちらの S3バケットのバケットポリシーの設定は不要です。

送信先アカウント(B)で IAM ロール datasync-config-role と datasync-transfer-role を作成する

送信先アカウント(B)にログインして datasync-config-role(DataSync 設定で使用される IAM ロール) と datasync-transfer-role (送信元 S3 ロケーションの作成時に割り当てられた IAM ロール)を作成していきます。

IAM ロール > ロールを作成 > 信頼されたエンティティタイプ:AWS のサービス(DataSync)> ポリシーを作成してアタッチ

信頼関係はどちらも AWS のサービス(DataSync)となります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "datasync.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

それぞれに必要なポリシーは下記となります。
下記以外のポリシーは必要ございません。

  • datasync-config-role
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:GetBucketLocation",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::送信先バケット"
        },
        {
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:ListMultipartUploadParts",
                "s3:GetObjectTagging",
                "s3:PutObjectTagging",
                "s3:PutObject"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::送信先バケット/*"
        }
    ]
}
  • datasync-transfer-role
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:GetBucketLocation",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::送信元バケット"
        },
        {
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:ListMultipartUploadParts",
                "s3:GetObjectTagging",
                "s3:PutObjectTagging",
                "s3:PutObject"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::送信元バケット/*"
        }
    ]
}

送信元アカウント(A)で送信元の S3 バケットのバケットポリシーを設定する

下記の通り、設定します。
"AWS": "arn:aws:sts::送信先アカウント:user/ユーザー名" には、送信先アカウントで AWS CLI で aws sts get-caller-identity を実施した結果を記載致します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::送信先アカウント:role/datasync-config-role",
                    "arn:aws:iam::送信先アカウント:role/datasync-transfer-role"
                ]
            },
            "Action": [
                "s3:GetBucketLocation",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads"
            ],
            "Resource": "arn:aws:s3:::送信元バケット"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::送信先アカウント:role/datasync-config-role",
                    "arn:aws:iam::送信先アカウント:role/datasync-transfer-role"
                ]
            },
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:ListMultipartUploadParts",
                "s3:PutObjectTagging",
                "s3:GetObjectTagging",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::送信元バケット/*"
        },
        {
            "Sid": "DataSyncCreateS3Location",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:sts::送信先アカウント:user/ユーザー名"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::送信元バケット"
        }
    ]
}

送信先アカウント(B)で送信元のロケーションを AWS CLI で作成する

AWS CLI で下記のコマンドを実施します。

aws datasync create-location-s3 --s3-bucket-arn arn:aws:s3:::送信元バケット --s3-storage-class STANDARD --s3-config BucketAccessRoleArn="arn:aws:iam::送信先アカウント:role/datasync-transfer-role" --region ap-northeast-1

正常に実施された場合は、下記の結果が返され、ロケーションが作成されます。

{
    "LocationArn": "arn:aws:datasync:ap-northeast-1:送信先アカウント:location/loc-xxxxxxxxxxxxx9c15"
}

送信先アカウント(B)で送信先のロケーションを作成する

下記を選択して送信先のロケーションを作成します。

  • ロケーションタイプ:S3
  • S3 バケット:送信先バケット
  • IAM ロール:arn:aws:iam::送信先アカウント:role/datasync-config-role

作成されたロケーションは下記となります。

送信先アカウント(B)でタスクを作成して、実行します。

下記を選択してタスクを作成します。
残りの設定はデフォルトのままとして作成します。

  • 送信元ロケーションを設定する→既存のロケーションを選択する:送信元のロケーション
  • 送信先ロケーションを設定する→既存のロケーションを選択する:送信先のロケーション

タスクを実行します。

Running の状態から、Available に変更すると転送は完了しており、送信先バケットにデータが転送されていることを確認します。

送信先バケットにデータが転送されていることを下記にて確認します。

最後に

クロスアカウント間の S3のデーターの転送は AWS DataSync を利用することで実施することが可能です。
送信元アカウントと送信先アカウントの IAMロールやバケットポリシーの設定を間違えやすいため、注意するとスムーズに実施することができます。
また、送信元アカウントから DataSync のリソース(送信元のロケーション、送信先のロケーション、タスク)を作成することもできますので、お試しいただければと存じます。
この記事がどなかのお役に立てば幸いです。

参考

アノテーション株式会社について

アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。