LoginSignup
8

More than 3 years have passed since last update.

Lambda用のVPC環境を、CloudFormationで構築する

Posted at

🔷 はじめに

外部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セット用意しました。

VPCイメージ.png

🔷テンプレートサンプル

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を使えば現物を再現する事もできます。

最初は作るのに時間が掛ると思いますが、たくさん作っていけば、だんだん流用できる部分が増えてくるので、余裕がある時は挑戦してみてはいかがでしょうか。

🔷 参考

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
8