S3からGCSへのデータ転送(AWSのIAM情報もらうパターン)


普段はGCP(GCS)ばっかり使ってて
「別クラウドからデータ受領」みたいなことをしたことなかったので
社外のどっかの会社がAWS(S3)にデータを配置してる想定で
社内のGCP(GCS)にデータを転送するシチュエーションをやってみた

データ転送パターン

1. インターネット(https)経由
  a. こちらからAWS(S3)にアクセスしてGCP(GCS)にデータ転送★
  b. 相手の会社の担当がAWS(S3)からGCP(GCS)にデータ転送
2. インターネットVPN(IPsec)経由
  a. インターネット経由はヤダって言われた時によりセキュアな提案
3. 専用線経由(Partner/Dedicated Interconnect)
  a. インターネットVPNすらダメで、専用線繋いでよ!と言われた場合

上記のようなパターンが考えられるが
とりあえず、★の「インターネット経由&こちらからAWSにアクセス想定」で実験してみる

実現イメージ

1. ファイルを配置するS3を準備してもらう
2. S3にアクセスするためのIAMユーザーを作成してもらう
3. S3へのアクセス権限を付与(以下いずれか。今回はb.)
  a. 対象のS3にIAMユーザーがアクセスできるようにBucketポリシー指定
  b. IAMユーザーがS3にアクセスできるようにIAMポリシー指定
4. IAMユーザーのCredential情報を受領
5. S3->GCSへのデータ移行実施

前提知識

S3のセキュリティ関連
あんまり業務でAWS触ってないので改めて調べてみる
S3のアクセス制御はざっくりこの3つで制御してるイメージ
1. Bucket ポリシー
 Bucket(オブジェクト含む)に対して誰がアクセスできるかjsonで制御
2. ACL(Bucket/Object)
 BucketまたはObjectに対してで誰がアクセス制御できるかxmlで制御
3. IAM ポリシー
 IAMユーザー/グループに対してどのBucketにアクセスできるかjsonで制御

ACLっているのかしら
Bucket ポリシーの説明みる感じバケット・オブジェクトレベルでアクセス制御指定できそうだが、ACLって必要なのかしら? とふと思ったが

バケット・オブジェクトACLそれぞれ使うシチュエーションはあるみたい
例えば、別のAWSアカウントBが、AWSアカウントAの作成したバケットにオブジェクトを作成した場合、
オブジェクトの所有者はアカウントBになるので、アカウントAがバケットポリシー指定してもアクセス制御できないらしい。
この場合、ACLしかそのオブジェクトを制御することできない。
みたいに使う必要のある場面はあるらしい

ただあんま制御してる箇所が分散すると訳わからんくなるし、xml書きたくないので基本はBucket、IAMポリシーくらいで制御したいところ

AWS持ってる相手にお願いすること

連携用のS3バケットを準備してもらう
既存のS3でもいいが、試しにS3バケット作成してみる
適当な名前でバケット作成

画像19

テストなのでオプションは特に指定せず

画像5

Block public accessは指定しておく
こいつを設定しておくとS3がpublic公開される事故を防げる

画像5

Create bucket

画像19

フォルダ毎にアクセス制御できるか検証したいので
アクセスできるフォルダ「access_allow」とアクセスできないフォルダ「access_deny」を作成して、適当なcsvファイル配置しとく

画像19

連携用のIAMユーザーを作成
IAM->Users->Add userでユーザー作成
とりあえず適当なuser nameとpasswordを入れる

画像6

パーミッションは後でつけるので一旦無視

画像7

tagも特につけずnext

画像8

create user

画像9

credentialは後で使うのでDownload .csvしとく

画像19

IAMユーザーでバケットにアクセスできないことを確認
作成したユーザーでログインしてS3みると作成したバケット見れない

スクリーンショット 2020-07-12 23.15.17

IAMポリシーの設定
IAMユーザーに作成したバケットの特定フォルダにアクセスできる
インラインポリシー作成

スクリーンショット 2020-07-14 23.07.42

