はじめに
AWS Lambdaを使用していると、「連携先のAPIがIP制限(ホワイトリスト)をかけているため、Lambdaからのアクセスを固定IPにしたい」という要件に直面することがあります。
LambdaはデフォルトではIPアドレスが動的に変わるため、VPCとNAT Gatewayを組み合わせる構成をとるのが一般的です。
今回は、この構成をCloudFormationを使って構築し、Go言語のLambda関数で実際に固定IP化を確認する手順を解説します。
ソースコード
以下のソースコードを元に解説していきます。
https://github.com/tkhs1121/fix-ip-lambda-cloudformation-template
アーキテクチャ概要
Lambda単体では固定IPを持てないため、以下のリソースを組み合わせます。

- VPC: カスタムVPCを作成します。
- Public Subnet: インターネットへの出口となる NAT Gateway を配置し、Elastic IP (固定IP) を割り当てます。
- Private Subnet: Lambda関数 を配置します。
- Routing: Lambdaからのインターネット向け通信を NAT Gateway へルーティングします。
これにより、Lambdaがインターネットへ出る際は必ずNAT Gatewayを経由するため、通信相手にはNAT GatewayのElastic IPが送信元として見えます。
実装例の環境
本記事のコード例では以下の環境を使用しますが、VPC構成の考え方は他の言語やランタイムでも共通です。
- IaC: AWS CloudFormation (AWS SAM)
- Language: Go (v1.26)
- Runtime: provided.al2023
- Architecture: arm64
CloudFormationテンプレートのポイント
1. ネットワーク構築 (VPC/Subnet/NAT Gateway)
最も重要なのは、NAT Gateway と ルートテーブル の設定です。
template-vpc.yaml では以下のように定義しています。
- NAT Gateway: パブリックサブネットに配置し、EIP (Elastic IP) を割り当てます。
- ルートテーブル: プライベートサブネットの
0.0.0.0/0(インターネット行き) のターゲットを NAT Gateway に向けます。
2. Lambda関数のVPC設定
Lambda関数をVPC内に配置するには、VpcConfig プロパティでサブネットとセキュリティグループを指定します。
# template-lambda.yaml (抜粋)
VpcConfig:
SecurityGroupIds: [!ImportValue FixIPLambda-SecurityGroup]
SubnetIds: [!ImportValue FixIPLambda-PrivateSubnet1] # プライベートサブネットを指定
デプロイ手順
VPCとLambdaの依存関係があるため、以下の順序でデプロイします。
下準備
# デプロイ先のリージョン(例: オレゴン)
export TargetRegion="us-west-2"
export AppName="fix-ip-lambda"
# S3バケット名は全世界で一意である必要があるためリージョン名を含める
export BucketName="${AppName}-${TargetRegion}"
Step 1: アーティファクト用S3バケットの作成
aws cloudformation deploy \
--stack-name "${AppName}-s3" \
--template-file template-s3.yaml \
--parameter-overrides BucketName="${BucketName}" \
--region "${TargetRegion}"
Step 2: VPCネットワークの構築
ここでNAT GatewayとElastic IPが作成されます。
aws cloudformation deploy \
--stack-name "${AppName}-vpc" \
--template-file template-vpc.yaml \
--capabilities CAPABILITY_IAM \
--region "${TargetRegion}"
Step 3: Lambda関数のデプロイ
AWS SAM CLIを使ってビルド・デプロイを行います。
# ビルド
sam build --template-file template-lambda.yaml
# デプロイ
sam deploy \
--stack-name "${AppName}-exec" \
--s3-bucket "${BucketName}" \
--capabilities CAPABILITY_IAM \
--region "${TargetRegion}" \
--parameter-overrides \
URL="https://httpbin.org/ip" \
FixIPEnabled="true"
動作確認
デプロイ完了後、Lambdaを実行してログを確認します。
https://httpbin.org/ip などのIP確認サービスへアクセスし、レスポンスに含まれるIPアドレスが、VPCスタックで作成された Elastic IP と一致していれば成功です。
// main.go (抜粋)
func handler() (string, error) {
// ...
resp, err := http.Get(url)
// ...
// ここで返ってくるIPが固定IPになっているか確認
fmt.Println("Reponse from", url, ":", responseBody)
return responseBody, nil
}
コストに関する注意点
この構成はIP固定化の標準的な手法ですが、コストには注意が必要です。
- NAT Gateway: 起動している時間に対して課金されます(東京リージョン 約 $0.062/時間 ≒ 月額 $45 前後 ※リージョンによる)。
- データ転送: NAT Gatewayを経由するデータ通信量に応じた料金も発生します。
検証目的で作成した場合は、不要になったら以下のコマンドでスタックを削除し、課金を停止することを推奨します。
# 削除順序: Lambda -> VPC -> S3
aws cloudformation delete-stack --stack-name "${AppName}-exec" --region "${TargetRegion}"
aws cloudformation delete-stack --stack-name "${AppName}-vpc" --region "${TargetRegion}"
# S3は中身を空にしてから削除
aws s3 rm s3://${BucketName} --recursive
aws cloudformation delete-stack --stack-name "${AppName}-s3" --region "${TargetRegion}"
まとめ
- LambdaのIP固定化には VPC + NAT Gateway 構成を使用する。
- Lambdaは プライベートサブネット に配置し、インターネット通信を NAT Gateway に向ける。
- NAT Gatewayはコストがかかるため、運用設計時に費用対効果を考慮する。