aws / aws/aws-cdk

aws-ec2: VPC Construct - Use of vpc.vpcIpv6CidrBlocks does not model VPCCidrBlock dependency in CFN

Open
#36,714 1 comment 0 reactions 0 assignees View on GitHub
@aws-cdk/aws-ec2 bug effort/medium good first issue p2
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.