インターネットアクセス可能な VPC Lambda を作成してみた

AWS ナレッジセンターの内容をやってみました
2022.09.21

はじめに

アノテーション株式会社の hato です。

VPC に接続した Lambda 関数(VPC Lambda)はインターネットアクセスが必要な場合、一般的に NAT ゲートウェイやルートテーブルの構築が必要です。

一連の構築の流れは AWS ナレッジセンターにて公開されていますが、実際に構築したことはなかったのと、お問い合わせ頂いた際に備えて画面キャプチャを取得するため、やってみました。

なお、一連の流れを確認することが目的のため、NAT ゲートウェイと NAT インスタンスなど、AWS ナレッジセンター内に記載のある選択肢の詳細には触れませんのでご注意ください。

完成図

プライベートサブネットに接続した Lambda 関数が、NAT ゲートウェイを経由してインターネットに接続できる環境を目指します。

今回の構築ではサブネット等はシングル構成ですが、高可用性を維持するには冗長化をご検討ください。

やってみた

手順

  1. VPC の作成
  2. サブネットの作成
  3. インターネットゲートウェイの作成
  4. NAT ゲートウェイの作成
  5. ルートテーブルの作成と設定
  6. IAM ロールの作成
  7. Lambda 関数
  8. テスト

VPC の作成

Amazon VPC コンソール のナビゲーションペインから「お使いの VPC」を選択して、「VPC を作成」を選択します。

