web-dev-qa-db-ja.com

VPC内のLambdaからAWS S3にアクセスする

全体として、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)
28
noobiemcfoob

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ロールを作成します。

15
Geoff

サブネットとルートに関係する別の問題があり、それは他の回答では解決されないため、上記のすべての回答が当てはまるという条件で別の回答を作成しています。ラムダ関数が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つのサブネットが必要であることに注意してください。これも良い考えです。

5
Paul S

問題の原因は、セキュリティグループの送信規則を適切に構成していなかったためです。具体的には、pl-XXXXXXXX(S3サービス。実際の値はAWSコンソールによって提供されました)の宛先を持つカスタムプロトコルアウトバウンドルールを追加する必要がありました。

4
noobiemcfoob

VPCエンドポイントに関連する別のソリューションがあります。

AWSコンソールで、VPCサービスを選択してから、エンドポイントを選択します。新しいエンドポイントを作成し、s3サービスに関連付けます

VPC S3エンドポイント選択

次に、VPCとルートテーブルを選択します。

次に、アクセスレベル(フルまたはカスタム)を選択すると機能します。

0
Luis RM