こんにちは、つくぼし(tsukuboshi0755)です!
AWS 上でIPアドレスを一元管理したい場合、VPC IP Address Manager (IPAM)を用いる事で実現可能です。
今回は、VPC IP Address Manager (IPAM)をCloudFormationで実装し、VPCで利用する方法をご紹介します!
やりたい事
以下のリソースをCloudFormationで実装します。
- IPAM
- IPAMを利用するVPC
なおIPAMの設定は、基本以下のブログで実装するものと同様とします。
(リソースのName値のみ変更します)
IPAM
テンプレート全体
IPAMテンプレートの全体を以下に記載します。
ipam.yaml
AWSTemplateFormatVersion: "2010-09-09"
# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------#
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: "IPAM Configuration"
Parameters:
- Name
- TopLevelPoolCidr
- RegionalPoolCidr
- DevelopmentPoolCidr
- DevelopMentPoolMinNetmask
- DevelopMentPoolDefNetmask
- DevelopMentPoolMaxNetmask
# ------------------------------------------------------------#
# Parameters
# ------------------------------------------------------------#
Parameters:
Name:
Description: "Fill in the System Name of IPAM."
Type: String
Default: cm
TopLevelPoolCidr:
Description: "Fill in the Cidr of Top-level Pool."
Type: String
Default: 192.0.0.0/8
RegionalPoolCidr:
Description: "Fill in the Cidr of Regional Pool."
Type: String
Default: 192.0.0.0/12
DevelopmentPoolCidr:
Description: "Fill in the Cidr of Development Pool."
Type: String
Default: 192.0.0.0/14
DevelopMentPoolMinNetmask:
Description: "Fill in the Minimum Netmask Length of Development Pool."
Type: Number
Default: 16
DevelopMentPoolDefNetmask:
Description: "Fill in the Default Netmask Length of Development Pool."
Type: Number
Default: 16
DevelopMentPoolMaxNetmask:
Description: "Fill in the Maximum Netmask Length of Development Pool."
Type: Number
Default: 24
# ------------------------------------------------------------#
# Resources
# ------------------------------------------------------------#
Resources:
# IP Address Manager
IPAM:
Type: AWS::EC2::IPAM
Properties:
OperatingRegions:
- RegionName: ap-northeast-1
Tags:
- Key: Name
Value: !Sub "${Name}-ipam"
IPAMTopLevelPool:
Type: AWS::EC2::IPAMPool
Properties:
AddressFamily: ipv4
Description: "top-level pool"
IpamScopeId: !GetAtt IPAM.PrivateDefaultScopeId
ProvisionedCidrs:
- Cidr: !Ref TopLevelPoolCidr
Tags:
- Key: Name
Value: !Sub "${Name}-toplevel-pool"
IPAMRegionalPool:
Type: AWS::EC2::IPAMPool
Properties:
AddressFamily: ipv4
Description: "regional pool"
IpamScopeId: !GetAtt IPAM.PrivateDefaultScopeId
Locale: ap-northeast-1
SourceIpamPoolId: !Ref IPAMTopLevelPool
ProvisionedCidrs:
- Cidr: !Ref RegionalPoolCidr
Tags:
- Key: Name
Value: !Sub "${Name}-regional-pool"
IPAMDevelopmentPool:
Type: AWS::EC2::IPAMPool
Properties:
AddressFamily: ipv4
AllocationMinNetmaskLength: !Ref DevelopMentPoolMinNetmask
AllocationDefaultNetmaskLength: !Ref DevelopMentPoolDefNetmask
AllocationMaxNetmaskLength: !Ref DevelopMentPoolMaxNetmask
Description: "development pool"
IpamScopeId: !GetAtt IPAM.PrivateDefaultScopeId
Locale: ap-northeast-1
SourceIpamPoolId: !Ref IPAMRegionalPool
ProvisionedCidrs:
- Cidr: !Ref DevelopmentPoolCidr
Tags:
- Key: Name
Value: !Sub "${Name}-development-pool"
# ------------------------------------------------------------#
# Outputs
# ------------------------------------------------------------#
Outputs:
TopLevelPoolId:
Description: "Top-level pool id"
Value: !Ref IPAMTopLevelPool
RegionalPoolId:
Description: "Regional pool id"
Value: !Ref IPAMRegionalPool
DevelopmentPoolId:
Description: "Development pool id"
Value: !Ref IPAMDevelopmentPool
Export:
Name: DevelopmentPoolId
以下、テンプレートのポイントを説明します。
IPAM全般
IPAM:
Type: AWS::EC2::IPAM
Properties:
OperatingRegions:
- RegionName: ap-northeast-1
Tags:
- Key: Name
Value: !Sub "${Name}-ipam"
OperatingRegions
で、IPAMが管理する運用リージョンを設定します。
今回はap-northeast-1
のみとしていますが、リスト形式で複数リージョンを指定する事も可能です。
トップレベルプール
IPAMTopLevelPool:
Type: AWS::EC2::IPAMPool
Properties:
AddressFamily: ipv4
Description: "top-level pool"
IpamScopeId: !GetAtt IPAM.PrivateDefaultScopeId
ProvisionedCidrs:
- Cidr: !Ref TopLevelPoolCidr
Tags:
- Key: Name
Value: !Sub "${Name}-toplevel-pool"
IpamScopeId
には、プライベートスコープのIDを指定する必要があります。
今回はデフォルトのプライベートスコープを指定していますが、新規のプライベートスコープを作成し指定する事も可能です。
リージョナルプール
IPAMRegionalPool:
Type: AWS::EC2::IPAMPool
Properties:
AddressFamily: ipv4
Description: "regional pool"
IpamScopeId: !GetAtt IPAM.PrivateDefaultScopeId
Locale: ap-northeast-1
SourceIpamPoolId: !Ref IPAMTopLevelPool
ProvisionedCidrs:
- Cidr: !Ref RegionalPoolCidr
Tags:
- Key: Name
Value: !Sub "${Name}-regional-pool"
Locale
に、プールが属するリージョンを指定する必要があります。
今回はCloudFormationを実行するap-northeast-1
を指定します。
開発者プール
IPAMDevelopmentPool:
Type: AWS::EC2::IPAMPool
Properties:
AddressFamily: ipv4
AllocationMinNetmaskLength: !Ref DevelopMentPoolMinNetmask
AllocationDefaultNetmaskLength: !Ref DevelopMentPoolDefNetmask
AllocationMaxNetmaskLength: !Ref DevelopMentPoolMaxNetmask
Description: "development pool"
IpamScopeId: !GetAtt IPAM.PrivateDefaultScopeId
Locale: ap-northeast-1
SourceIpamPoolId: !Ref IPAMRegionalPool
ProvisionedCidrs:
- Cidr: !Ref DevelopmentPoolCidr
Tags:
- Key: Name
Value: !Sub "${Name}-development-pool"
必要に応じて、開発者プールを設定します。(無くても問題ありません)
AllocationMinNetmaskLength
、AllocationDefaultNetmaskLength
、AllocationMaxNetmaskLength
で、割り当て可能なサブネットマスクの最小値/デフォルト値/最大値を指定します。
VPC
テンプレート全体
IPAMを利用するVPCテンプレートの全体を以下に記載します。
vpc.yaml
AWSTemplateFormatVersion: "2010-09-09"
# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------#
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: "VPC Configuration"
Parameters:
- Name
- Env
- VPCNetmask
# ------------------------------------------------------------#
# Parameters
# ------------------------------------------------------------#
Parameters:
Name:
Description: "Fill in the System Name of IPAM."
Type: String
Default: cm
Env:
Description: "Select the environment."
Type: String
Default: dev
AllowedValues:
- prd
- stg
- dev
VPCNetmask:
Description: "Fill in the Netmask Length of VPC."
Type: Number
Default: 16
# ------------------------------------------------------------#
# Resources
# ------------------------------------------------------------#
Resources:
# VPC
VPC:
Type: AWS::EC2::VPC
Properties:
EnableDnsSupport: true
EnableDnsHostnames: true
Ipv4IpamPoolId: !ImportValue DevelopmentPoolId
Ipv4NetmaskLength: !Ref VPCNetmask
Tags:
- Key: Name
Value: !Sub "${Name}-${Env}-vpc"
# Internet Gateway
IGW:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub "${Name}-${Env}-igw"
IGWAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref IGW
IGWRoute:
Type: AWS::EC2::Route
DependsOn: IGWAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref IGW
# Subnet
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select
- 0
- !GetAZs
Ref: AWS::Region
VpcId: !Ref VPC
CidrBlock: !Select [ 0, !Cidr [ !GetAtt VPC.CidrBlock, 4, 8 ]]
Tags:
- Key: Name
Value: !Sub "${Name}-${Env}-public-subnet-1"
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select
- 1
- !GetAZs
Ref: AWS::Region
VpcId: !Ref VPC
CidrBlock: !Select [ 1, !Cidr [ !GetAtt VPC.CidrBlock, 4, 8 ]]
Tags:
- Key: Name
Value: !Sub "${Name}-${Env}-public-subnet-2"
# Route Table
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${Name}-${Env}-public-rt"
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet1
RouteTableId: !Ref PublicRouteTable
PublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet2
RouteTableId: !Ref PublicRouteTable
# Network ACL
PublicNetworkAcl:
Type: AWS::EC2::NetworkAcl
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${Name}-${Env}-public-nacl"
PublicSubnet1NetworkAclAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref PublicSubnet1
NetworkAclId: !Ref PublicNetworkAcl
PublicSubnet2NetworkAclAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref PublicSubnet2
NetworkAclId: !Ref PublicNetworkAcl
以下、テンプレートのポイントを説明します。
VPC
VPC:
Type: AWS::EC2::VPC
Properties:
EnableDnsSupport: true
EnableDnsHostnames: true
Ipv4IpamPoolId: !ImportValue DevelopmentPoolId
Ipv4NetmaskLength: !Ref VPCNetmask
Tags:
- Key: Name
Value: !Sub "${Name}-${Env}-vpc"
Ipv4IpamPoolId
に、VPCが利用するIPAMプールのIDを指定する必要があります。
今回は、IPAMテンプレートで開発者プールIDを出力し、Ipv4IpamPoolId
で参照するようにしています。
またIpv4NetmaskLength
で、VPCのサブネットマスクを指定できます。
その場合、指定したIPAMプールのサブネットマスクの範囲の中(今回は16-24のいずれか)で指定する必要があります。
Subnet
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select
- 1
- !GetAZs
Ref: AWS::Region
VpcId: !Ref VPC
CidrBlock: !Select [ 1, !Cidr [ !GetAtt VPC.CidrBlock, 4, 8 ]]
Tags:
- Key: Name
Value: !Sub "${Name}-${Env}-public-subnet-2"
IPAMを利用したVPCを作成する場合、Subnetは自動で作成されないため、別途設定する必要があります。
その際にCidr関数を利用し、VPCのCIDRから自動でSubnetにCIDRを割り当てるように設定します。
なおCidr関数については、以下のブログをご参照ください。
デプロイ後の設定値
IPAMテンプレートをデフォルト値のままでデプロイすると、以下の設定でIPAMプールが構築されます。
またVPCテンプレートをデフォルト値のままでデプロイすると、以下の設定でVPC及びSubnetが構築されます。
最後に
今回は、VPC IP Address Manager (IPAM)をCloudFormationで実装し、VPCで利用する方法を紹介しました!
IPAMテンプレート自体は簡単に作れる一方で、VPCテンプレートはCidr関数を用いるというような工夫が必要になりますね。
IPAMをCloudFormationで実装し管理したいという方がいらっしゃれば、ぜひご参照ください。
以上、つくぼし(tsukuboshi0755)でした!