以下jsonのように書けば行けるはず。
(「s3:ListBucket」の方はResourceに「arn:aws:s3:::data-for-gcs/access_allow/*」って書いてもうまくいかなかった...)

{
  "Version": "2012-10-17",
  "Statement": [
      {
          "Effect": "Allow",
          "Action": [
              "s3:ListBucket"
          ],
          "Resource": "arn:aws:s3:::[aws_bucket_name]",
          "Condition": {
              "StringLike": {
                  "s3:prefix": "access_allow/*"
              }
          }
      },
      {
          "Effect": "Allow",
          "Action": [
              "s3:GetObject"
          ],
          "Resource": "arn:aws:s3:::[aws_bucket_name]/access_allow/*"
      }
  ]
}

検証してみる
対象バケットのフォルダurlにはアクセスできるが、ファイルが見えない🤔

スクリーンショット 2020-07-14 23.13.03

AWS CLIで確認する
公式に書いてあるとおりインストール

curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /

# IAM作成時にダウンロードしたcsvの情報を入力
aws configure

アクセス確認してみる

aws s3 ls s3://[aws_bucket_name]/access_allow/
2020-07-12 22:44:44          0
2020-07-12 22:47:02         14 test.csv
# 見れた!

aws s3 ls s3://[aws_bucket_name]/access_deny/
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
# 見れない!!

でけた。UIで見えるようにするにはもっとActionの指定が必要説

S3のバケットポリシーだけでも行けるか検証
IAMポリシーを削除してバケットポリシーにIAMのarnを指定

スクリーンショット 2020-07-14 23.31.03

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Principal": {
               "AWS": "[user arn]"
           },
           "Action": "s3:ListBucket",
           "Resource": [
               "arn:aws:s3:::[aws_bucket_name]"
           ],
           "Condition": {
               "StringLike": {
                   "s3:prefix": "access_allow/*"
               }
           }
       },
       {
           "Effect": "Allow",
           "Principal": {
               "AWS": "[user arn]"
           },
           "Action": "s3:GetObject",
           "Resource": [
               "arn:aws:s3:::[aws_bucket_name]/access_allow/*"
           ]
       }
   ]
}

AWS CLIでアクセス確認

aws s3 ls s3://[aws_bucket_name]/access_allow/
2020-07-12 22:44:44          0
2020-07-12 22:47:02         14 test.csv
# 見れた!

aws s3 ls s3://[aws_bucket_name]/access_deny/
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
# 見れない!!

特定のディレクトリだけ見れた!成功!
今回はIAMポリシーの設定でやってみよう

GCP(こちら側)がやること

あとは作成してもらったIAMのcredential情報をもらって転送するのみ
公式のおすすめによるとStorage Transfer Serviceだが、gsutilとどっちもやってみる。

gsutilで転送してみる

公式に習ってgsutilをインストール
きっとこの辺打ち込んでログインしとけばいけるはず

curl https://sdk.cloud.google.com | bash
exec -l $SHELL
gcloud init​

~/.botoファイルに作成してもらったIAMのCredential情報設定

$ vim ~/.boto
[Credentials]
aws_access_key_id = [aws_access_key_id]
aws_secret_access_key = [aws_secret_access_key]

gsutilで作成したGCSのバケットにデータコピー

$ gsutil ls gs://[gcs_bucket_name]/
gs://[gcs_bucket_name]/
$
$ gsutil cp s3://[s3_bucket_name]/access_allow/test.csv gs://[gcs_bucket_name]/
Copying s3://[s3_bucket_name]/access_allow/test.csv [Content-Type=text/csv]...
/ [1 files][   14.0 B/   14.0 B]
Operation completed over 1 objects/14.0 B.
$
$ gsutil ls gs://[gcs_bucket_name]/
gs://[gcs_bucket_name]/test.csv
$ # 転送できてる!! 
$
$ gsutil cp s3://[s3_bucket_name]/access_deny/test.csv gs://[gcs_bucket_name]/
AccessDeniedException: 403 AccessDenied
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message>
$ # アクセス制御の無い場合は怒られた!成功!

うまくいった!

Storage Transfer Serviceで転送してみる
AWSのIAMポリシーに「s3:GetBucketLocation」Actionを追加

{
  "Version": "2012-10-17",
  "Statement": [
      {
          "Effect": "Allow",
          "Action": [
              "s3:ListBucket",
              "s3:GetBucketLocation"
          ],
          "Resource": "arn:aws:s3:::[aws_bucket_name]",
          "Condition": {
              "StringLike": {
                  "s3:prefix": "access_allow/*"
              }
          }
      },
      {
          "Effect": "Allow",
          "Action": [
              "s3:GetObject"
          ],
          "Resource": "arn:aws:s3:::[aws_bucket_name]/access_allow/*"
      }
  ]
}

「Data Transfer -> Transfer Service | クラウド」 から転送を作成

スクリーンショット 2020-07-14 23.48.43

作成してもらったIAMのcredential含め必要な情報を入れてく

画像16

作成押してみる!

スクリーンショット 2020-07-15 21.43.08

なんやて🧐
追加したで。しっかりと。
ものすごい詰まったけどおそらくディレクトリレベルでの制御されてると上手くいかない説が有力。
こんな感じでディレクトリ単位の制御を除いたら上手くいった

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "s3:ListBucket",
               "s3:GetBucketLocation"
           ],
           "Resource": "arn:aws:s3:::data-for-gcs"
       },
       {
           "Effect": "Allow",
           "Action": [
               "s3:GetObject"
           ],
           "Resource": "arn:aws:s3:::data-for-gcs/*"
       }
   ]
}

スクリーンショット 2020-07-15 20.45.00

$ gsutil ls s3://data-for-gcs/access_allow/
gs://uchiyama-sandbox-data/access_allow/test.csv

転送されてる!キタコレ!

まとめ

だいぶ長くなったけど、やることはこんな感じ
1. 特定バケットの権限を持つIAM作ってもらう
2. IAMのCredentialもらう
3. gsutilかStorage Transfer ServiceでGCSに連携

Storage Transfer Service使うときはディレクトリ 単位じゃなくて
バケット単位でアクセス制御が吉やで。というとこ

次は相手がこっちにアップロードするケース
その次はVPN構成やってみよう

この記事が気に入ったらサポートをしてみませんか?