ipv6 + dhcp + cloudformation

영진·2023년 1월 27일
0

AWS

목록 보기
15/17
post-thumbnail

오늘 나는 ipv6 + dhcp를 cloudformation stack을 통해 생성하는 작업을 성공하였다.
아래는 내가 stack을 생성할때 참고한 게시물들이다.

vpc: https://docs.aws.amazon.com/codebuild/latest/userguide/cloudformation-vpc-template.html
DHCPOptions: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcpoptions.html
DHCPOptionsAssociation: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcdhcpoptionsassociation.html
ipv6😂: https://raw.githubusercontent.com/suzryo/aws/master/cfn-ipv6-validation/ipv6-validation-vpc.yaml


목적

목적은 다음과 같았다. 총 2가지의 목적이 있다.

  • 2개의 가용영역ipv6 퍼블릭 및 프라이빗 서브넷이 있는 VPC를 생성한다.
  • DHCP 옵션 세트를 활용하여 Amazon Time Sync Service를 통해 동기화 기능을 제공한다.

이제 내가 stack을 어떤식으로 생성하였는지에 대해 작성해 볼 것이다.


파라미터

우선 나는 vpcCIDR, subnetCIDR등 파라미터 값으로 정의 하였다.

정의한 내용은 다음과 같다. 템플릿 버전은 '2010-09-09'로 사용하였다.

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  EnvironmentName:
    Description: An environment name that is prefixed to resource names
    Type: String
    Default: "demo-22"

  VpcCIDR:
    Description: Please enter the IP range (CIDR notation) for this VPC
    Type: String
    Default: 172.16.0.0/16
  PublicSubnet1CIDR:
    Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone
    Type: String
    Default: 172.16.10.0/24

  PublicSubnet2CIDR:
    Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone
    Type: String
    Default: 172.16.11.0/24

  PrivateSubnet1CIDR:
    Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone
    Type: String
    Default: 172.16.12.0/24

  PrivateSubnet2CIDR:
    Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone
    Type: String
    Default: 172.16.13.0/24

VPC

vpc 부분은 아래와 같이 작성하였다.

  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsSupport: true
      EnableDnsHostnames: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-vpc

아마존에서 기본으로 제공하는 IPv6를 허용해 주었다.

  Ipv6VPCCidrBlock:
    Type: AWS::EC2::VPCCidrBlock
    Properties:
      AmazonProvidedIpv6CidrBlock: true
      VpcId: !Ref VPC

외부전용 인터넷 게이트웨이와, 인터넷 게이트웨이를 연결해주었다.
  EgressOnlyInternetGateway:
    Type: AWS::EC2::EgressOnlyInternetGateway
    Properties: 
      VpcId: !Ref VPC


  
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Ref EnvironmentName

  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC

DHCP

dhcp 부분을 설정하였다. 나는 도메인네임과 NTP만 추가해주었다.
추가한 내용은 다음과 같다.

  DhcpOptions: 
    Type: AWS::EC2::DHCPOptions
    Properties:
        DomainNameServers: 
          - 172.16.0.2
        NtpServers: 
          - 169.254.169.123
        Tags: 
        - Key: Name
          Value: !Sub ${EnvironmentName}-dhcp-opt
  
  DHCPOptionsAssociation:
    Type: AWS::EC2::VPCDHCPOptionsAssociation
    Properties:
      DhcpOptionsId: !Ref DhcpOptions
      VpcId: !Ref VPC

public 서브넷

나는 가용영역 a, 가용영역c를 가지는 퍼블릭 서브넷을 생성하였다.
해당 퍼블릭 서브넷은 각각 ipv6 9번째 주소와, 10번째 주소를 가진다.

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    DependsOn:
    - Ipv6VPCCidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      Ipv6CidrBlock: !Sub ['${Param1}10::/64', {Param1: !Select ['0', !Split ['00::/',
              !Select [0, !GetAtt 'VPC.Ipv6CidrBlocks']]]}]
      CidrBlock: !Ref PublicSubnet1CIDR  
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-pub-a

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    DependsOn:
    - Ipv6VPCCidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 2, !GetAZs  '' ] 
      CidrBlock: !Ref PublicSubnet2CIDR
      Ipv6CidrBlock: !Sub ['${Param1}11::/64', {Param1: !Select ['0', !Split ['00::/',
              !Select [0, !GetAtt 'VPC.Ipv6CidrBlocks']]]}]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-pub-c

Private 서브넷

