VPC IP Address ManagerをCloudFormationで実装してみた
こんにちは、つくぼし(tsukuboshi0755)です!
AWS 上でIPアドレスを一元管理したい場合、VPC IP Address Manager (IPAM)を用いる事で実現可能です。
今回は、VPC IP Address Manager (IPAM)をCloudFormationで実装し、VPCで利用する方法をご紹介します!
やりたい事
以下のリソースをCloudFormationで実装します。
- IPAM
- IPAMを利用するVPC
なおIPAMの設定は、基本以下のブログで実装するものと同様とします。
(リソースのName値のみ変更します)
IPAM
テンプレート全体
IPAMテンプレートの全体を以下に記載します。
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テンプレートの全体を以下に記載します。
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)でした!