Help us understand the problem. What is going on with this article?

【AWS】VPC内のLambdaから別のLambdaを呼び出す

ちょっと前にやったことなので記憶があいまいですが、
今後もやる可能性のある事なので備忘録として残しておこうと思います。

VPC内で実行するLambda

AWSのEC2やRDSなどのVPC内のリソースにLambdaでアクセスする場合、
LambdaにVPC設定をすることで可能になります↓

【AWS】LambdaをVPC内で実行し、EC2のMySQLにアクセスする
https://www.geekfeed.co.jp/geekblog/lambda_vpc

しかし一方で、VPCにpublicなサブネットを設定していない場合、VPC内Lambdaからは外部のネットワークに接続することができなくなります。
つまり以下のアクセスが不可能となります。

  1. VPC内Lambda→VPC内Lambda
  2. VPC内Lambda→VPC外Lambda
  3. VPC内Lambda→VPC外リソース(PrivateLinkがサポートされているもの以外)

例えば、VPC内リソースからデータ取得後、そのデータを別リソースに保存したりする場合などに
データ取得Lambda→データ保存Lambdaというように連携することがあると思いますが、
LambdaからLambdaを呼び出す場合もネットワーク経由で行うため、これができなくなってしまいます。
※Lambdaを呼び出そうとしたときにTimeoutになります。

今回はこれを解決し、VPC内Lambdaから外部リソースへのアクセスができるように設定したいと思います。

方針

PrivateLinkによる外部サービスアクセス

まず、冒頭に書いた「3. VPC内Lambda→VPC外リソース」ですが、
AWSのサービスでPrivateLinkがサポートされている場合、Publicサブネットの設定などの面倒な設定はせずに
VPC内Lambdaから外部サービスへのアクセスが可能です。

例えば、EC2, CloudWatch, SNSなどの多くのサービスがPrivateLinkにサポートされています。
PrivateLinkがサポートしているサービスはこちらを参照

が、Lambdaは無いです。

そこで、Lambdaやその他の外部リソースにアクセスできるようにするため、
VPCそのものに設定を加えていきたいと思います。

構成

VPCにNAT Gatewayを持つPublicサブネットを作成し、PrivateサブネットからそのNAT Gateway経由でアクセスします。
tempsnip.png

Publicサブネット+NAT Gatewayの設定

VPCを作成した時点でPrivateサブネットは作成されているはずですので、
Publicサブネットの作成からしていきたいと思います。

①Publicサブネットの作成

普通にサブネットを作成します。わかりやすいようにNameタグを設定しておきます。
AZの指定ですが、すでにVPC Lambdaで設定しているPrivateサブネットが存在するAZを指定しておきます。
キャプチャ.PNG

②NAT Gatewayの作成

NAT Gatewayを作成します。
①で作成したPublicサブネットを指定します。
2.png

③ルートテーブルの設定

さてここまでprivate, publicと言ってきましたが、
AWSの参考記事にも書かれている通り、

注: サブネットがプライベートであるかパブリックであるかは、そのルートテーブルにより決まります。パブリックサブネットにはインターネットゲートウェイを指すルートがあり、プライベートサブネットにはありません。

です。
つまり以下の手順によって
NAT Gatewayを設定したサブネットがPrivateサブネットになり、
Internet Gatewayを設定したサブネットがPublicサブネットになります。

Privateサブネットを関連付けたルートテーブルの作成

デフォルトで作成されているルートテーブルがあると思いますが、新規に作成しています。
NAT Gatewayを設定します。
public.png

Publicサブネットを関連付けたルートテーブルの作成

VPC作成時のInternet Gatewayを設定します。
private.png

以上で設定終了です。

アクセスの流れ的には
VPC内Lambda (private subnet) → NAT Gateway (public subnet) → Internet Gateway → 外部
って感じですかね?

AWS歴3か月の雑魚なので認識間違ってたらすみません。

lambdaの呼び出し方

通常のlambda呼び出しと変わりません。
ランタイムはNode.jsです。

lambda.js
const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();

exports.handler = function(event, context, callback) {

    // ペイロード。呼び出すLambda関数に受け渡す引数的な。
    let payload = {
        "hoge":"huga"
    };

    // ペイロードをStringにする。
    payload = JSON.stringify(payload);

    // invoke引数設定
    let params = {
        FunctionName:"実行するlambda名",
        InvocationType:"RequestResponse",
        Payload:payload
    };

    // Lambda関数呼び出し
    lambda.invoke(params, function(err, data){
        if(err){
            context.fail(err);
        }
        context.succeed(data);
    });

}

備考

参考のAWSリンクにもありますが、
private、publicのサブネットを持ったVPC作成を一発でやる方法があります。
用途がはっきりしているVPCを作成する場合はこれも使えるかも。

参考

How do I give internet access to my Lambda function in a VPC?
VPC内のLambdaからインターネットにアクセスする

duplicate1984
エンジニア見習いです。投稿内容は個人の見解…なんとかかんとか。 C#.NET, Laravel, React, PHP, Python, JS, Oracle, Mysql, Win, Linux, AWS
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした