Boto3を使ってプライベートサブネットのEC2からクロスアカウントのS3にアップロードしてみた

プライベートサブネットに立ち上げたEC2から異なるAWSアカウントのS3にクロスアカウントでファイルをアップロードしてみたので紹介します。

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、ニシヤマです。はいマスキュラー。

プライベートサブネットにあるEC2からVPC Endpoint経由で異なるAWSアカウントのS3にファイルアップロードする環境を構築してみたので紹介します。

気をつける点としては、クロスアカウント環境で適切に設定しないでS3へファイルアップロードを行うと、アップしたファイルで権限エラーが発生してしまうので今回はそれを考慮しながらプログラムから実施しています。

イメージ

説明が長くなってしまいましたが図にするとこんな感じになります。ゴチャッとしてます。

アクセスの流れ

S3バケットのあるアカウントをアカウントA、ファイルアップロードするEC2のあるアカウントをアカウントBとします。アカウントBのEC2→アカウントAのS3バケットにファイルアップロードする流れです。

ファイルをアップロードするサーバへは踏み台サーバ経由でログインします。

前提

アカウントA

  • S3バケットが作成済みであること

アカウントB

  • VPC、Subnetが作成済みであること
  • boto3がインストール済みのEC2が作成済みであること

やってみる

アカウントA側作業

  • S3バケットへのアクセス権限を持ったIAMロール「Role-A」を作成しS3バケットへのアクセス権限を設定
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
            "arn:aws:s3:::<アカウントAのS3バケット>",
            "arn:aws:s3:::<アカウントAのS3バケット>/*"
            ]
        }
    ]
}
  • 上記IAMロールの信頼されたエンティティにアカウントBのAWSアカウントIDを入力

信頼されたエンティティ

アカウントB側作業

  • VPCにVPC Endpointをアタッチ

VPC Endpointポリシー

  • Public SubnetにNAT Gatewayを作成
  • Private SubnetのルートテーブルでDefault GatewayをPublic SubnetのNAT Gatewayに指定します
  • EC2用のIAMロール「Role-B」を作成しSTSのAssumeRoleでアカウントAで作成したIAMロール「Role-A」のARNを指定します

アカウントBのIAMロール

  • 上記のIAMロールをboto3がインストール済みのEC2インスタンスにアタッチ
  • 踏み台サーバ経由でPrivate SubnetのEC2ログインし、以下のPythonスクリプトを設置。
#!/usr/bin/env python
# coding: utf-8

import boto3

sts = boto3.client('sts')


assumedRole = sts.assume_role(
    RoleArn='arn:aws:iam::<アカウントAのAWSアカウントID>:role/Role-A',
    RoleSessionName='sample_session',
)

credentials = assumedRole['Credentials']

s3 = boto3.resource(
    's3',
    aws_access_key_id = credentials['AccessKeyId'],
    aws_secret_access_key = credentials['SecretAccessKey'],
    aws_session_token = credentials['SessionToken'],
)

bucket = s3.Bucket('<アカウントAのS3バケット>')

bucket.upload_file('test.txt', 'hoge_from_private_sts.txt')

スクリプトではEC2のローカルにあるテキストファイルtest.txtをS3バケットにhoge_from_private_sts.txtとしてアップロードしています。

  • スクリプトを実行
python cross_s3_upload.py

ちゃんとアカウントAのS3バケットにファイルがアップされていました!

S3バケットの中身

確認してみるとちゃんと権限が設定されておりアカウントA、アカウントBのどちらからもファイル操作が可能です。

S3バケットのファイルの権限確認

注意点

この構成の時にNAT Gatewayへのルート情報を編集してEC2からインターネットへの通信を遮断したところPythonスクリプトがSTSの一時トークン発行で止まってしまいました。 また、STSを東京リージョンで利用する場合はインターネットへの接続が必須となります。

※STSがVPC Endpiontに対応しているのは2019/03時点でオレゴンリージョンのみ。

さいごに

今回、VPC Endpoint経由でのS3アクセスなど今まであまり利用していなかったサービスを利用する機会があり少しですが注意点なども理解できました。かなり限定的な環境だったとと思いますがこの記事が誰かのお役に立てば幸いです。

参考

http://blog.serverworks.co.jp/tech/2018/04/17/access-to-cross-bucket/ http://rriifftt.hatenablog.com/entry/2018/11/02/125726