How to determine ipv6 CIDR block prefix in AWS Cloudformation when creating subnets on a VPC

╄→尐↘猪︶ㄣ 提交于 2019-12-21 18:26:56

问题


AWS generates the ipv6 CIDR block for VPCs so its not possible to determine ahead of time. The generated CIDR block looks something like: 2a05:d018:84c:c500::/56 and is always size 56.

When creating a subnet you have to specify a size 64 block using the full prefixed value. E.g. 2a05:d018:84c:c501::/64.

It's possible to look up the ipv6 CIDR blocks for a VPC in cloudformation, but this returns the full value, not just the prefix. To create a subnet we need to be able to append something 01::/64 to the prefix to create the 64 sized block for the subnet.

I've seen solutions that use a lambda function, but this greatly complicated the templates. I'd like to do this using just the built-in intrinsic functions available in the templates.

When deploying a VPC with ipv6 subnets in the same stack, how can you generate valid ipv6 CIDR blocks for the subnets?


回答1:


Here is a one liner that does the same thing using the Fn::Cidr intrinsic function.

!Select [1, !Cidr [!Select [0, !GetAtt 'Vpc.Ipv6CidrBlocks'], 256, 64]]

For a given block 2a05:d018:84c:c500::/56 this will give you 2a05:d018:84c:c501::/64

Increment the first index to get the next block.

!Select [2, !Cidr [!Select [0, !GetAtt 'Vpc.Ipv6CidrBlocks'], 256, 64]]

will give you 2a05:d018:84c:c502::/64

Also here is a full minimal example including the crucial steps of using an AWS::EC2::VPCCidrBlock resource to attach the IPv6 block to the VPC and using the DependsOn property to make sure that the VPCCidrBlock is attached before the Subnet is created.

Resources:
  Vpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Sub '10.255.0.0/16'

  VpcCidrBlockIpv6:
    Type: 'AWS::EC2::VPCCidrBlock'
    Properties:
      VpcId: !Ref 'Vpc'
      AmazonProvidedIpv6CidrBlock: true

  PrivateSubnet:
    Type: AWS::EC2::Subnet
    DependsOn: VpcCidrBlockIpv6 # Wait for IPv6 CIDR to be attached to VPC before creating subnet
    Properties:
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      VpcId: !Ref 'Vpc'
      AssignIpv6AddressOnCreation: true
      CidrBlock: !Sub '10.255.0.0/20'
      Ipv6CidrBlock: !Select [1, !Cidr [!Select [0, !GetAtt 'Vpc.Ipv6CidrBlocks'], 256, 64]]



回答2:


Here's a way to calculate the first subnet in YAML:

Fn::Sub:
    - "${VpcPart}${SubnetPart}"
    - SubnetPart: 01::/64
      VpcPart: !Select [0, !Split ['00::/56', !Select [0,!GetAtt YourVpc.Ipv6CidrBlocks]]]



回答3:


You can determine the prefix by using a combination of Fn::Split (on 00::/56) and Fn::Select to get the prefix. Then you can append your own value to create the subnet CIDR blocks using Fn::Join. The following example assumes you have a VPC with one or more Ipv6 CIDR blocks associated with it.

Use this value for the Ipv6CidrBlock property on the subnet.

{
    "Fn::Join": [
        "",
        [
            {
                "Fn::Select": [
                    0,
                    {
                        "Fn::Split": [
                            "00::/56",
                            {
                                "Fn::Select": [
                                    0,
                                    {
                                        "Fn::GetAtt": [
                                            "Vpc",
                                            "Ipv6CidrBlocks"
                                        ]
                                    }
                                ]
                            }
                        ]
                    }
                ]
            },
            "01::/64"
        ]
    ]
}



回答4:


AWS VPC Service allows us to create a VPC and associate an Amazon provided /56 IPv6 CIDR block [We cannot provide our own CIDR]. Each subnet can have an IP block of /64. Which means that there can be theoretically 2^(64-56)subnets which is 2^8 = 256 subnets.

For calculating the Subnets for the IPv6 CIDR block, Cloudformation provides an intrinsic function !Cidr for us to do just that.

Syntax of the CIDR Block goes as follows:

!Cidr [ ipBlock, count, cidrBits ]

where

count --> The number of CIDRs to generate. Valid range is between 1 and 256.

cidrBits -->The number of subnet bits for the CIDR. For example, specifying a value "8" for this parameter will create a CIDR with a mask of "/24".

So our statement Becomes:

!Select [0, !Cidr [!Select [0, !GetAtt 'Vpc.Ipv6CidrBlocks'], 256, 64]]

So a sample template to create a VPC with 2 subnets with IPv6 attached to them looks like this:

AWSTemplateFormatVersion: "2010-09-09"
    Resources:
        Vpc:
            Type: AWS::EC2::VPC
            Properties:
                CidrBlock: !Sub '10.255.0.0/16'

        VpcCidrBlockIpv6:
            Type: 'AWS::EC2::VPCCidrBlock'
            Properties:
                VpcId: !Ref 'Vpc'
                AmazonProvidedIpv6CidrBlock: true

        Subnet1:
            Type: AWS::EC2::Subnet
            Properties:
                AvailabilityZone: !Select [ 0, !GetAZs '' ]
                VpcId: !Ref 'Vpc'
                AssignIpv6AddressOnCreation: true
                CidrBlock: !Sub '${PrivateSubnetCIDR1}'
                Ipv6CidrBlock: !Select [0, !Cidr [!Select [0, !GetAtt 'Vpc.Ipv6CidrBlocks'], 256, 64]]

        Subnet2:
            Type: AWS::EC2::Subnet
            Properties:
                VpcId: !Ref 'Vpc'
                AssignIpv6AddressOnCreation: true
                CidrBlock: !Sub '${PrivateSubnetCIDR2}'
                Ipv6CidrBlock: !Select [1, !Cidr [!Select [0, !GetAtt 'Vpc.Ipv6CidrBlocks'], 256, 64]]


来源:https://stackoverflow.com/questions/46571338/how-to-determine-ipv6-cidr-block-prefix-in-aws-cloudformation-when-creating-subn

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!