VPC設定したlambda関数からS3へアクセスする方法

VPC設定したlambda関数からS3へアクセスする方法

こんにちは、自動化・AIツール開発担当の中田(@valmore_nakata)です。

AWS LambdaでVPCの設定をすると、S3へのアクセスでタイムアウトしたという経験はありませんか?
これはlambdaがVPC外のリソースにアクセスできなくなって発生するタイムアウトエラーです。 lambdaをVPC内で使いたいけど、 VPC外のリソースにもアクセスしたいというケースで生じるエラーですね。

この場合の解決策は「NATを使う」か「 VPC Endpoint を設定する」かです。
S3へのアクセスのみで事足りる場合は「 VPC Endpoint 」を利用したほうがスマートでしょう。

そこで、本記事ではVPC設定していてもlambdaでS3を利用できるようにする、「VPC Endpoint」の設定方法をご紹介します。

lambda関数作成直後からの手順をご紹介するので、順に設定してみてください。

lambda関数実行ロールを設定する

lambda関数にVPCを設定すると、lambdaはENI(Elastic Network Interface)を作成するようになるので、実行ロールにアクセス許可を与える必要があります。

lambda関数の基本設定から実行ロールに「AWSLambdaVPCAccessExecutionRole」ポリシーをアタッチしましょう。「IAM コンソールで {ロール名}ロールを表示します。」のリンクをクリックします。

IAMのロール設定の画面に遷移するので、「ポリシーをアタッチします」ボタンで進んでください。
検索ボックスに「AWSLambdaVPCAccessExecutionRole」を検索すると該当のポリシーが出てくるので、チェックを入れます。

S3へのアクセスも必要になるので、「AmazonS3FullAccess」にもチェックを入れて押しましょう。
必要なポリシーにチェックを入れたら「ポリシーのアタッチ」ボタンをクリックして保存すれば完了です。

lambdaにVPCを設定する

続いてlambda関数のVPC設定を行います。
エディター画面下部にVPC設定の項目があるのでそこから設定できます。「編集」をクリックしてください。

「カスタムVPC」を選択すると、VPC, サブネット, セキュリティグループを選択できます。


記事ではデフォルトのものを使用しました。
設定が完了したら保存を押してください。

S3でバケットを作成

lambda関数からアクセスするS3バケットを作成しましょう。
ポイントはlambda関数で設定したVPCと同じリージョンを選択することです。
記事では「米国西部(北カリフォルニア)」を選択していますが、ご自身のリージョンを選択してください。

S3への接続確認のために何かファイルを入れておくとよいでしょう。

「VPC Endpoint」の設定

lambdaのVPC設定とアクセス先のS3バケットを作成しましたが、このままではS3へアクセスができずタイムアウトエラーが発生してしまいます。
S3へアクセスするために「VPC Endpoint」の設定を行いましょう。

AWSマネジメントコンソールでVPCサービスを開いてください。
「エンドポイント」を選択し、「エンドポイントの作成」をクリックします。

サービスカテゴリを「AWSサービス」、サービス名で該当リージョンのS3サービス名を選択してください。
ルートテーブルの設定のルートテーブルにチェックを入れて、「エンドポイントの作成」をクリックします。

これで、lambda関数からS3へのアクセスが可能になったはずです。

boto3でS3へアクセス

必要な設定はすべて完了しました。あとはlambdaで下記のコードを実行してS3へアクセスできるか確認してみましょう。

import json
import boto3

def lambda_handler(event, context):
    s3 = boto3.resource('s3', region_name='us-west-1')
    bucket = s3.Bucket("{S3のバケット名}")
    objs = bucket.objects.filter()
    print([obj.key for obj in objs])

ポイントはboto3.resourceでS3バケットのリージョンを指定することです。
リージョンとバケット名は作成されたもので置き換えてください。
実行してバケット内のファイルがログに表示されれば成功です。

まとめ

VPC内のlambda関数からS3へアクセスする方法を解説しました。

ポイントはlambda実行ロールへポリシーをアタッチした上で「VPC Endpoint」の設定をすることです。リージョンを選択する場面では、全てlambdaに設定しているVPCと同一のリージョンを指定する必要がある点に気を付けてください。