はじめに
業務で対応した内容を、今後でも参考にする可能性があり、メモとして残します。(この記事の内容を踏襲される場合は、自己責任でお願いします。)
要件は以下。
・あるアカウント(Aとする)でAWS上で検証環境を構築した
・別のアカウント(Bとする)にAの検証データ(そこそこのサイズ)を共有したい
検証環境の構成は以下。
・アカウントA:Private Subnet内のEC2インスタンスだが、NAT-Gateway経由でインターネット接続可能
・アカウントB:インターネット接続完全不可のPrivate Subnet内のEC2インスタンス
作業フロー
概要
概要は以下。
- アカウントBでバケット(bucket B)を作成し、ポリシーを編集してバケットをアカウントBに共有する
- アカウントAでEC2からバケット(bucket B)にデータを登録する
- アカウントBでS3のEndpointを作成する
- アカウントBでバケット(bucket B)からデータをEC2に取得する
詳細
バケットポリシーの編集(by アカウントB)
・バケットのPublic Accessの設定を行う(Public Accessを許可する必要がある)
・下記のバケットポリシーを適用する(アカウントAに権限を付与する)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Example permissions for test",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXXXXXXXX:root"
},
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::s3-dev-tools"
},
{
"Sid": "statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXXXXXXXX:root"
},
"Action": [
"s3:PutObject",
"s3:DeleteObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::s3-dev-tools/*"
}
]
}
バケットへのデータ登録(by アカウントA)
EC2からデータを登録する(put-object)
・単純なファイル登録はput-objectでできる
$ aws s3api put-object --bucket s3-dev-tools --key tools.tar.gz --body date --profile hanako-a
{
"ETag": "\"cd04401d4c09a17cc36005d8973619c4\""
}
$ aws s3 ls --region ap-northeast-1 --recursive s3://s3-dev-tools --profile hanako-a
2019-07-25 06:40:06 29 tools.tar.gz
$
・オブジェクトの所有者はアカウントAだけど、バケットオーナーのアカウントBで取得できるようにするためには「--acl bucket-owner-full-control」が必要
$ aws s3api put-object-acl --bucket s3-dev-tools --key tools.tar.gz --acl bucket-owner-full-control --profile hanako-a
put-objectではなくsyncを使う場合も同じ。-aclオプションで[bucket-owner-full-control]を指定する必要がある。
(参考)別の AWS アカウントで自分の Amazon S3 バケットにアップロードされたオブジェクトにアクセスできないのはなぜですか?
https://aws.amazon.com/jp/premiumsupport/knowledge-center/s3-bucket-owner-access/
(参考)AWS CLI Command Reference
https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html#options
この時点で、アカウントBは、AWSマネジメントコンソール上にて、該当するバケット内のファイルを参照およびダウンロードが可能なことを確認するべし。
S3のEndpointを作成する(by アカウントB)
アカウントBでS3からデータを取得したいEC2は、完全に閉じたPrivate Subnetにいるため、Endpointを作成しないと(自分で作ったS3だとしても)S3に接続できません。
…後で手順追記するかも。。
(参考)VPCエンドポイントを使ってプライベートサブネットからS3へアクセスする。
https://qiita.com/kooohei/items/794a7d6e041f43f98f5b
アカウントBでバケット(bucket B)からデータをEC2に取得する
バケット参照できるか?確認する。
$ aws s3 ls s3://s3-dev-tool --profile hanako-b
そしてダウンロード。
$ mkdir -p ~/tools-data
$ cd tools-data
$ aws s3 sync s3://s3-dev-tools ~/tools-data/ --profile hanako-b
download: s3://s3-dev-tools/md5sum.txt to ./md5sum.txt
download: s3://s3-dev-tools/tools.tar.gz to ./tools.tar.gz
$
躓いたところ
初心者ならでは、っぽいところで躓きました。
-
bucket ownerの権限変更が必要
バケットオーナーであるアカウントBでも、「アカウントAがアップロードしたオブジェクトを参照するには明示的に権限付与が必要」というところがわからず、最初、バタバタしました。 -
S3 Endpointが必要
バケットオーナーが無事にマネジメントコンソールでオブジェクトを参照/ダウンロード可能になっても、EC2からは見えない状況でした。基本的にはEC2からS3へのアクセスはPublicの経路で接続するということで、完全にprivateなsubnetから接続するには、S3のEndpointの作成が必要でした。