aws-ec2: VPC Construct - Use of vpc.vpcIpv6CidrBlocks does not model VPCCidrBlock dependency in CFN
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the bug
When using the VPC construct to model a dual-stack VPC, one cannot guarantee references to the VPC's underlying IPv6 CIDR block(s) exist at deployment time (no direct references available to mark `AWS::EC2::VPCCidrBlock` as a dependency).
During CFN deployments, this may cause race conditions between CIDR creation and dependent resource creation (ex: a security group).
### Regression Issue
- [ ] Select this option if this issue appears to be a regression.
### Last Known Working CDK Library Version
_No response_
### Expected Behavior
When referencing the `vpcIpv6CidrBlocks` field of a CDK VPC, one expects the underlying `AWS::EC2::VPCCidrBlock` to exist already. One can use `vpcIpv6CidrBlocks` to model security groups (and other relevant resources).
### Current Behavior
When referencing the `vpcIpv6CidrBlocks` field of a CDK VPC to model another resource (ex: security group), one may encounter deployment failures.
```
Logical ID: SecurityGroupIpv6XXX
Status: CREATE_FAILED
Status Reason: Template error: Fn::Select cannot select nonexistent value at index 0
```
Generated CFN JSON for `AWS::EC2::SecurityGroup` contains reference to `AWS::EC2::VPC` resource, not the `AWS::EC2::VPCCidrBlock` resource
```json
{
"DualStackVpcXXX": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "10.0.0.0/16",
"EnableDnsHostnames": true,
"EnableDnsSupport": true,
"InstanceTenancy": "default",
"Tags": [
{
"Key": "Name",
"Value": "XXX/DualStackVpc"
}
]
},
"Metadata": {
"aws:cdk:path": "XXX/DualStackVpc/Resource"
}
},
...
"DualStackVpcipv6cidrXXX": {
"Type": "AWS::EC2::VPCCidrBlock",
"Properties": {
"AmazonProvidedIpv6CidrBlock": true,
"VpcId": {
"Ref": "DualStackVpcXXX"
}
},
"Metadata": {
"aws:cdk:path": "XXX/DualStackVpc/ipv6cidr"
}
},
...
"SecurityGroupIpv6XXX": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Security group for IPv6 PrivateLinks",
"SecurityGroupEgress": [
{
"CidrIp": "255.255.255.255/32",
"Description": "Disallow all traffic",
"FromPort": 252,
"IpProtocol": "icmp",
"ToPort": 86
}
],
"SecurityGroupIngress": [
{
"CidrIpv6": {
"Fn::Select": [
0,
{
"Fn::GetAtt": [
"DualStackVpcXXX",
"Ipv6CidrBlocks"
]
}
]
},
"Description": "Allow IPv6 traffic from within VPC",
"FromPort": 443,
"IpProtocol": "tcp",
"ToPort": 443
}
],
"VpcId": {
"Ref": "DualStackVpcXXX"
}
},
"Metadata": {
"aws:cdk:path": "XXX/SecurityGroupIpv6XXX/Resource"
}
}
}
...
```
### Reproduction Steps
1. Model a dual-stack VPC and a security group using the VPC's `vpcIpv6CidrBlocks` field
```ts
const dualStackVpc: ec2.Vpc = new ec2.Vpc(this, 'DualStackVpc', {
ipProtocol: ec2.IpProtocol.DUAL_STACK
});
const privatelinkSecurityGroup: ec2.SecurityGroup = new ec2.SecurityGroup(this, 'SecurityGroupIpv6', {
vpc: vpc,
allowAllOutbound: false,
allowAllIpv6Outbound: false,
description: 'Security group for IPv6 PrivateLinks',
});
// possible race condition; CREATE_FAILED for reason Fn::Select cannot select nonexistent value at index 0
privatelinkSecurityGroup.addIngressRule(
Peer.ipv6(Fn.select(0, dualStackVpc.vpcIpv6CidrBlocks)),
Port.tcp(443),
'Allow IPv6 traffic from within VPC'
);
```
2. Attempt to deploy the CFN stack
3. Observe create failure for SecurityGroup during CFN deployment
Please note failures depend on server-side conditions. If the IPv6 CIDR is allocated quickly, the deployment may succeed
### Possible Solution
_No response_
### Additional Information/Context
_No response_
### AWS CDK Library version (aws-cdk-lib)
2.221.1
### AWS CDK CLI version
2.1100.3
### Node.js Version
20
### OS
Amazon Linux 2
### Language
TypeScript
### Language Version
_No response_
### Other information
_No response_
Contributor guide
Research direction
Start at the VPC construct's vpcIpv6CidrBlocks implementation and synthesize the TypeScript reproduction to inspect the generated CloudFormation resources. Trace how the SecurityGroup reference is represented relative to AWS::EC2::VPCCidrBlock; done when dependent resources reliably wait for IPv6 CIDR allocation and the synthesized template covers this case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100