나는 가용영역 a, 가용영역c를 가지는 프라이빗 서브넷을 생성하였다.
해당 퍼블릭 서브넷은 각각 ipv6 11번째 주소와, 12번째 주소를 가진다.

  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    DependsOn:
    - Ipv6VPCCidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 0, !GetAZs  '' ]
      CidrBlock: !Ref PrivateSubnet1CIDR
      Ipv6CidrBlock: !Sub ['${Param1}12::/64', {Param1: !Select ['0', !Split ['00::/',
              !Select [0, !GetAtt 'VPC.Ipv6CidrBlocks']]]}]
      AssignIpv6AddressOnCreation: true
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-priv-a

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    DependsOn:
    - Ipv6VPCCidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 2, !GetAZs  '' ] 
      CidrBlock: !Ref PrivateSubnet2CIDR
      Ipv6CidrBlock: !Sub ['${Param1}13::/64', {Param1: !Select ['0', !Split ['00::/',
              !Select [0, !GetAtt 'VPC.Ipv6CidrBlocks']]]}]
      AssignIpv6AddressOnCreation: true
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-priv-c

NAT 게이트웨이

2개의 가용영역을 가져서 2개의 EIP를 통해 2개의 NAT 게이트웨이를 생성하였다.

  NatGateway1EIP:
    Type: AWS::EC2::EIP
    DependsOn: InternetGatewayAttachment
    Properties:
      Domain: vpc

  NatGateway2EIP:
    Type: AWS::EC2::EIP
    DependsOn: InternetGatewayAttachment
    Properties:
      Domain: vpc



  NatGateway1:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGateway1EIP.AllocationId
      SubnetId: !Ref PublicSubnet1

  NatGateway2:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGateway2EIP.AllocationId
      SubnetId: !Ref PublicSubnet2

퍼블릭 라우팅 테이블 설정

퍼블릭 서브넷을 모두 연결하는 라우팅 테이블을 생성하였다.
인터넷 게이트웨이를 연결하고, 대상을 0.0.0.0/0, ::/0으로 지정하였다.

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-public-rt
  DefaultPublicRoute:
    Type: AWS::EC2::Route
    DependsOn: InternetGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  DefaultPublicRouteV6:
    Type: AWS::EC2::Route
    DependsOn: InternetGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      GatewayId: !Ref InternetGateway
      DestinationIpv6CidrBlock: "::/0"

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet1

  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet2

프라이빗라우팅 테이블 설정

퍼블릭 서브넷을 모두 연결하는 라우팅 테이블을 생성하였다.
NAT 게이트웨이 대상을 0.0.0.0/0으로 지정하고,
외부전용 인터넷 게이트웨이 대상을 ::/0으로 지정하였다.

stack은 다음과 같다.

  DefaultPrivateRoute1:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway1

  PrivateSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      SubnetId: !Ref PrivateSubnet1

  PrivateSubnet1DefaultIpv6Route:
    Type: AWS::EC2::Route
    Properties:
      DestinationIpv6CidrBlock: ::/0
      RouteTableId: !Ref PrivateRouteTable1
      EgressOnlyInternetGatewayId: !Ref EgressOnlyInternetGateway





  PrivateRouteTable2:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-priv-c-rt

  DefaultPrivateRoute2:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable2
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway2

  PrivateSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTable2
      SubnetId: !Ref PrivateSubnet2

  PrivateSubnet2DefaultIpv6Route:
    Type: AWS::EC2::Route
    Properties:
      DestinationIpv6CidrBlock: ::/0
      RouteTableId: !Ref PrivateRouteTable2
      EgressOnlyInternetGatewayId: !Ref EgressOnlyInternetGateway

완성된 코드

나의 완성된 코드는 아래 문서와 유사하다.
즉 아래 문서로 vpc를 생성하였다면 이해하기 쉬울 것이다.

vpc stack: https://docs.aws.amazon.com/codebuild/latest/userguide/cloudformation-vpc-template.html

