VPC Private Network 内の Lambda Function から boto3 で S3 を操作する


ちょっと前に VPC Private Network 内に立てた Python Lambda Function から boto3 で S3 を操作しようとしたとき、 S3 へアクセスできなくて困った。今更ながらそのときの解決策を(思い出しながら)メモ。

VPC Endpoint の作成

VPC Lambdaからs3へアクセスする 』によると、 Private Network から S3 へアクセスするには NAT インスタンス(ゲートウェイ)を立てるか VPC Endpoint for S3 を使う必要があるとのこと。自分は後者にすることにした。

boto3 から S3 を操作する

上記設定をしたものの、依然として S3 へアクセスしようとするとエラーとなってしまう。

raise caught_exception ConnectionError: ('Connection aborted.', error(111, 'Connection refused'))

いろいろ調べているうちに こちらのポスト で以下のように configsignature_version を指定しているのをみつけた。

s3 = boto3.client('s3', config=Config(signature_version='s3v4'))

s3v4 とは、S3認証の Version 4 ということらしい。
config を指定して実行したところ、 S3 へアクセスすることができた。

ちゃんと調べていないので推測になってしまうけど、デフォルトの v2 で S3 へアクセスしにいったけど、東京リージョンは v4 しか対応していないのでエラーになった、というところだろうか。

まとめ

VPC Private Network 内に立てた Lambda Function から Python boto3 で S3 へアクセスする場合は以下のように signature_version を明示的に指定する。

import boto3
import botocore.client

config = botocore.client.Config(signature_version='s3v4')
s3 = boto3.resource('s3', region_name='ap-northeast-1', config=config)
bucket = s3.Bucket(s3_bucket_name)
obj = bucket.Object(s3_key)