異なる AWS アカウントの S3 バケットに Lambda からエンドポイント経由でアクセスする

技術 1 課の山中です。 今日、屋上で作業をしようとおもって上がったら、小雨が降っていてすぐに断念しました。

というわけで、本日は異なるアカウントの S3 バケットに対して VPC エンドポイント経由でアクセスしてみたいとおもいます。

構成について

今回は異なるアカウントとしてアカウント A とアカウント B を想定しています。 アカウント B には S3 バケットが存在し、アカウント A の Lambda からアカウント B の S3 バケットを参照します。 Lambda は Private サブネットにあり取得したデータを DirectConnect 経由で SFTP 等を利用してオンプレミスのサーバに送信することが可能です。(ここは本ブログでは割愛します。

認証

アカウント A の Lambda にはアカウント B の S3 バケットにアクセスするための権限が必要です。 Lambda から STS を利用して S3 にアクセスするための一時クレデンシャルを取得します。

事前準備

アカウント B での準備

S3 バケットの作成

データを取得するためのバケット(examplebucket)を作成します。 今回はエンドポイント経由でのアクセスだけを許可するように、以下バケットポリシーを付与します。

S3 バケットにアクセスするための IAM Role 作成

IAM ロールの作成画面にて信頼されたエンティティの種類で「別の AWS アカウント」を選びアカウント A のアカウント ID を入力します。 今回は S3 へアクセスしたいので AmazonS3FullAccess のポリシーをアタッチします。 ※ examplebucket のみにアクセスを許可したい場合は、別途ポリシーを作成しアタッチしてください。

アカウント A での準備

STS をコールするための IAM Role 作成

STS をコールするためのポリシーを作成します。 Resource にはアカウント B で作成したロール ARN を指定します。 IAM ロールの作成画面にて信頼されたエンティティの種類で「AWS サービス」を選択後「Lambda」を選びます。 その後作成したポリシーをアタッチしてください。

VPC 及びサブネットの作成

今回は 1 つの VPC と 2 つのサブネットを作成します。 サブネットは Public と Private を作成します。それぞれの役割は以下のとおりです。
Public サブネット Private サブネットの Lambda が AWS エンドポイントにインターネット経由でアクセスするための NAT サーバを配置
Private サブネット Lambda ファンクションをデプロイするサブネット
※ STS の API をコールするために Lambda はインターネットに接続できる必要があります。

エンドポイントの作成

Lambda をデプロイする VPC に S3 エンドポイントを作成してください。
参考:VPC Endpointを使ってS3にアクセスしてみる

NAT サーバの作成

NAT インスタンス作成手順 に従い、 Public サブネットに NAT インスタンスを作成します。 (もちろん NAT Gateway を利用しても大丈夫です。)

ルーティングの設定

以下を参考に Private サブネットのルートテーブルを修正します。
送信先 ターゲット
VPC のローカル local
0.0.0.0/0 NAT インスタンスのインスタンス ID
com.amazonaws.ap-northeast-1.s3 エンドポイント ID

Lambda の設定

新しい Lambda を作成します。 以下の設定値を参考に作成してください。
項目
関数コード ※以下を参考に作成
ランタイム Python 3.6
実行ロール Lambda 用に作成した IAM ロールを選択
ネットワーク Lambda 用に作成した Private サブネットを選択
作成後、テスト実行するとアカウント B のバケットのオブジェクト一覧が取得できるはずです。 取得したオブジェクトを DirectConnect 経由で拠点に送る等処理をすることができます。

注意事項

Lambda からインターネットに接続できる必要がある

今回 Private サブネットの Lambda ファンクションから他アカウントの S3 へプライベートアクセスを行いましたが、 アカウント B のバケットを操作する権限を取得するために AWS Security Token Service(STS) を利用しているので HTTPS リクエストを Lambda からインターネット経由で発行できる必要があります。

まとめ

今度は今回作成したアカウント B のバケットのイベントをトリガとしてアカウント A の Lambda を実行する方法を書きたいと思います!

AWS運用自動化サービス「Cloud Automator」無料トライアルはこちらから

CATEGORY :

COMMENT ON FACEBOOK