share facebook facebook facebook twitter twitter menu hatena pocket slack

2021.10.12 TUE

Google Cloud の Storage Transfer Serviceを使ってS3→GCSへデータ転送

Shimpei Chiba

WRITTEN BY Shimpei Chiba

これは一体…?

GCのStorage Transfer Serviceを使ってS3→GCSへデータ転送し、送信後はデータを送信元(S3)から削除する、までをやってみました。メモとして残します。

なお、今回VPC service controlsは使っていません。
GC公式の手順では、これを使用する方法が載っており、おそらくこの方がセキュアなんだろうと思いますが…

デフォルトでHTTPS使っている(以下参照)し、大丈夫だろうということでやってみました。

Storage Transfer Service では、デフォルトで次の処理を行います。
・ファイルがデータシンク内に存在しない場合、またはデータソースとデータシンクの間でファイルのバージョンが異なる場合は、
Storage Transfer Service はデータソースからファイルをコピーする。
・転送オペレーション後にソース内のファイルを保持する。
・HTTPs 接続に TLS 暗号化を使用する。唯一の例外は、URL リストの転送に HTTP URL を指定した場合です。

VPC service controlsを使うと得られるメリットは、今のところ以下だと考えています。
そもそもVPC service controlsは、仮想的なセキュリティの境界を定義して、GCへの各種リソースのアクセスを制限するものです。

  • 承認を受けたネットワーク以外は機密データにアクセスできないようにする
    →特定のIPからのみBQやGCSへアクセスを許可させる、など
  • BQやGCSのデータのコピー先、持ち出し先を、特定のGCプロジェクトに制限する。

この辺は機会があれば、今度まとめてみたいと思います。

前提

今回は検証、やってみた的なメモなので、本番環境などでは、念のためVPC service controls使用を考えた方がいいかなと思います。

やってみた

Access Context Manager, Cloud Storage, and Storage Transfer Service API を有効になっていることを確認

[IAM と管理] で、ストレージ管理者のロールと Access Context Manager 管理者のロールをアカウントに付与する
VPC service controls使わないのであれば、Access Context Manager 管理者のロールは必要ないと思います。

Storage Transfer Service 用の AWS IAM ポリシーを作成してバケットに適用する
公式手順

ただ、これだとなぜかできなかったので、画面下の方にあるポリシーに変えました。

AWS IAM ユーザーを AWS IAM ポリシーに追加する
公式手順

Cloud Storage バケットを作成する
公式手順

