こんにちは、技術3課の紅林です。
【そんなときどうする?】シリーズに便乗してみました。さて、今回は、S3をクロスアカウントで利用する方法やハマリポイントをご紹介します。
はじめに
開発環境と本番環境とでAWSアカウントを分けているとき等、クロスアカウントでS3を扱いたくなるケースがあります。その際に採用できそうないくつかの方法と、実際にやってみるとハマりがちなポイントについてご紹介します。
クロスアカウントでの利用方法
クロスアカウントでS3を扱う方法ですが、代表的な方法として以下3つの方法があると思います。今回はAWS CLIや各種SDK等からの利用を念頭に置きます。
- IAMユーザの共有
- バケットポリシーの許可
- STSの利用
それぞれ簡単に概要を記載します。便宜的に、
- S3バケットがあるアカウントを「アカウントA」
- S3バケットを扱うアカウントを「アカウントB」
とします。
1. IAMユーザの共有
概要
アカウントAでS3バケットを扱うことに出来るIAMユーザを作成し、そのクレデンシャルをアカウントBのインスタンスで用いる方法です。下記の通り、クレデンシャルの管理が必要となりますので、可能であれば後述の方法が望ましいと思います。
- メリット
- 方法が分かりやすい
- デメリット
- クレデンシャルの管理が必要
イメージ
設定例
アカウントAで当該S3バケットを操作できるIAMユーザを作成し、クレデンシャルをアカウントBのインスタンスから用います。AWS CLIであれば以下のようにクレデンシャルを用います。これは簡単ですね。
$ aws configure
AWS Access Key ID []:xxxxxxxxxxxxxxx
AWS Secret Access Key []:xxxxxxxxxxxxx
Default region name []:ap-northeast-1
Default output format []:json
2. バケットポリシーの許可
概要
アカウントAのバケットのバケットポリシーにアカウントBのIAMのARNを許可する。
- メリット
- クレデンシャルの管理が不要
- デメリット
- アップロードしたオブジェクトにバケットポリシーが適用されない(※詳細は後述)
イメージ
設定例
アカウントAのバケットポリシーを以下のように設定します。アカウントBのIAMロール等を指定して、そのロールからのアクションを許可します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Example",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[AccountB-Role]"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucket-name/*",
"arn:aws:s3:::bucket-name"
]
}
]
}
3. STSの利用
概要
STSを用いてBアカウントはAアカウントの一時クレデンシャルを用いる。
※STS自体に関しては以下の記事等を参考ください
【そんなときどうする?】別のアカウントにセキュアにアクセスしたい! いまさらきけないSTSとは?
IAMロールによるクロスアカウントアクセス
- メリット
- クレデンシャルの管理が不要
- デメリット
- 一時クレデンシャルを扱う処理が必要
イメージ
設定例
アカウントAのIAMロール
ポリシー
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::[bucket-name]/*",
"arn:aws:s3:::[bucket-name]"
]
}
}
信頼関係
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[AccountB-Number]:root"
},
"Action": "sts:AssumeRole"
}
]
}
アカウントBのIAMロール
ポリシー
{
"Version": "2012-10-17",
"Statement":
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::[AccontA-Role]"
}
}
使用例(AWS CLI)
アカウントBから実行
# aws sts assume-role --role-arn [AccountA-Role] --role-session-name zzzzz(任意)
★アクセスキー、シークレットアクセスキー、セッショントークンを控える
# export AWS_ACCESS_KEY_ID = xxxx
# export AWS_SECRET_ACCESS_KEY= xxxx
# export AWS_SESSION_TOKEN= xxx
★あとはExpire(1H)するまで自由に
# aws ec2 describe-instances
ハマリポイント
バケットポリシーで実現する場合
アカウントBからオブジェクトをアップロードした場合、オブジェクトの所有者はアカウントB(バケット所有者のアカウントAとは別のアカウント)になるためバケットポリシーがオブジェクトに適用されません。
例えば、静的ウェブホスティングを有効にしているバケットに、アカウントBからオブジェクトをアップロードしても、バケットポリシーが適用されないため、アップロードしただけではそのコンテンツは公開できません(公開するためには、アップロード後にオブジェクトの権限を変更する必要があります)。
バケットの所有者は、自分が所有していないオブジェクトへのアクセス許可を付与できません。たとえば、オブジェクトへのアクセス許可を付与するバケットポリシーが適用されるのは、バケットの所有者が所有しているオブジェクトに対してだけです。 アクセスポリシーのオプションを使用するためのガイドライン - Amazon Simple Storage Service
VPCエンドポイントがある場合
もし、アカウントBにVPCエンドポイントがある場合には注意が必要です。VPCエンドポイントは指定のリージョンのすべてのS3に対するエンドポイントとなります。すなわち、アカウントAのS3バケットにアクセスする際にもVPCエンドポイント経由になります。
デフォルトのポリシーでは、任意の AWS アカウントからの認証情報を使用して、VPC 内のユーザーまたはサービスによる、任意の Amazon S3 リソースへのアクセスが許可されます。これには、VPC が関連付けられているアカウントとは別の AWS アカウントの Amazon S3 リソースが含まれます。
Amazon S3 におけるエンドポイント - Amazon Virtual Private Cloud
これがいつ影響するかというと、例えば、S3バケットのアクセス制御をバケットポリシーで行う場合、アカウントBのインスタンスのIPアドレスでの制限が出来ません。アカウントBのインスタンスはVPCエンドポイント経由でアクセスしてくるので、VPCエンドポイントのIDで制限する必要があります。
※詳細や、具体的な設定方法は以下の記事をご確認ください
VPCエンドポイント構成でS3バケットへのアクセスを制限するには? | サーバーワークス エンジニアブログ
おわりに
以上、S3をクロスアカウントで利用する場合の概要とハマリポイントをご紹介してみました。