Loading
BLOG 開発者ブログ

2021年9月22日

AWSでVPC内のリソースに固定Private IPアドレスのLambdaでアクセスさせる方法

AWSでVPC内のリソースに固定Private IPのLambdaでアクセスさせる方法

かなり限定的な状況ではありますが、AWSでVPC内のリソース(EC2など)にLambdaからアクセスする際、
そのPrivate IPアドレスを固定する必要があったため、備忘録も兼ねて記事にしておきます。
※ 限定的な状況 : EC2のアプリケーション側で接続元IPアドレスを個別に許可する必要があった。

目次



はじめに

こんにちは。
クラウドソリューショングループのwatanabe.tです。

LambdaのPublic IPアドレスを固定する方法は調べると出てきますが、Private IPアドレスを固定となると意外と出てきません。
ニッチな話ではありますが、知っておくと応用が効くかもしれません。

先に記載しますが、今回の構成は以下のようになります。

AWSネットワーク構成図


前提条件

本手順を進めるにあたり、以下は実施済みの前提となります。
必要に応じて公式ページ等を参考に実施してください。



Private NAT Gateway作成

さて、まずはPrivate NAT Gatewayから作成していきましょう。
とはいえ、この部分はPublic NAT Gatewayを作成する場合と大きく変わりません。

NAT Gateways から右上の「Create NAT Gateway」を選択し、 NAT Gateway 作成画面に遷移します。

次に「NAT Gateway用のサブネット」「Connectivity type : Private」を選択し、右下の「Create NAT Gateway」を選択すると、NAT Gatewayの作成が開始されます。

このとき、「Connectivity type : Private」を選択していることによって、 VPC内でのみ有効なPrivate NAT Gatewayが作成されることがポイント です。


Lambda作成

次に、作成したNAT Gatewayを通して通信するLambdaを作成します。

AWSのLambdaにはいくつか用意されたサンプル(Blueprint)があり、その中に単純なhttpリクエストを送信するものがあったため、今回はそれを用います。
LambdaのFunctions から右上の「Create functions」を選択し、Functions作成画面を開きます。

「Use a blueprint」を選択後、「nodejs 12.x」「https-request」のサンプルを選択します。
これはNode.js 12.xで動作する、シンプルなHTTPSリクエストを送信し、そのレスポンスをロギングするだけの関数です。



「関数名」「実行に必要なIAMロール」を入力し、「Create function」を選択します。
※ 今回はLambdaをVPCに所属させる関係上、「ec2:DescribeNetworkInterfaces」「ec2:CreateNetworkInterface」「ec2:DeleteNetworkInterface」の権限が必要です。



次に、Lambdaの「Configuration」タブから「VPC」「Edit」と選択し、LambdaをVPCに所属させるように設定します。

事前に作成しておいたLambda用のVPC/サブネット(NAT Gatewayとは別のサブネット)を選択します。
セキュリティグループに関しては、Lambdaの通信先となるリソース(今回はEC2にApache HTTPを起動)に通信が許可されるようにしておきます。




ルーティング変更

さて、ここまで来たらもう一息です。
Lambdaからの通信がNAT Gatewayを通過するように、Lambda用サブネットのルートテーブルを変更します。

VPCのRoute Tables からLambda用サブネットに設定されているルートテーブルを確認します。



デフォルトの状態だと「10.0.0.0/16」向けの通信が「local」にルーティングされるようになっていますが、これを作成したNAT Gatewayに向けることで、VPC内への通信をNAT Gateway経由にすることができます。



「Edit routes」を選択しルーティング編集画面に遷移します。

「10.0.0.0/16」のTargetが「local」になっているため、これを作成済みのNAT Gateway( nat- で始まるリソースID)に変更して保存します。



これでLambdaはVPC内への通信時にNAT Gatewayを通るようになりました。


動作確認

では最後にLambdaがNAT Gatewayを通して通信できているかの確認をしてみましょう。

あらかじめ通信対象のEC2はVPC内に立てておき、NAT GatewayのIPアドレスからの通信を許可するように設定しておきました。
また、Apache HTTPサーバをインストールし、どこからアクセスがあったかも確認できるようにしておきました。

ここでLambdaのindex.jsを編集し、HTTP通信が行えるようにしておきます。(Apache HTTPサーバ側でSSL証明書を用意するのがめんどくさかったので。。。)

「index.js」の「https」となっている箇所を全て「http」と書き換えて保存・デプロイしておけばOKです。

あとはLambdaのテスト実行で以下のデータを渡して実行すれば、Lambda -> NAT Gateway -> EC2(Apache HTTPサーバ)という通信が行われます。

{
  "options": {
    "protocol": "http:",
    "host": "EC2のPrivate IPアドレス",
    "port": 80,
    "path": "/",
    "method": "GET"
  },
  "data": ""
}


通信の確認のためApache HTTPサーバの /var/log/httpd/access_log を見てみると、以下のようにアクセスログが表示されていました。

[root@ip-10-0-0-103 ~]# tail -f /var/log/httpd/access_log
10.0.10.17 - - [12/Sep/2021:07:16:59 +0000] "GET / HTTP/1.1" 200 380 "-" "-"


このアクセスログに表示されている 「10.0.10.17」が作成したPrivate NAT GatewayのPrivate IPアドレスと一致しているため、無事にLambdaからの通信がNAT Gatewayを経由してEC2に到達していることが確認できました。




おわりに

今回は、VPC内のリソースに固定Private IPアドレスのLambdaでアクセスさせる方法を紹介しました。

かなり限定的な状況であるとはいえ、Private NAT Gatewayの挙動を知ることができたのは面白かったです。
特に、AWSのネットワーク周りは目に見えづらく、理解しづらい部分も多い分野です。
少しずつユースケースごとのベストパターンを探っていければと思います。

この記事が誰かの役に立つことを祈って。

ちなみに、VPCエンドポイントを利用している場合はLambda用サブネットのルーティング設定がさらに複雑になるのですが、長くなってしまうのでまた別の機会にでも。


/a>

watanabe.tのブログ

クラウドソリューショングループ所属

昔はモバイルアプリ開発を、今はGCP, AWS, Firebaseなどのクラウド周りの提案/開発を行っているエンジニアです。

AWS認定ソリューションアーキテクト取得しました!