LoginSignup
6
8

More than 3 years have passed since last update.

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

Posted at

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

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からインターネットにアクセスする

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8