在 VPC 上创建子网时如何确定 AWS Cloudformation 中的 ipv6 CIDR 块前缀
How to determine ipv6 CIDR block prefix in AWS Cloudformation when creating subnets on a VPC
AWS 为 VPC 生成 ipv6 CIDR 块,因此无法提前确定。生成的 CIDR 块类似于:2a05:d018:84c:c500::/56
并且大小始终为 56。
创建子网时,您必须使用完整前缀值指定大小为 64 的块。例如。 2a05:d018:84c:c501::/64
.
可以在 cloudformation 中查找 VPC 的 ipv6 CIDR 块,但这 returns 是完整值,而不仅仅是前缀。要创建一个子网,我们需要能够在前缀上附加一些东西 01::/64
来为子网创建 64 大小的块。
我见过使用 lambda 函数的解决方案,但这使模板变得非常复杂。我想仅使用模板中可用的内置内部函数来执行此操作。
在同一堆栈中部署具有 ipv6 子网的 VPC 时,如何为子网生成有效的 ipv6 CIDR 块?
您可以通过组合使用 Fn::Split
(在 00::/56
上)和 Fn::Select
来获取前缀来确定前缀。然后您可以附加您自己的值以使用 Fn::Join
创建子网 CIDR 块。以下示例假设您有一个 VPC,其中关联了一个或多个 Ipv6 CIDR 块。
将此值用于子网上的 Ipv6CidrBlock
属性。
{
"Fn::Join": [
"",
[
{
"Fn::Select": [
0,
{
"Fn::Split": [
"00::/56",
{
"Fn::Select": [
0,
{
"Fn::GetAtt": [
"Vpc",
"Ipv6CidrBlocks"
]
}
]
}
]
}
]
},
"01::/64"
]
]
}
这是一种在 YAML 中计算第一个子网的方法:
Fn::Sub:
- "${VpcPart}${SubnetPart}"
- SubnetPart: 01::/64
VpcPart: !Select [0, !Split ['00::/56', !Select [0,!GetAtt YourVpc.Ipv6CidrBlocks]]]
这是一个使用 Fn::Cidr intrinsic function.
做同样事情的单行本
!Select [1, !Cidr [!Select [0, !GetAtt 'Vpc.Ipv6CidrBlocks'], 256, 64]]
对于给定的块 2a05:d018:84c:c500::/56
这会给你 2a05:d018:84c:c501::/64
增加第一个索引以获得下一个块。
!Select [2, !Cidr [!Select [0, !GetAtt 'Vpc.Ipv6CidrBlocks'], 256, 64]]
会给你2a05:d018:84c:c502::/64
这里还有一个完整的最小示例,包括使用 AWS::EC2::VPCCidrBlock
资源将 IPv6 块附加到 VPC 并使用 DependsOn
属性 确保在创建子网之前附加 VPCCIdrBlock。
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]]
AWS VPC 服务允许我们创建 VPC 并关联亚马逊提供的 /56 IPv6 CIDR 块 [我们无法提供自己的 CIDR]。
每个子网都可以有一个 /64 的 IP 块。这意味着理论上可以有 2^(64-56) 个子网,即 2^8 = 256 个子网。
为了计算 IPv6 CIDR 块的子网,Cloudformation 提供了一个内部函数 !Cidr 供我们执行此操作。
CIDR 块的语法如下:
!Cidr [ ipBlock, count, cidrBits ]
哪里
count --> 要生成的 CIDR 的数量。有效范围在 1 到 256 之间。
cidrBits --> CIDR 的子网位数。例如,为此参数指定值“8”将创建一个掩码为“/24”的 CIDR。
所以我们的语句变成:
!Select [0, !Cidr [!Select [0, !GetAtt 'Vpc.Ipv6CidrBlocks'], 256, 64]]
因此,创建 VPC 的示例模板具有 2 个附加了 IPv6 的子网,如下所示:
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]]
AWS 为 VPC 生成 ipv6 CIDR 块,因此无法提前确定。生成的 CIDR 块类似于:2a05:d018:84c:c500::/56
并且大小始终为 56。
创建子网时,您必须使用完整前缀值指定大小为 64 的块。例如。 2a05:d018:84c:c501::/64
.
可以在 cloudformation 中查找 VPC 的 ipv6 CIDR 块,但这 returns 是完整值,而不仅仅是前缀。要创建一个子网,我们需要能够在前缀上附加一些东西 01::/64
来为子网创建 64 大小的块。
我见过使用 lambda 函数的解决方案,但这使模板变得非常复杂。我想仅使用模板中可用的内置内部函数来执行此操作。
在同一堆栈中部署具有 ipv6 子网的 VPC 时,如何为子网生成有效的 ipv6 CIDR 块?
您可以通过组合使用 Fn::Split
(在 00::/56
上)和 Fn::Select
来获取前缀来确定前缀。然后您可以附加您自己的值以使用 Fn::Join
创建子网 CIDR 块。以下示例假设您有一个 VPC,其中关联了一个或多个 Ipv6 CIDR 块。
将此值用于子网上的 Ipv6CidrBlock
属性。
{
"Fn::Join": [
"",
[
{
"Fn::Select": [
0,
{
"Fn::Split": [
"00::/56",
{
"Fn::Select": [
0,
{
"Fn::GetAtt": [
"Vpc",
"Ipv6CidrBlocks"
]
}
]
}
]
}
]
},
"01::/64"
]
]
}
这是一种在 YAML 中计算第一个子网的方法:
Fn::Sub:
- "${VpcPart}${SubnetPart}"
- SubnetPart: 01::/64
VpcPart: !Select [0, !Split ['00::/56', !Select [0,!GetAtt YourVpc.Ipv6CidrBlocks]]]
这是一个使用 Fn::Cidr intrinsic function.
做同样事情的单行本!Select [1, !Cidr [!Select [0, !GetAtt 'Vpc.Ipv6CidrBlocks'], 256, 64]]
对于给定的块 2a05:d018:84c:c500::/56
这会给你 2a05:d018:84c:c501::/64
增加第一个索引以获得下一个块。
!Select [2, !Cidr [!Select [0, !GetAtt 'Vpc.Ipv6CidrBlocks'], 256, 64]]
会给你2a05:d018:84c:c502::/64
这里还有一个完整的最小示例,包括使用 AWS::EC2::VPCCidrBlock
资源将 IPv6 块附加到 VPC 并使用 DependsOn
属性 确保在创建子网之前附加 VPCCIdrBlock。
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]]
AWS VPC 服务允许我们创建 VPC 并关联亚马逊提供的 /56 IPv6 CIDR 块 [我们无法提供自己的 CIDR]。 每个子网都可以有一个 /64 的 IP 块。这意味着理论上可以有 2^(64-56) 个子网,即 2^8 = 256 个子网。
为了计算 IPv6 CIDR 块的子网,Cloudformation 提供了一个内部函数 !Cidr 供我们执行此操作。
CIDR 块的语法如下:
!Cidr [ ipBlock, count, cidrBits ]
哪里
count --> 要生成的 CIDR 的数量。有效范围在 1 到 256 之间。
cidrBits --> CIDR 的子网位数。例如,为此参数指定值“8”将创建一个掩码为“/24”的 CIDR。
所以我们的语句变成:
!Select [0, !Cidr [!Select [0, !GetAtt 'Vpc.Ipv6CidrBlocks'], 256, 64]]
因此,创建 VPC 的示例模板具有 2 个附加了 IPv6 的子网,如下所示:
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]]