IAMポリシー
公式参考

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ここは任意",
            "Effect": "Allow",
            "Action": [
                "s3:PutAnalyticsConfiguration",
                "s3:PutAccessPointConfigurationForObjectLambda",
                "s3:GetObjectVersionTagging",
                "s3:DeleteAccessPoint",
                "s3:CreateBucket",
                "s3:DeleteAccessPointForObjectLambda",
                "s3:GetStorageLensConfigurationTagging",
                "s3:ReplicateObject",
                "s3:GetObjectAcl",
                "s3:GetBucketObjectLockConfiguration",
                "s3:DeleteBucketWebsite",
                "s3:GetIntelligentTieringConfiguration",
                "s3:PutLifecycleConfiguration",
                "s3:GetObjectVersionAcl",
                "s3:DeleteObject",
                "s3:CreateMultiRegionAccessPoint",
                "s3:GetBucketPolicyStatus",
                "s3:GetObjectRetention",
                "s3:GetBucketWebsite",
                "s3:GetJobTagging",
                "s3:GetMultiRegionAccessPoint",
                "s3:PutReplicationConfiguration",
                "s3:PutObjectLegalHold",
                "s3:GetObjectLegalHold",
                "s3:GetBucketNotification",
                "s3:PutBucketCORS",
                "s3:DescribeMultiRegionAccessPointOperation",
                "s3:GetReplicationConfiguration",
                "s3:ListMultipartUploadParts",
                "s3:PutObject",
                "s3:GetObject",
                "s3:PutBucketNotification",
                "s3:DescribeJob",
                "s3:PutBucketLogging",
                "s3:GetAnalyticsConfiguration",
                "s3:PutBucketObjectLockConfiguration",
                "s3:GetObjectVersionForReplication",
                "s3:GetAccessPointForObjectLambda",
                "s3:GetStorageLensDashboard",
                "s3:CreateAccessPoint",
                "s3:GetLifecycleConfiguration",
                "s3:GetInventoryConfiguration",
                "s3:GetBucketTagging",
                "s3:PutAccelerateConfiguration",
                "s3:GetAccessPointPolicyForObjectLambda",
                "s3:DeleteObjectVersion",
                "s3:GetBucketLogging",
                "s3:ListBucketVersions",
                "s3:RestoreObject",
                "s3:ListBucket",
                "s3:GetAccelerateConfiguration",
                "s3:GetBucketPolicy",
                "s3:PutEncryptionConfiguration",
                "s3:GetEncryptionConfiguration",
                "s3:GetObjectVersionTorrent",
                "s3:AbortMultipartUpload",
                "s3:GetBucketRequestPayment",
                "s3:DeleteBucketOwnershipControls",
                "s3:GetAccessPointPolicyStatus",
                "s3:UpdateJobPriority",
                "s3:GetObjectTagging",
                "s3:GetMetricsConfiguration",
                "s3:GetBucketOwnershipControls",
                "s3:DeleteBucket",
                "s3:PutBucketVersioning",
                "s3:GetBucketPublicAccessBlock",
                "s3:GetMultiRegionAccessPointPolicyStatus",
                "s3:ListBucketMultipartUploads",
                "s3:PutIntelligentTieringConfiguration",
                "s3:GetMultiRegionAccessPointPolicy",
                "s3:GetAccessPointPolicyStatusForObjectLambda",
                "s3:PutMetricsConfiguration",
                "s3:PutBucketOwnershipControls",
                "s3:DeleteMultiRegionAccessPoint",
                "s3:UpdateJobStatus",
                "s3:GetBucketVersioning",
                "s3:GetBucketAcl",
                "s3:GetAccessPointConfigurationForObjectLambda",
                "s3:PutInventoryConfiguration",
                "s3:GetObjectTorrent",
                "s3:GetStorageLensConfiguration",
                "s3:DeleteStorageLensConfiguration",
                "s3:PutBucketWebsite",
                "s3:PutBucketRequestPayment",
                "s3:PutObjectRetention",
                "s3:CreateAccessPointForObjectLambda",
                "s3:GetBucketCORS",
                "s3:GetBucketLocation",
                "s3:GetAccessPointPolicy",
                "s3:ReplicateDelete",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::S3バケットの名前"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:ListStorageLensConfigurations",
                "s3:ListAccessPointsForObjectLambda",
                "s3:GetAccessPoint",
                "s3:GetAccountPublicAccessBlock",
                "s3:ListAllMyBuckets",
                "s3:ListAccessPoints",
                "s3:ListJobs",
                "s3:PutStorageLensConfiguration",
                "s3:ListMultiRegionAccessPoints",
                "s3:CreateJob"
            ],
            "Resource": "arn:aws:s3:::S3バケットの名前/*"
        }
    ]
}

ただ、これだと、なぜか送信できなかったので、ググって以下のポリシーを参考にさせていただきました。

IAMポリシー
参考

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "s3:ListBucket",
               "s3:GetBucketLocation"
           ],
           "Resource": "arn:aws:s3:::S3バケットの名前"
       },
       {
           "Effect": "Allow",
           "Action": [
               "s3:GetObject"
           ],
           "Resource": "arn:aws:s3:::S3バケットの名前/*"
       }
   ]
}

ただ、こちらだと、ソース元が削除できないエラーが発生したので、最終的に以下にしました。

IAMポリシー

/// DeleteObjectを追加

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::S3バケットの名前"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::S3バケットの名前/*"
        }
    ]
}

ここに書いてありました。

転送を開始

公式手順

いざ転送!
なんですが、ファイルパス指定が最初よくわかりませんでした。

/ 例
Source
S3
path:2021/01/

Destination
Google Cloud Storage
path:logs/2021/01

の場合、GCSに届く時のファイルパスは、gcs-bucket/logs/2021/01/2021/01
になります。
→つまり、GCSのpath指定は、S3のファイル指定まで含める必要はないということを学びました。(二重になる)

転送成功

送信元からも削除されています。

参考

https://cloud.google.com/architecture/transferring-data-from-amazon-s3-to-cloud-storage-using-vpc-service-controls-and-storage-transfer-service
https://cloud.google.com/vpc-service-controls
https://medium.com/google-cloud/designing-secure-data-pipelines-with-vpc-service-controls-e3b4502307df
https://note.com/ucwork/n/n5fe04382409b
https://cloud.google.com/storage-transfer/docs/iam-transfer#source-permissions

参考にさせていただきました。ありがとうございます。

元記事はこちら

https://qiita.com/namely_/items/f5a9d0bed27aba2a06ef

cloudpack

cloudpackは、Amazon EC2やAmazon S3をはじめとするAWSの各種プロダクトを利用する際の、導入・設計から運用保守を含んだフルマネージドのサービスを提供し、バックアップや24時間365日の監視/障害対応、技術的な問い合わせに対するサポートなどを行っております。
AWS上のインフラ構築およびAWSを活用したシステム開発など、案件のご相談はcloudpack.jpよりご連絡ください。