aws-cdk: VPC fromLookup fails with asymmetric subnets

Note: for support questions, please first reference our documentation, then use Stackoverflow. This repository’s issues are intended for feature requests and bug reports.

  • I’m submitting a …

    • 🪲 bug report
    • 🚀 feature request
    • 📚 construct library gap
    • ☎️ security issue or vulnerability => Please see policy
    • ❓ support request => Please see note at the top of this template.
  • What is the current behavior? If the current behavior is a 🪲bug🪲: Please provide the steps to reproduce

ec2.Vpc.from_lookup(self, "VPC", is_default=True)

Returns the following error when subnets/types are not symmetric across AZs.

Not all subnets in VPC have the same AZs: eu-west-1a,eu-west-1b,eu-west-1c vs eu-west-1b
  • What is the expected behavior (or behavior of feature suggested)? As the name of the lookup function implies, it should return any VPC configuration.

  • What is the motivation / use case for changing the behavior or adding this feature? Deploying an App to existing VPCs should not be predicated on an opinionated view of the VPC.

  • Please tell us about your environment:

ℹ️ CDK Version: 1.1.0 (build 1a11e96) ℹ️ AWS environment variables:

  • AWS_CLOUDWATCH_HOME = /opt/aws/apitools/mon
  • AWS_PATH = /opt/aws
  • AWS_AUTO_SCALING_HOME = /opt/aws/apitools/as
  • AWS_ELB_HOME = /opt/aws/apitools/elb ℹ️ No CDK environment variables
  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. associated pull-request, stackoverflow, gitter, etc)

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 7
  • Comments: 22 (4 by maintainers)

Commits related to this issue

Most upvoted comments

Your setup has:

  • 1 PRIVATE subnet group composed of:

    • subnet-123 in eu-west-1b
  • 1 PUBLIC subnet group composed of:

    • subnet-234 in eu-west-1c
    • subnet-345 in eu-west-1a
    • subnet-456 in eu-west-1b

Currently, the Vpc construct requires that all subnet groups cover the same list of availability zones. You are missing two PRIVATE subnets (in eu-west-1c and eu-west-1a) to satisfy this constraint.

I tend to agree with your point that this seems to force opinions on you, we’re currently investigating ways we could meet this more flexible.

Please keep in mind that the vast majority of your users will have no control over this. We’re developers, our company’s cloud/network engineers have worked hand in hand with AWS contractors to set up our configuration. There is no way they’re changing any of this to accommodate these CDK constraints

In general, lookup functions should not be opinionated and just return the current state. If it exists, it obviously met any AWS requirements to create it in the first place. Further more, the ability to use the information should not be predicated on arbitrary tags. Tags can be useful but in this case, its just a label the may or may not reflect the resource itself.

This is a show stopper for me as well as I have to use a legacy VPC in our production environment. But since the subnets are not symmetric and I cannot easily fix this I would need some guidance regarding workarounds.

@mmoulton could you share how to manually define a VPC in the context json file?

It’s okay if you use only N of M available AZs in your region, but all the subnet groups need ot have the same set of AZs covered.

The default determination is:

  • If there is a aws-cdk:subnet-type tag on the subnet (value one of Public, Private, Isolated), then it maps into that group.
  • Otherwise, if MapPublicIpOnLaunch is true, the subnet is part of the Public group
  • Otherwise, subnet is part of the PRIVATE group

A aws-cdk:subnet-name tag can also be set on the subnets to achieve multiple subnet groups of the same type (i.e. multiple Public / Private / Isolated subnets) – all subnets sharing the same name will be considered a group. When the tag is not present, the group’s name is equal to the subnet group type name (Public / Private / Isolated).

In any case, all of the subnet groups must cover the same list of AZs.

subnets

I got the same issue: Not all subnets in VPC have the same AZs: ap-southeast-2a,ap-southeast-2b,ap-southeast-2c vs ap-southeast-2a,ap-southeast-2a,ap-southeast-2a,ap-southeast-2b,ap-southeast-2b,ap-southeast-2b,ap-southeast-2c,ap-southeast-2c,ap-southeast-2c, the thing is our network has symmetric subnets settings but we don’t have tags for each group which meet the requirement you mentioned above(e.g. aws-cdk:subnet-type). Instead, we have a custom tag called Tier to distinguish different subnet group. Is it possible to let user define their own lookup rule for this? Instead of providing PRIVATE/PUBLIC/ISOLATED, let user provide custom tag matching rules.

So, the workaround that I am doing right now to be able to use the legacy VPC is to simply reference it by ID. And then pass it to the low level API when creating different resources, like this:

const vpcId = "vpc-xxxxxxxx"

const targetGroup = new elb.CfnTargetGroup(this, "TargetGroup", { targetType: elb.TargetType.IP, port: 80, vpcId: vpcId, protocol: "HTTP" });

This works but this means that I cannot use the constructs in most cases which is defeating the purpose of CDK. You should look into this issue so that we do not need to implement hacky solutions like this.

Looking into this more, I’ve found that VPC’s created with LandingZones also only create a single route table for the public subnets. This is causing a violation here: ImportSubnetGroup:67

Regarding the issue with LZ creating 2 Public and 4 Private subnets above, I’ve actually traced the problem to VpcNetworkContextProviderPlugin:166. It seems to me this should also do a reduce to eliminate duplicates. That is the particular problem I’m seeing with the VPC created with the Public-and-2-Private-Subnets-2-AZ LandingZone VPC config as it creates two subnets in 1 AZ, and 2 in another AZ, causing the above code to result in a list of 4 AZ’s such as ['us-west-2a', 'us-west-2b', 'us-west-2a', 'us-west-2b']

I’ve been able to work around this problem by manually defining the VPC in the cdk.context.json file, obviously defeating the purpose of context providers.

Hello @RomainMuller / @rix0rrr

I’m experiencing this exact problem on one of my accounts that has been provisioned with LandingZones. There are multiple VPC configuration options in landing zones that will result in asymmetrical VPC configurations such as Public-and-2-Private-Subnets-2-AZ. The fact that the import requires symmetric subnets seems like a significant hurtle to place on users of CDK. Can you help us understand the reasoning behind this, and more importantly the benefit this provides to CDK?

CDK Version: 1.3.0 / Typescript

Your setup has:

  • 1 PRIVATE subnet group composed of:
    • subnet-123 in eu-west-1b
  • 1 PUBLIC subnet group composed of:
    • subnet-234 in eu-west-1c
    • subnet-345 in eu-west-1a
    • subnet-456 in eu-west-1b

Currently, the Vpc construct requires that all subnet groups cover the same list of availability zones. You are missing two PRIVATE subnets (in eu-west-1c and eu-west-1a) to satisfy this constraint.

I tend to agree with your point that this seems to force opinions on you, we’re currently investigating ways we could meet this more flexible.