Closed joel-aws closed 3 years ago
Temporary workaround in a stack when the runtime context for the imported VPC has already been generated:
def _get_ipv4_cidr(self) -> str:
"""Returns the IPv4 CIDR for a given subnet.
Temporary fix for: https://github.com/aws/aws-cdk/issues/11821
"""
try:
return self.emr_subnet.ipv4_cidr_block
except: # noqa
print("Error getting the subnet via Lookup. Now searching Runtime Context.")
ctx = json.loads(os.environ["CDK_CONTEXT_JSON"])
for key in ctx.keys():
if all(x in key for x in [self._vpc.vpc_id, self.region, self.account]):
for subnet_type in ctx[key]["subnetGroups"]:
for subnet in subnet_type["subnets"]:
if subnet["subnetId"] == self.emr_subnet.subnet_id:
return subnet["cidr"]
Hello, any idea when this might be fixed? I tried the workaround but it does not work in our build pipeline since the context is not there. I looked at the code for other resources that have a from_* factory method (eg SecurityGroup) to see if that could be reused, but I am not familiar with typescript so I didn't get much further unfortunately.
Hello @rix0rrr,
In the subnetGroupToSubnets function in https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-ec2/lib/vpc.ts#L1888
the ipv4CidrBlock attribute is missing :
private subnetGroupToSubnets(subnetGroup: cxapi.VpcSubnetGroup): ISubnet[] {
const ret = new Array<ISubnet>();
for (let i = 0; i < subnetGroup.subnets.length; i++) {
const vpcSubnet = subnetGroup.subnets[i];
ret.push(Subnet.fromSubnetAttributes(this, `${subnetGroup.name}Subnet${i + 1}`, {
availabilityZone: vpcSubnet.availabilityZone,
subnetId: vpcSubnet.subnetId,
routeTableId: vpcSubnet.routeTableId,
// Add this to fix
ipv4CidrBlock: vpcSubnet.cidr
//
}));
}
return ret;
}
Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.
If somebody is still using the old version, here is the workaround in typescript:
interface Subnet {
subnetId: string;
cidr: string;
}
interface SubnetGroup {
subnets: Subnet[];
}
interface VpcData {
vpcId: string;
subnetGroups: SubnetGroup[];
}
interface ContextData {
[key: string]: VpcData;
}
...
...
private getIpv4Cidr(vpc: ec2.IVpc, emrSubnet: ec2.ISubnet, region: string, account: string): string {
try {
return emrSubnet.ipv4CidrBlock;
} catch (error) {
console.error(`Error getting the subnet via Lookup. Error: ${error}`);
const ctxJson = process.env.CDK_CONTEXT_JSON;
if (!ctxJson) {
throw new Error("CDK_CONTEXT_JSON environment variable not found.");
}
const ctxData: ContextData = JSON.parse(ctxJson);
const vpcId = vpc.vpcId;
for (const key in ctxData) {
if (key.includes(vpcId) && key.includes(region) && key.includes(account)) {
const vpcData = ctxData[key];
for (const subnetGroup of vpcData["subnetGroups"]) {
for (const subnet of subnetGroup["subnets"]) {
if(subnet["subnetId"] === emrSubnet.subnetId) {
console.log("Subnet CIDR: ", subnet["cidr"]);
return subnet["cidr"];
}
}
}
}
}
console.log("Subnet CIDR not found!!!")
return ""; // Return empty string if CIDR not found
}
}
When referencing a VPC from its ID, despite populating the Runtime Context with all the VPC's information (including the subnets' CIDRs), an error is thrown when trying to get the the IPv4 CIDR block of a given subnet.
Reproduction Steps
What did you expect to happen?
I expected the subnet's IPv4 CIDR block to be returned, similar to how it would've been returned if the VPC were created (
self.vpc = ec2.Vpc(self, "VPC", cidr="10.0.0.0/16", max_azs=3)
) and referenced.What actually happened?
The IPv4 CIDR was not returned; instead the following error was given:
You cannot reference an imported Subnet's IPv4 CIDR if it was not supplied. Add the ipv4CidrBlock when importing using Subnet.fromSubnetAttributes()
Environment
This is :bug: Bug Report