次の値を指定して「VPC を作成」を選択します。

  • 名前タグ:任意の名前(例:Lambda VPC
  • IPv4 CIDR ブロック:任意の値(10.0.0.0/16

VPC が正常に作成されたことを確認します。

サブネットの作成

NAT ゲートウェイ用のパブリックサブネットと Lambda 関数用のプライベートサブネットを作成します。
なお、パブリックとプライベートの違いは、インターネットへの到達可否などの関連設定に依存し、作成時に指定するものではないのでご注意ください。

サブネットタイプ - Amazon Virtual Private Cloud

パブリックサブネット: サブネットトラフィックは、インターネットゲートウェイまたは出力専用インターネットゲートウェイを介して、パブリックインターネットに到達できます。

プライベートサブネット: サブネットトラフィックは、インターネットゲートウェイまたは出力専用インターネットゲートウェイを介して、パブリックインターネットに到達できません。パブリックインターネットにアクセスするには、NAT デバイスが必要です。

Amazon VPC コンソール のナビゲーションペインから「サブネット」を選択して、「サブネットを作成」を選択します。

さきほど作成した VPC を指定します。

「サブネットの設定」にパブリックサブネット用の値を指定して、「新しいサブネットを追加」を選択します。

  • サブネット名:任意の名前(例:パブリックサブネット
  • IPv4 CIDR ブロック:任意の値(10.0.1.0/24

同様にプライベートサブネット用の値を指定して、「サブネットを作成」を選択します。

  • サブネット名:任意の名前(例:プライベートサブネット
  • IPv4 CIDR ブロック:任意の値(10.0.2.0/24

二つのサブネットが正常に作成されたことを確認します。

インターネットゲートウェイの作成

Amazon VPC コンソール のナビゲーションペインから「インターネットゲートウェイ」を選択して、「インターネットゲートウェイを作成」を選択します。

名前タグに任意の名前(例:Lambda-InternetGateway)を指定して、「インターネットゲートウェイの作成」を選択します。

インターネットゲートウェイが正常に作成されたことを確認して、「VPC へアタッチ」を選択します。
※閉じた場合は、「アクション」 -> 「VPC にアタッチ」を選択します。

作成した VPC を指定して「インターネットゲートウェイのアタッチ」を選択します。

インターネットゲートウェイが正常にアタッチされたことを確認します。

NAT ゲートウェイの作成

インターネットにアクセスするには、パブリック IP アドレスが必要です。
EC2 とは違い、 Lambda にはパブリック IP アドレスを割り当てることができないため、NAT ゲートウェイを作成します。

VPC 内のリソースにアクセスするように Lambda 関数を設定する - AWS Lambda

関数にインターネットアクセスが必要な場合は、ネットワークアドレス変換 (NAT) を使用します。関数をパブリックサブネットに接続しても、インターネットアクセスやパブリック IP アドレスは提供されません。

Amazon VPC コンソール のナビゲーションペインから「NAT ゲートウェイ」を選択して、「NAT ゲートウェイを作成」を選択します。

次の値を指定して、「NAT ゲートウェイを作成」を選択します。

  • 名前:任意の名前(例:Lambda-NATGateway
  • サブネット:作成したパブリックサブネットを指定
  • 接続タイプ:パブリック
  • Elastic IP 割り当て ID:既存の EIP もしくは「Elastic IP を割り当て」をクリック

NAT ゲートウェイが正常に作成されたことを確認します。

ルートテーブルの作成と設定

パブリックサブネット用のルートテーブルとプライベートサブネット用のルートテーブルを作成します。
まず、パブリックサブネット用ルートテーブルの作成と設定をします。

Amazon VPC コンソール のナビゲーションペインから「ルートテーブル」を選択して、「ルートテーブルを作成」を選択します。

次の値を指定して、「ルートテーブルを作成」を選択します。

  • 名前:任意の名前(例:パブリックルートテーブル
  • VPC:作成した VPC を指定

ルートテーブルが正常に作成されたことを確認して「ルートを編集」を選択します。

「ルートを追加」を選択します。

「ルートを編集」に次の値を指定して「変更を保存」を選択します。

  • 送信先:0.0.0.0/0
  • ターゲット:作成したインターネットゲートウェイを指定

ルートが正常に更新されたことを確認して「サブネットの関連付け」タブを選択します。

「サブネットの関連付けを編集」を選択します。

作成したパブリックサブネットを選択して「関連付けを保存」を選択します。

サブネットの関連付けが正常に更新されたことを確認します。
以上の設定により、設定したサブネットはパブリックサブネットとなり、VPC 外への通信がインターネットゲートウェイを通して可能です。

同様にプライベートサブネット用ルートテーブルの作成と設定をします。
Amazon VPC コンソール のナビゲーションペインから「ルートテーブル」を選択して、「ルートテーブルを作成」を選択します。

次の値を指定して、「ルートテーブルを作成」を選択します。

  • 名前:任意の名前(例:プライベートルートテーブル
  • VPC:作成した VPC を指定

ルートテーブルが正常に作成されたことを確認して「ルートを編集」を選択します。

「ルートを追加」を選択します。

「ルートを編集」に次の値を指定して「変更を保存」を選択します。

  • 送信先:0.0.0.0/0
  • ターゲット:作成した NAT ゲートウェイを指定

ルートが正常に更新されたことを確認して「サブネットの関連付け」タブを選択します。

「サブネットの関連付けを編集」を選択します。

作成したプライベートサブネットを選択して「関連付けを保存」を選択します。

サブネットの関連付けが正常に更新されたことを確認します。
以上の設定により、設定したサブネットはプライベートサブネットとなり、VPC 外への通信は NAT ゲートウェイ経由で可能です

IAM ロールの作成

Lambda に設定する IAM ロールを作成します。 VPC Lambda は通常の Lambda 関数の権限に加えて、追加の権限が必要となりますが、AWS 管理ポリシーAWSLambdaVPCAccessExecutionRoleが提供されているため、こちらを使用します。

実行ロールとユーザーアクセス許可 - AWS Lambda

IAM コンソール を開き、ロールから「ロールを作成」をクリックします。

信頼されたエンティティタイプに「AWS のサービス」、ユースケースに「Lambda」を選択して、「次へ」をクリックします。

許可ポリシーからAWSLambdaVPCAccessExecutionRoleを選択して、「次へ」をクリックします。

ロール名に任意の名前(例:lambda_vpc_basic_execution)を指定して、「ロールを作成」をクリックします。

IAM ロールが正常に作成されたことを確認します。

Lambda 関数

動作確認も兼ねてパブリック IP アドレスが確認できるhttps://checkip.amazonaws.com/にアクセスする簡単な Lambda 関数を作成します。
必要に応じて作成後に本来のコードに変更してください。

Lambda コンソールを開き、関数から「関数の作成」をクリックします。

次の値を指定します。赤枠の部分は「▼デフォルトの実行ロールの変更」をクリックすると表示されます。

  • 関数名:任意の名前(例:VPC-Lambda
  • ランタイム:Node.js 16.x
  • デフォルトの実行ロールの変更:既存のロールを使用する
    • 作成した IAM ロールを指定

同様に「▼詳細設定」から次の値を指定して、「関数の作成」を選択します。

  • VPC を有効化:有効
    • VPC:作成した VPC を指定
    • サブネット:作成したプライベートサブネットを指定
    • セキュリティグループ:default VPC security group

Lambda 関数の作成中は設定変更ができないためしばらく待ちます。

Lambda 関数が正常に作成されたことを確認し、エディタ(赤枠で囲った部分)に、次のサンプルコードを入力します。

※パブリック IP アドレスが確認できるhttps://checkip.amazonaws.com/にアクセスし、結果を表示するサンプルコードです。

参考:AWS Lambdaから外部ライブラリに依存せずにHTTPリクエストする

const https = require('https')

exports.handler = async (event) => {
    const url = 'https://checkip.amazonaws.com/'
    const res = await req(url)
        .catch(err => err)
    return {
        url,
        res
    }
}

async function req (url) {
    return new Promise((resolve, reject) => {
        https.get(url, (resp) => {
            let data = ''
            resp.on('data', (chunk) => {
                data += chunk
            })
            resp.on('end', () => {
                resolve(data)
            })
        })
        .on('error', (err) => {
          reject(err)
        })
    })
}

「Deploy」をクリックします。

コードが正常に更新されたことを確認して「テスト」タブを選択します。

イベント名に任意の名前(例:Internet-Access-Test)を指定して、「テスト」を選択します。

テストが正常に実行されたことを確認して「詳細」をクリックします。

resキーの値(例:35.76.184.65)を確認し、

Amazon VPC コンソール のナビゲーションペインから「NAT ゲートウェイ」を選択して、NAT ゲートウェイのElastic IP アドレスと比較します。
値が同じ場合、Lambda 関数は NAT ゲートウェイを経由して、インターネットにアクセスできています。

最後に

この記事が誰かのお役にたてば幸いです。

参考資料

アノテーション株式会社について

アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。