0
0

More than 1 year has passed since last update.

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

Last updated at Posted at 2021-10-08

これは一体…?

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のファイル指定まで含める必要はないということを学びました。(二重になる)

転送成功

スクリーンショット 2021-10-07 15.29.20.png

スクリーンショット 2021-10-07 17.31.28.png

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

スクリーンショット 2021-10-07 17.31.43.png

参考

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

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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0