완성된 코드는 다음과 같이 나타낼 수 있다.

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  EnvironmentName:
    Description: An environment name that is prefixed to resource names
    Type: String
    Default: "demo-22"

  VpcCIDR:
    Description: Please enter the IP range (CIDR notation) for this VPC
    Type: String
    Default: 172.16.0.0/16
  PublicSubnet1CIDR:
    Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone
    Type: String
    Default: 172.16.10.0/24

  PublicSubnet2CIDR:
    Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone
    Type: String
    Default: 172.16.11.0/24

  PrivateSubnet1CIDR:
    Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone
    Type: String
    Default: 172.16.12.0/24

  PrivateSubnet2CIDR:
    Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone
    Type: String
    Default: 172.16.13.0/24

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsSupport: true
      EnableDnsHostnames: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-vpc


  Ipv6VPCCidrBlock:
    Type: AWS::EC2::VPCCidrBlock
    Properties:
      AmazonProvidedIpv6CidrBlock: true
      VpcId: !Ref VPC


  EgressOnlyInternetGateway:
    Type: AWS::EC2::EgressOnlyInternetGateway
    Properties: 
      VpcId: !Ref VPC


  
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Ref EnvironmentName

  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC
  


  DhcpOptions: 
    Type: AWS::EC2::DHCPOptions
    Properties:
        DomainNameServers: 
          - 172.16.0.2
        NtpServers: 
          - 169.254.169.123
        Tags: 
        - Key: Name
          Value: !Sub ${EnvironmentName}-dhcp-opt
  
  DHCPOptionsAssociation:
    Type: AWS::EC2::VPCDHCPOptionsAssociation
    Properties:
      DhcpOptionsId: !Ref DhcpOptions
      VpcId: !Ref VPC



  PublicSubnet1:
    Type: AWS::EC2::Subnet
    DependsOn:
    - Ipv6VPCCidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      Ipv6CidrBlock: !Sub ['${Param1}10::/64', {Param1: !Select ['0', !Split ['00::/',
              !Select [0, !GetAtt 'VPC.Ipv6CidrBlocks']]]}]
      CidrBlock: !Ref PublicSubnet1CIDR  
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-pub-a

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    DependsOn:
    - Ipv6VPCCidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 2, !GetAZs  '' ] 
      CidrBlock: !Ref PublicSubnet2CIDR
      Ipv6CidrBlock: !Sub ['${Param1}11::/64', {Param1: !Select ['0', !Split ['00::/',
              !Select [0, !GetAtt 'VPC.Ipv6CidrBlocks']]]}]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-pub-c




  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    DependsOn:
    - Ipv6VPCCidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 0, !GetAZs  '' ]
      CidrBlock: !Ref PrivateSubnet1CIDR
      Ipv6CidrBlock: !Sub ['${Param1}12::/64', {Param1: !Select ['0', !Split ['00::/',
              !Select [0, !GetAtt 'VPC.Ipv6CidrBlocks']]]}]
      AssignIpv6AddressOnCreation: true
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-priv-a

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    DependsOn:
    - Ipv6VPCCidrBlock
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 2, !GetAZs  '' ] 
      CidrBlock: !Ref PrivateSubnet2CIDR
      Ipv6CidrBlock: !Sub ['${Param1}13::/64', {Param1: !Select ['0', !Split ['00::/',
              !Select [0, !GetAtt 'VPC.Ipv6CidrBlocks']]]}]
      AssignIpv6AddressOnCreation: true
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-priv-c




  NatGateway1EIP:
    Type: AWS::EC2::EIP
    DependsOn: InternetGatewayAttachment
    Properties:
      Domain: vpc

  NatGateway2EIP:
    Type: AWS::EC2::EIP
    DependsOn: InternetGatewayAttachment
    Properties:
      Domain: vpc



  NatGateway1:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGateway1EIP.AllocationId
      SubnetId: !Ref PublicSubnet1

  NatGateway2:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGateway2EIP.AllocationId
      SubnetId: !Ref PublicSubnet2





  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-public-rt
  DefaultPublicRoute:
    Type: AWS::EC2::Route
    DependsOn: InternetGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  DefaultPublicRouteV6:
    Type: AWS::EC2::Route
    DependsOn: InternetGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      GatewayId: !Ref InternetGateway
      DestinationIpv6CidrBlock: "::/0"

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet1

  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet2





  PrivateRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-priv-a-rt

  DefaultPrivateRoute1:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway1

  PrivateSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      SubnetId: !Ref PrivateSubnet1

  PrivateSubnet1DefaultIpv6Route:
    Type: AWS::EC2::Route
    Properties:
      DestinationIpv6CidrBlock: ::/0
      RouteTableId: !Ref PrivateRouteTable1
      EgressOnlyInternetGatewayId: !Ref EgressOnlyInternetGateway





  PrivateRouteTable2:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-priv-c-rt

  DefaultPrivateRoute2:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable2
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway2

  PrivateSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTable2
      SubnetId: !Ref PrivateSubnet2

  PrivateSubnet2DefaultIpv6Route:
    Type: AWS::EC2::Route
    Properties:
      DestinationIpv6CidrBlock: ::/0
      RouteTableId: !Ref PrivateRouteTable2
      EgressOnlyInternetGatewayId: !Ref EgressOnlyInternetGateway

느낀점

  • 2개의 AZ를 가진 Ipv6 stack에 관한 자료가 별로 없어서 힘들었던거 같다.
  • 완성을 딱 하였을때 성취감으로 울뻔한 거 같다.
profile
I'm good at cloud computing.

0개의 댓글