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バケット作成してみる
適当な名前でバケット作成
テストなのでオプションは特に指定せず
Block public accessは指定しておく
こいつを設定しておくとS3がpublic公開される事故を防げる
Create bucket
フォルダ毎にアクセス制御できるか検証したいので
アクセスできるフォルダ「access_allow」とアクセスできないフォルダ「access_deny」を作成して、適当なcsvファイル配置しとく
連携用のIAMユーザーを作成
IAM->Users->Add userでユーザー作成
とりあえず適当なuser nameとpasswordを入れる
パーミッションは後でつけるので一旦無視
tagも特につけずnext
create user
credentialは後で使うのでDownload .csvしとく
IAMユーザーでバケットにアクセスできないことを確認
作成したユーザーでログインしてS3みると作成したバケット見れない
IAMポリシーの設定
IAMユーザーに作成したバケットの特定フォルダにアクセスできる
インラインポリシー作成
以下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にはアクセスできるが、ファイルが見えない🤔
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を指定
{
"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 | クラウド」 から転送を作成
作成してもらったIAMのcredential含め必要な情報を入れてく
作成押してみる!
なんやて🧐
追加したで。しっかりと。
ものすごい詰まったけどおそらくディレクトリレベルでの制御されてると上手くいかない説が有力。
こんな感じでディレクトリ単位の制御を除いたら上手くいった
{
"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/*"
}
]
}
$ 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構成やってみよう
この記事が気に入ったらサポートをしてみませんか?