오늘 나는 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가지의 목적이 있다.
이제 내가 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:
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 부분을 설정하였다. 나는 도메인네임과 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
나는 가용영역 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
나는 가용영역 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
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