全体として、VPC内でAWS Lambdaを使用することでかなり混乱しています。問題は、S3バケットにアクセスしようとしているときにLambdaがタイムアウトすることです。ソリューションはVPCエンドポイントのようです。
Lambda関数をVPCに追加して、RDSホストデータベースにアクセスできるようにしました(以下のコードには示されていませんが、機能しています)。ただし、今ではS3にアクセスできず、アクセスしようとしてもタイムアウトになります。
VPC S3エンドポイントを作成しようとしましたが、何も変わっていません。
VPC設定
最初にEC2インスタンスを作成するたびに、デフォルトで作成されたシンプルなVPCを使用しています。 4つのサブネットがあり、すべてデフォルトで作成されます。
VPCルートテーブル
_Destination - Target - Status - Propagated_
172.31.0.0/16 - local - Active - No
pl-63a5400a (com.amazonaws.us-east-1.s3) - vpce-b44c8bdd - Active - No
0.0.0.0/0 - igw-325e6a56 - Active - No
簡易S3ダウンロードLambda:
import boto3
import pymysql
from StringIO import StringIO
def lambda_handler(event, context):
s3Obj = StringIO()
return boto3.resource('s3').Bucket('marineharvester').download_fileobj('Holding - Midsummer/sample', s3Obj)
Boto3では、S3のURLはデフォルトでvirtualであり、地域固有のURLに解決するにはインターネットアクセスが必要です。これにより、タイムアウトまでLambda関数がハングします。
これを解決するには、クライアントの作成時にConfig
オブジェクトを使用する必要があり、boto3にpathベースのS3 URLを作成するよう指示します。
import boto3 import botocore.config
client = boto3.client('s3', 'ap-southeast-2, config=botocore.config.Config(s3={'addressing_style':'path'}))
呼び出しのリージョンは、ラムダとVPCエンドポイントをデプロイするリージョンでなければならないことに注意してください。
その後、Lambdaのセキュリティグループ内のVPCエンドポイントにpl-xxxxxx
プレフィックスリストを使用し、引き続きS3にアクセスできます。
これが動作する CloudFormationスクリプト です。 S3バケット、プライベートサブネットとVPCエンドポイントのみを含むVPCに関連付けられたラムダ(バケットにレコードを置く)、および必要なIAMロールを作成します。
サブネットとルートに関係する別の問題があり、それは他の回答では解決されないため、上記のすべての回答が当てはまるという条件で別の回答を作成しています。ラムダ関数がS3にアクセスするには、それらをすべて正しく取得する必要があります。
昨年秋に行った新しいAWSアカウントを作成するとき、デフォルトのVPCに自動的に関連付けられたルートテーブルはありません(コンソールのルートテーブル->サブネットの関連付けを参照)。
したがって、 instructions に従ってエンドポイントを作成し、そのエンドポイントのルートを作成した場合、ルートを追加するサブネットがないため、ルートは追加されません。そして、AWSではいつものように、エラーメッセージは表示されません...
ラムダ関数のサブネットを作成し、そのサブネットをルートテーブルとラムダ関数に関連付けてから、エンドポイントの指示を再実行すると、次のような3つのエントリを持つルートテーブルが見つかります。
Destination Target
10.0.0.0/16 Local
0.0.0.0/0 igw-1a2b3c4d
pl-1a2b3c4d vpce-11bb22cc
エントリが2つしかない(「pl-xxxxx」エントリがない)場合、まだ成功していません。
最後に、ネットワーク内の他のエンティティのように、ラムダ関数が生きるためにサブネットを必要とすることは驚くべきことではないと思います。また、ラムダはEC2インスタンスと同じサブネット上に存在しないことをお勧めします。ラムダは異なるルートまたはセキュリティ権限を必要とする可能性があるためです。 lambdaのGUIでは、2つの異なるAZに2つのサブネットが必要であることに注意してください。これも良い考えです。
問題の原因は、セキュリティグループの送信規則を適切に構成していなかったためです。具体的には、pl-XXXXXXXX(S3サービス。実際の値はAWSコンソールによって提供されました)の宛先を持つカスタムプロトコルアウトバウンドルールを追加する必要がありました。
VPCエンドポイントに関連する別のソリューションがあります。
AWSコンソールで、VPCサービスを選択してから、エンドポイントを選択します。新しいエンドポイントを作成し、s3サービスに関連付けます
次に、VPCとルートテーブルを選択します。
次に、アクセスレベル(フルまたはカスタム)を選択すると機能します。