#🔷 はじめに
外部APIにリクエストを投げるLambda関数を作ったのですが、外部API側でIP制限をかける事になったので、Lambda関数のIPを固定化する必要が出てきました。
そこで、以下を参考にVPC環境を構築して、外部APIにリクエストを投げる際の、リクエスト元のIPアドレスを固定化しました。
Lambdaの実行IPアドレスを固定し、kintoneセキュアアクセスに対応する方法
その際、設定のドキュメントも併せて作ろうと思ったのですが、AWS CloudFormationのテンプレートファイルを作れば、設定ドキュメント兼環境構築プログラムになると思い、以下を参考にしながらVPC環境を定義したテンプレート作ってみました。
AWS CloudFormationによるVPC作成 + public及びprivateサブネット作成
ちなみに、最初はAWS SAMでLambdaも含めて一つのテンプレートを作ろうとしましたが、**AWS SAMからはVPCの構築は対応していない(2019年7月時点)**という事だったので、VPCはCloudFormationから構築する事にしました。
#🔷 作るもの
今回構築するVPC環境は以下のようなイメージです。
使い捨てリソースであるLambda関数に固定IPを割り当てるのは無理なので、VPC環境を構築して、Lambda関数がVPCの外に出る時に通過する、NAT GatewayにIPを割り振ることで、リクエスト元のIPアドレスの固定化を実現しています。
サブネットがAvailability Zone別に2セット作ってあるのは、実際にLambda関数にPrivateサブネットを割り当てた時、複数のPrivateサブネットを割り当てる事を推奨する警告が表示されたので、一応2セット用意しました。
#🔷テンプレートサンプル
CloudFormationのテンプレートは以下の通りです。
テンプレートリファレンスに書き方が一通り書いてあるので、時間を掛ければ書くのは難しくないですが、とにかく設定する箇所が多いので、慣れないうちは設定漏れ等で苦戦すると思います。
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: hoge環境
Resources:
# ■□ VPC環境構築 □■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■
# ■□■□ VPCの作成
hogeVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: 'false'
EnableDnsHostnames: 'false'
InstanceTenancy: default
Tags:
- Key: product
Value: hoge
- Key: developer
Value: jimu
- Key: Name
Value: hoge-vpc
# ■□■□ インターネットゲートウェイの作成
hogeIGW:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: product
Value: hoge
- Key: developer
Value: jimu
- Key: Name
Value: hoge-igw
# ■□■□■□ インターネットゲートウェイをVPCにセット
AttachVpcGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId:
Ref: hogeVPC
InternetGatewayId:
Ref: hogeIGW
# ■□ サブネットの設定(2つのAZに作成) □■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■
# ■□■□ Publicのルートテーブルの作成
hogeRTblPublicAZ01:
Type: AWS::EC2::RouteTable
Properties:
VpcId:
Ref: hogeVPC
Tags:
- Key: product
Value: hoge
- Key: developer
Value: jimu
- Key: Name
Value: hoge-rtb-az01-igw
hogeRTblPublicAZ02:
Type: AWS::EC2::RouteTable
Properties:
VpcId:
Ref: hogeVPC
Tags:
- Key: product
Value: hoge
- Key: developer
Value: jimu
- Key: Name
Value: hoge-rtb-az02-igw
# ■□■□■□ IGW-publicルーティング
hogeRouteIGWPublicAZ01:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref hogeRTblPublicAZ01
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref hogeIGW
hogeRouteIGWPublicAZ02:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref hogeRTblPublicAZ02
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref hogeIGW
# ■□■□ Privateのルートテーブルの作成
hogeRTblPrivateAZ01:
Type: AWS::EC2::RouteTable
Properties:
VpcId:
Ref: hogeVPC
Tags:
- Key: product
Value: hoge
- Key: developer
Value: jimu
- Key: Name
Value: hoge-rtb-az01-nat
hogeRTblPrivateAZ02:
Type: AWS::EC2::RouteTable
Properties:
VpcId:
Ref: hogeVPC
Tags:
- Key: product
Value: hoge
- Key: developer
Value: jimu
- Key: Name
Value: hoge-rtb-az02-nat
# ■□■□■□ Nat-privateルーティング
hogeRouteNatPrivateAZ01:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref hogeRTblPrivateAZ01
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: hogeNatAZ01
hogeRouteNatPrivateAZ02:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref hogeRTblPrivateAZ02
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: hogeNatAZ02
# ■□■□ NATゲートウェイの作成
hogeNatAZ01:
Type: AWS::EC2::NatGateway
Properties:
AllocationId:
Fn::GetAtt:
- hogeEipAZ01
- AllocationId
SubnetId:
Ref: hogeSBNPrivateAZ01
Tags:
- Key: product
Value: hoge
- Key: developer
Value: jimu
- Key: Name
Value: hoge-nat-az01
hogeNatAZ02:
Type: AWS::EC2::NatGateway
Properties:
AllocationId:
Fn::GetAtt:
- hogeEipAZ02
- AllocationId
SubnetId:
Ref: hogeSBNPrivateAZ02
Tags:
- Key: product
Value: hoge
- Key: developer
Value: jimu
- Key: Name
Value: hoge-nat-az02
# ■□■□ EIPの作成
hogeEipAZ01:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
hogeEipAZ02:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
# ■□■□ Publicサブネットの作成
hogeSBNPublicAZ01:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: hogeVPC
CidrBlock: 10.0.10.0/24
# 指定したregionの最初のazを選択
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: ""
Tags:
- Key: product
Value: hoge
- Key: developer
Value: jimu
- Key: Name
Value: hoge-sbn-public-az01
hogeSBNPublicAZ02:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: hogeVPC
CidrBlock: 10.0.12.0/24
# 指定したregionの最初のazを選択
AvailabilityZone:
Fn::Select:
- 1
- Fn::GetAZs: ""
Tags:
- Key: product
Value: hoge
- Key: developer
Value: jimu
- Key: Name
Value: hoge-sbn-public-az02
# ■□■□■□ サブネットをルートテーブルに関連付け
hogeSbnRTblAssociationAZ01:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId:
Ref: hogeSBNPublicAZ01
RouteTableId:
Ref: hogeRTblPublicAZ01
hogeSbnRTblAssociationAZ02:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId:
Ref: hogeSBNPublicAZ02
RouteTableId:
Ref: hogeRTblPublicAZ02
# ■□■□ Privateサブネットの作成
hogeSBNPrivateAZ01:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: hogeVPC
CidrBlock: 10.0.11.0/24
# 指定したregionの最初のazを選択
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: ""
Tags:
- Key: product
Value: hoge
- Key: developer
Value: jimu
- Key: Name
Value: hoge-sbn-private-az01
hogeSBNPrivateAZ02:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: hogeVPC
CidrBlock: 10.0.13.0/24
# 指定したregionの最初のazを選択
AvailabilityZone:
Fn::Select:
- 1
- Fn::GetAZs: ""
Tags:
- Key: product
Value: hoge
- Key: developer
Value: jimu
- Key: Name
Value: hoge-sbn-private-az02
# ■□■□ セキュリティグループの作成
hogeSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security Group for hoge VPC
VpcId:
Ref: hogeVPC
Tags:
- Key: product
Value: hoge
- Key: developer
Value: jimu
- Key: Name
Value: hoge-vpc-sg
🔶 ポイント
Availability Zoneの指定を以下のように書くことで、配置可能なAvailability Zoneのリストを取ってくきて、その1件目を選択する事ができます。
# 指定したregionの最初のazを選択
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: ""
このように書くことで、Availability Zoneをハードコーディングしなくてすむので、このテンプレートファイルはどのリージョンでも使用する事ができるようになります。
また、セキュリティグループは今回は細かく設定していませんが、以下のように最低限の記述にする事で、インバウンドなし、アウトバウンドはすべてOKという、デフォルトよりはマシな設定にしています。
hogeSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security Group for hoge VPC
VpcId:
Ref: hogeVPC
#🔷 まとめ
以上で設定は完了です。
とりあえず、最初の全体図と、テンプレートファイルがあれば、設計書の代わりになるかと思います。(Elastic IP等の補足メモは必要ですが)
テンプレートファイルなら、見て分からなければ、最悪CloudFomationを使えば現物を再現する事もできます。
最初は作るのに時間が掛ると思いますが、たくさん作っていけば、だんだん流用できる部分が増えてくるので、余裕がある時は挑戦してみてはいかがでしょうか。
#🔷 参考