チュートリアル here に従って、パブリックサブネットとプライベートサブネットを持つVPCを作成しました。
次に、パブリックサブネット内にAWSラムダ関数を設定して、外部インターネットに接続できるかどうかをテストしました。
これがpython3で書かれた私のラムダ関数です
import requests
def lambda_handler(event, context):
r = requests.get('http://www.google.com')
print(r)
上記の関数は、VPCのパブリックサブネット内に設定すると、http://www.google.com
のコンテンツを取得できませんでした。
エラーメッセージは次のとおりです。
"errorMessage": "HTTPConnectionPool(Host = 'www.google.com'、port = 80):次のURLで最大再試行回数を超えました:/(NewConnectionError( 'により発生):新しい接続を確立できませんでした:[Errno 110]接続がタイムアウトしました'、)) "、" errorType ":" ConnectionError "、
理由がわかりません。
パブリックサブネットのルートテーブルは次のようになります。
http://www.google.com
へのGET
リクエストは、igw-XXXXXXXXX
ターゲットと一致する必要があります。 internet-gateway(igw)がhttp://www.google.com
にリクエストを配信してWebサイトのコンテンツを取得できないのはなぜですか?
これは 記事 は、インターネットにアクセスするためにプライベートサブネット内にラムダ関数を設定する必要があることを示しています。
Lambda関数がプライベートVPCリソース(Amazon RDS DBインスタンスやAmazon EC2インスタンスなど)にアクセスする必要がある場合は、関数をVPCに関連付ける必要があります。関数がインターネットアクセスも必要とする場合(たとえば、パブリックAWSサービスエンドポイントに到達するため)、関数はNATゲートウェイまたはインスタンスを使用する必要があります。
しかし、パブリックサブネット内にラムダ関数を設定できない理由は説明されていません。
Lambda関数がVPCのパブリックサブネット内で実行されている場合でも、Lambda関数がインターネットにアクセスできないのは、Lambda関数がパブリックIPアドレスを持たず、また持つことができないためです。パブリックIPがないと、トラフィックをインターネットに直接送信できません。 NAT経由でルーティングする必要があります。
VPCパブリックサブネットのトラフィックのデフォルトルートターゲットは インターネットゲートウェイ(IGW) であり、Lambda関数にはプライベートIPしかないため、Lambda関数からインターネットへのすべてのパケットはドロップされますIGW。
Lambda関数が実際にVPC内のプライベートリソースに到達する必要がない場合は、通常、LambdaをVPCにデプロイする必要はありません。ただし、必要な場合は、プライベートサブネットでLambda関数を実行し、そのサブネットからNATインスタンスまたはNATパブリックサブネット、そしてIGWを構成します。