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 ...
What is the current behavior?
If the current behavior is a :beetle:bug:beetle:: 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:
Hey,
Could you provide your VPC's subnet description? You can obtain it using the AWS CLI (replace ${VPC_ID}
with your default VPC ID, which you'll find in the AWS Console):
aws ec2 describe-subnets --filters "Name=vpcId,Values=${VPC_ID}"
Before posting the result, it would be a good idea to remove references that are specific to your account (we don't need to see those anyway):
SubnetId
VpcId
OwnerId
SubnetArn
{
"Subnets": [
{
"MapPublicIpOnLaunch": false,
"AvailabilityZoneId": "euw1-az1",
"AvailableIpAddressCount": 4091,
"DefaultForAz": false,
"SubnetArn": "arn:aws:ec2:eu-west-1:123456789012:subnet/subnet-123",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-12345",
"State": "available",
"AvailabilityZone": "eu-west-1b",
"SubnetId": "subnet-123",
"OwnerId": "123456789012",
"CidrBlock": "172.31.48.0/20",
"AssignIpv6AddressOnCreation": false
},
{
"MapPublicIpOnLaunch": true,
"AvailabilityZoneId": "euw1-az2",
"AvailableIpAddressCount": 4089,
"DefaultForAz": true,
"SubnetArn": "arn:aws:ec2:eu-west-1:123456789012:subnet/subnet-234",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-12345",
"State": "available",
"AvailabilityZone": "eu-west-1c",
"SubnetId": "subnet-234",
"OwnerId": "123456789012",
"CidrBlock": "172.31.16.0/20",
"AssignIpv6AddressOnCreation": false
},
{
"MapPublicIpOnLaunch": true,
"AvailabilityZoneId": "euw1-az3",
"AvailableIpAddressCount": 4090,
"DefaultForAz": true,
"SubnetArn": "arn:aws:ec2:eu-west-1:123456789012:subnet/subnet-345",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-12345",
"State": "available",
"AvailabilityZone": "eu-west-1a",
"SubnetId": "subnet-345",
"OwnerId": "123456789012",
"CidrBlock": "172.31.32.0/20",
"AssignIpv6AddressOnCreation": false
},
{
"MapPublicIpOnLaunch": true,
"AvailabilityZoneId": "euw1-az1",
"AvailableIpAddressCount": 4090,
"DefaultForAz": true,
"SubnetArn": "arn:aws:ec2:eu-west-1:123456789012:subnet/subnet-456",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-12345",
"State": "available",
"AvailabilityZone": "eu-west-1b",
"SubnetId": "subnet-456",
"OwnerId": "123456789012",
"CidrBlock": "172.31.0.0/20",
"AssignIpv6AddressOnCreation": false
}
]
}
Your setup has:
PRIVATE
subnet group composed of:subnet-123
in eu-west-1b
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.
I haven't tested this but is this also the case with regions with more than 3 AZs if I were to use only 3 of 5, for example? What will happen when a new AZ is added to a region? Also is the determination based solely on the MapPublicIpOnLaunch
property or is there further inspection of routing, gateways, NACLs, etc.?
At the moment, this is a bit of a hurdle when it comes to advocating CDK for use in large organizations.
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:
aws-cdk:subnet-type
tag on the subnet (value one of Public
, Private
, Isolated
), then it maps into that group.MapPublicIpOnLaunch
is true
, the subnet is part of the Public
groupPRIVATE
groupA 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.
Same issue - and i have all subnets across all az's. It seems it's either considering the data and the private subnets twoce, or re-considering the database subnet group.
Error message:
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-2b,ap-southeast-2b,ap-southeast-2c,ap-southeast-2c
Error: 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-2b,ap-southeast-2b,ap-southeast-2c,ap-southeast-2c
Subnet code:
# aws ec2 describe-subnets --filters "Name=vpcId,Values=vpc-xxxxxxxxxxxxxxxxxxx
{
"Subnets": [
{
"AvailabilityZone": "ap-southeast-2b",
"AvailabilityZoneId": "apse2-az1",
"AvailableIpAddressCount": 8185,
"CidrBlock": "10.0.32.0/19",
"DefaultForAz": false,
"MapPublicIpOnLaunch": false,
"State": "available",
"SubnetId": "xxxxxxxxxxxxxxxxxxx",
"VpcId": "vpc-xxxxxxxxxxxxxxxxxxx",
"OwnerId": "xxxxxxxxxxxxxxxxxxx",
"AssignIpv6AddressOnCreation": false,
"Ipv6CidrBlockAssociationSet": [],
"Tags": [
{
"Key": "Project",
"Value": "AWS LZ"
},
{
"Key": "Purpose",
"Value": "AWS LZ Private Subnet for AZ 2"
},
{
"Key": "aws:cloudformation:stack-id",
"Value": "arn:aws:cloudformation:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:stack/StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e/63ed59c0-ac3e-11e9-8b69-0accf194060a"
},
{
"Key": "aws:cloudformation:stack-name",
"Value": "StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e"
},
{
"Key": "Name",
"Value": "private-subnet-az2"
},
{
"Key": "aws:cloudformation:logical-id",
"Value": "PrivateSubnetAz2"
},
{
"Key": "AWS_Solutions",
"Value": "LandingZoneStackSet"
},
{
"Key": "Environment",
"Value": "AWS LZ"
}
],
"SubnetArn": "arn:aws:ec2:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:subnet/xxxxxxxxxxxxxxxxxxx"
},
{
"AvailabilityZone": "ap-southeast-2b",
"AvailabilityZoneId": "apse2-az1",
"AvailableIpAddressCount": 2042,
"CidrBlock": "10.0.200.0/21",
"DefaultForAz": false,
"MapPublicIpOnLaunch": false,
"State": "available",
"SubnetId": "xxxxxxxxxxxxxxxxxxx",
"VpcId": "vpc-xxxxxxxxxxxxxxxxxxx",
"OwnerId": "xxxxxxxxxxxxxxxxxxx",
"AssignIpv6AddressOnCreation": false,
"Ipv6CidrBlockAssociationSet": [],
"Tags": [
{
"Key": "Purpose",
"Value": "AWS LZ Data Subnet for AZ 2"
},
{
"Key": "Environment",
"Value": "AWS LZ"
},
{
"Key": "aws:cloudformation:logical-id",
"Value": "DataSubnetAz2"
},
{
"Key": "AWS_Solutions",
"Value": "LandingZoneStackSet"
},
{
"Key": "aws:cloudformation:stack-name",
"Value": "StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e"
},
{
"Key": "Name",
"Value": "data-subnet-az2"
},
{
"Key": "Project",
"Value": "AWS LZ"
},
{
"Key": "aws:cloudformation:stack-id",
"Value": "arn:aws:cloudformation:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:stack/StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e/63ed59c0-ac3e-11e9-8b69-0accf194060a"
}
],
"SubnetArn": "arn:aws:ec2:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:subnet/xxxxxxxxxxxxxxxxxxx"
},
{
"AvailabilityZone": "ap-southeast-2a",
"AvailabilityZoneId": "apse2-az3",
"AvailableIpAddressCount": 8187,
"CidrBlock": "10.0.0.0/19",
"DefaultForAz": false,
"MapPublicIpOnLaunch": false,
"State": "available",
"SubnetId": "xxxxxxxxxxxxxxxxxxx",
"VpcId": "vpc-xxxxxxxxxxxxxxxxxxx",
"OwnerId": "xxxxxxxxxxxxxxxxxxx",
"AssignIpv6AddressOnCreation": false,
"Ipv6CidrBlockAssociationSet": [],
"Tags": [
{
"Key": "Purpose",
"Value": "AWS LZ Private Subnet for AZ 1"
},
{
"Key": "aws:cloudformation:stack-name",
"Value": "StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e"
},
{
"Key": "AWS_Solutions",
"Value": "LandingZoneStackSet"
},
{
"Key": "aws:cloudformation:logical-id",
"Value": "PrivateSubnetAz1"
},
{
"Key": "Project",
"Value": "AWS LZ"
},
{
"Key": "aws:cloudformation:stack-id",
"Value": "arn:aws:cloudformation:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:stack/StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e/63ed59c0-ac3e-11e9-8b69-0accf194060a"
},
{
"Key": "Environment",
"Value": "AWS LZ"
},
{
"Key": "Name",
"Value": "private-subnet-az1"
}
],
"SubnetArn": "arn:aws:ec2:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:subnet/xxxxxxxxxxxxxxxxxxx"
},
{
"AvailabilityZone": "ap-southeast-2b",
"AvailabilityZoneId": "apse2-az1",
"AvailableIpAddressCount": 4090,
"CidrBlock": "10.0.144.0/20",
"DefaultForAz": false,
"MapPublicIpOnLaunch": true,
"State": "available",
"SubnetId": "xxxxxxxxxxxxxxxxxxx",
"VpcId": "vpc-xxxxxxxxxxxxxxxxxxx",
"OwnerId": "xxxxxxxxxxxxxxxxxxx",
"AssignIpv6AddressOnCreation": false,
"Ipv6CidrBlockAssociationSet": [],
"Tags": [
{
"Key": "Name",
"Value": "public-subnet-az2"
},
{
"Key": "Project",
"Value": "AWS LZ"
},
{
"Key": "aws:cloudformation:logical-id",
"Value": "PublicSubnetAz2"
},
{
"Key": "Purpose",
"Value": "AWS LZ Public Subnet for AZ 2"
},
{
"Key": "aws:cloudformation:stack-name",
"Value": "StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e"
},
{
"Key": "aws:cloudformation:stack-id",
"Value": "arn:aws:cloudformation:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:stack/StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e/63ed59c0-ac3e-11e9-8b69-0accf194060a"
},
{
"Key": "AWS_Solutions",
"Value": "LandingZoneStackSet"
},
{
"Key": "Environment",
"Value": "AWS LZ"
}
],
"SubnetArn": "arn:aws:ec2:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:subnet/xxxxxxxxxxxxxxxxxxx"
},
{
"AvailabilityZone": "ap-southeast-2c",
"AvailabilityZoneId": "apse2-az2",
"AvailableIpAddressCount": 2043,
"CidrBlock": "10.0.208.0/21",
"DefaultForAz": false,
"MapPublicIpOnLaunch": false,
"State": "available",
"SubnetId": "xxxxxxxxxxxxxxxxxxx",
"VpcId": "vpc-xxxxxxxxxxxxxxxxxxx",
"OwnerId": "xxxxxxxxxxxxxxxxxxx",
"AssignIpv6AddressOnCreation": false,
"Ipv6CidrBlockAssociationSet": [],
"Tags": [
{
"Key": "Name",
"Value": "data-subnet-az3"
},
{
"Key": "Purpose",
"Value": "AWS LZ Data Subnet for AZ 3"
},
{
"Key": "Environment",
"Value": "AWS LZ"
},
{
"Key": "AWS_Solutions",
"Value": "LandingZoneStackSet"
},
{
"Key": "aws:cloudformation:logical-id",
"Value": "DataSubnetAz3"
},
{
"Key": "Project",
"Value": "AWS LZ"
},
{
"Key": "aws:cloudformation:stack-id",
"Value": "arn:aws:cloudformation:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:stack/StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e/63ed59c0-ac3e-11e9-8b69-0accf194060a"
},
{
"Key": "aws:cloudformation:stack-name",
"Value": "StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e"
}
],
"SubnetArn": "arn:aws:ec2:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:subnet/xxxxxxxxxxxxxxxxxxx"
},
{
"AvailabilityZone": "ap-southeast-2c",
"AvailabilityZoneId": "apse2-az2",
"AvailableIpAddressCount": 4090,
"CidrBlock": "10.0.160.0/20",
"DefaultForAz": false,
"MapPublicIpOnLaunch": true,
"State": "available",
"SubnetId": "xxxxxxxxxxxxxxxxxxx",
"VpcId": "vpc-xxxxxxxxxxxxxxxxxxx",
"OwnerId": "xxxxxxxxxxxxxxxxxxx",
"AssignIpv6AddressOnCreation": false,
"Ipv6CidrBlockAssociationSet": [],
"Tags": [
{
"Key": "aws:cloudformation:stack-id",
"Value": "arn:aws:cloudformation:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:stack/StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e/63ed59c0-ac3e-11e9-8b69-0accf194060a"
},
{
"Key": "aws:cloudformation:stack-name",
"Value": "StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e"
},
{
"Key": "AWS_Solutions",
"Value": "LandingZoneStackSet"
},
{
"Key": "Purpose",
"Value": "AWS LZ Public Subnet for AZ 3"
},
{
"Key": "Project",
"Value": "AWS LZ"
},
{
"Key": "aws:cloudformation:logical-id",
"Value": "PublicSubnetAz3"
},
{
"Key": "Name",
"Value": "public-subnet-az3"
},
{
"Key": "Environment",
"Value": "AWS LZ"
}
],
"SubnetArn": "arn:aws:ec2:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:subnet/xxxxxxxxxxxxxxxxxxx"
},
{
"AvailabilityZone": "ap-southeast-2c",
"AvailabilityZoneId": "apse2-az2",
"AvailableIpAddressCount": 8187,
"CidrBlock": "10.0.64.0/19",
"DefaultForAz": false,
"MapPublicIpOnLaunch": false,
"State": "available",
"SubnetId": "xxxxxxxxxxxxxxxxxxx",
"VpcId": "vpc-xxxxxxxxxxxxxxxxxxx",
"OwnerId": "xxxxxxxxxxxxxxxxxxx",
"AssignIpv6AddressOnCreation": false,
"Ipv6CidrBlockAssociationSet": [],
"Tags": [
{
"Key": "Environment",
"Value": "AWS LZ"
},
{
"Key": "Project",
"Value": "AWS LZ"
},
{
"Key": "AWS_Solutions",
"Value": "LandingZoneStackSet"
},
{
"Key": "Purpose",
"Value": "AWS LZ Private Subnet for AZ 3"
},
{
"Key": "aws:cloudformation:logical-id",
"Value": "PrivateSubnetAz3"
},
{
"Key": "aws:cloudformation:stack-name",
"Value": "StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e"
},
{
"Key": "Name",
"Value": "private-subnet-az3"
},
{
"Key": "aws:cloudformation:stack-id",
"Value": "arn:aws:cloudformation:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:stack/StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e/63ed59c0-ac3e-11e9-8b69-0accf194060a"
}
],
"SubnetArn": "arn:aws:ec2:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:subnet/xxxxxxxxxxxxxxxxxxx"
},
{
"AvailabilityZone": "ap-southeast-2a",
"AvailabilityZoneId": "apse2-az3",
"AvailableIpAddressCount": 4088,
"CidrBlock": "10.0.128.0/20",
"DefaultForAz": false,
"MapPublicIpOnLaunch": true,
"State": "available",
"SubnetId": "xxxxxxxxxxxxxxxxxxx",
"VpcId": "vpc-xxxxxxxxxxxxxxxxxxx",
"OwnerId": "xxxxxxxxxxxxxxxxxxx",
"AssignIpv6AddressOnCreation": false,
"Ipv6CidrBlockAssociationSet": [],
"Tags": [
{
"Key": "Project",
"Value": "AWS LZ"
},
{
"Key": "Name",
"Value": "public-subnet-az1"
},
{
"Key": "aws:cloudformation:stack-name",
"Value": "StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e"
},
{
"Key": "aws:cloudformation:stack-id",
"Value": "arn:aws:cloudformation:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:stack/StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e/63ed59c0-ac3e-11e9-8b69-0accf194060a"
},
{
"Key": "AWS_Solutions",
"Value": "LandingZoneStackSet"
},
{
"Key": "Environment",
"Value": "AWS LZ"
},
{
"Key": "aws:cloudformation:logical-id",
"Value": "PublicSubnetAz1"
},
{
"Key": "Purpose",
"Value": "AWS LZ Public Subnet for AZ 1"
}
],
"SubnetArn": "arn:aws:ec2:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:subnet/xxxxxxxxxxxxxxxxxxx"
},
{
"AvailabilityZone": "ap-southeast-2a",
"AvailabilityZoneId": "apse2-az3",
"AvailableIpAddressCount": 2043,
"CidrBlock": "10.0.192.0/21",
"DefaultForAz": false,
"MapPublicIpOnLaunch": false,
"State": "available",
"SubnetId": "xxxxxxxxxxxxxxxxxxx",
"VpcId": "vpc-xxxxxxxxxxxxxxxxxxx",
"OwnerId": "xxxxxxxxxxxxxxxxxxx",
"AssignIpv6AddressOnCreation": false,
"Ipv6CidrBlockAssociationSet": [],
"Tags": [
{
"Key": "Name",
"Value": "data-subnet-az1"
},
{
"Key": "AWS_Solutions",
"Value": "LandingZoneStackSet"
},
{
"Key": "Environment",
"Value": "AWS LZ"
},
{
"Key": "aws:cloudformation:stack-name",
"Value": "StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e"
},
{
"Key": "Project",
"Value": "AWS LZ"
},
{
"Key": "aws:cloudformation:stack-id",
"Value": "arn:aws:cloudformation:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:stack/StackSet-AWS-Landing-Zone-Baseline-PrimaryVPC-e12d699b-c6e1-42a2-9087-bbac78b69b5e/63ed59c0-ac3e-11e9-8b69-0accf194060a"
},
{
"Key": "aws:cloudformation:logical-id",
"Value": "DataSubnetAz1"
},
{
"Key": "Purpose",
"Value": "AWS LZ Data Subnet for AZ 1"
}
],
"SubnetArn": "arn:aws:ec2:ap-southeast-2:xxxxxxxxxxxxxxxxxxx:subnet/xxxxxxxxxxxxxxxxxxx"
}
]
}
This is quite bad issue if you have "legacy" infra. We had to create the security group and it took some time to find out how to workaround this if I want to use (Python) aws_ec2.SecurityGroup class for security group. So here's the workaround how I manage to get proper looking SG:
''' As long as something is initialized to self.vpc_id this works.
That is not used anywhere, so it can be just '''
class TempVPC:
def __init__(self, vpc_id):
self.vpc_id = vpc_id
''' So let's initialize the SG '''
tempvpc = TempVpc('vpcid')
sg = ec2.SecurityGroup(self, "testsg",
vpc = tempvpc)
sg.node.children[0].vpc_id='vpc-realid'
So please - fix this to something less hack looking.
Seems that Route53 requires different kind of handling for VPC. I'm wondering if this is showstopper for us or should I just leave the legacy VPC to be legacy until this is fixed and then start to use it again.
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
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.
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?
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.
Your setup has:
1
PRIVATE
subnet group composed of:
subnet-123
ineu-west-1b
1
PUBLIC
subnet group composed of:
subnet-234
ineu-west-1c
subnet-345
ineu-west-1a
subnet-456
ineu-west-1b
Currently, the
Vpc
construct requires that all subnet groups cover the same list of availability zones. You are missing twoPRIVATE
subnets (ineu-west-1c
andeu-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
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.
I need to map my vpc in cdk to create a simple ALB.
Now we have 10 subnets split in 2 AZ: 6 public and 4 private.
based on your definition it should work.
Now I need only 2 subnet(not random). How can I do that?
In the ApplicationLoadBalancer construct I need to refer only two specific private subnet.
How? If I use the method from_lookup to get the IVPC I receive this error:
Error at /alb] Not all subnets in VPC have the same AZs: eu-west-1a,eu-west-1a,eu-west-1a,eu-west-1b,eu-west-1b,eu-west-1b vs eu-west-1a,eu-west-1a,eu-west-1b,eu-west-1b
{
"Subnets": [
{
"MapPublicIpOnLaunch": false,
"AvailabilityZoneId": "euw1-az2",
"Tags": [
{
"Value": "customer-mng-b-prv",
"Key": "Name"
}
],
"AvailableIpAddressCount": 45,
"DefaultForAz": false,
"SubnetArn": "arn:aws:ec2:eu-west-1:ACCOUNT:subnet/subnet-15819f63",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-a44d47c0",
"State": "available",
"AvailabilityZone": "eu-west-1b",
"SubnetId": "subnet-15819f63",
"OwnerId": "ACCOUNT",
"CidrBlock": "10.111.255.64/26",
"AssignIpv6AddressOnCreation": false
},
{
"MapPublicIpOnLaunch": true,
"AvailabilityZoneId": "euw1-az2",
"Tags": [
{
"Value": "customer-prod-b-fe-pub",
"Key": "Name"
}
],
"AvailableIpAddressCount": 107,
"DefaultForAz": false,
"SubnetArn": "arn:aws:ec2:eu-west-1:ACCOUNT:subnet/subnet-58e8f02e",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-a44d47c0",
"State": "available",
"AvailabilityZone": "eu-west-1b",
"SubnetId": "subnet-58e8f02e",
"OwnerId": "ACCOUNT",
"CidrBlock": "10.111.2.128/25",
"AssignIpv6AddressOnCreation": false
},
{
"MapPublicIpOnLaunch": false,
"AvailabilityZoneId": "euw1-az2",
"Tags": [
{
"Value": "customer-mng-b-pub",
"Key": "Name"
}
],
"AvailableIpAddressCount": 42,
"DefaultForAz": false,
"SubnetArn": "arn:aws:ec2:eu-west-1:ACCOUNT:subnet/subnet-46b1af30",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-a44d47c0",
"State": "available",
"AvailabilityZone": "eu-west-1b",
"SubnetId": "subnet-46b1af30",
"OwnerId": "ACCOUNT",
"CidrBlock": "10.111.255.192/26",
"AssignIpv6AddressOnCreation": false
},
{
"MapPublicIpOnLaunch": false,
"AvailabilityZoneId": "euw1-az1",
"Tags": [
{
"Value": "customer-mng-a-pub",
"Key": "Name"
}
],
"AvailableIpAddressCount": 42,
"DefaultForAz": false,
"SubnetArn": "arn:aws:ec2:eu-west-1:ACCOUNT:subnet/subnet-30a6b854",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-a44d47c0",
"State": "available",
"AvailabilityZone": "eu-west-1a",
"SubnetId": "subnet-30a6b854",
"OwnerId": "ACCOUNT",
"CidrBlock": "10.111.255.128/26",
"AssignIpv6AddressOnCreation": false
},
{
"MapPublicIpOnLaunch": false,
"AvailabilityZoneId": "euw1-az2",
"Tags": [
{
"Value": "customer-prod-b-prv",
"Key": "Name"
}
],
"AvailableIpAddressCount": 181,
"DefaultForAz": false,
"SubnetArn": "arn:aws:ec2:eu-west-1:ACCOUNT:subnet/subnet-02f7ef74",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-a44d47c0",
"State": "available",
"AvailabilityZone": "eu-west-1b",
"SubnetId": "subnet-02f7ef74",
"OwnerId": "ACCOUNT",
"CidrBlock": "10.111.1.0/24",
"AssignIpv6AddressOnCreation": false
},
{
"MapPublicIpOnLaunch": false,
"AvailabilityZoneId": "euw1-az1",
"Tags": [
{
"Value": "customer-mng-a-prv",
"Key": "Name"
}
],
"AvailableIpAddressCount": 48,
"DefaultForAz": false,
"SubnetArn": "arn:aws:ec2:eu-west-1:ACCOUNT:subnet/subnet-b7b7a9d3",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-a44d47c0",
"State": "available",
"AvailabilityZone": "eu-west-1a",
"SubnetId": "subnet-b7b7a9d3",
"OwnerId": "ACCOUNT",
"CidrBlock": "10.111.255.0/26",
"AssignIpv6AddressOnCreation": false
},
{
"MapPublicIpOnLaunch": false,
"AvailabilityZoneId": "euw1-az1",
"Tags": [
{
"Value": "customer-prod-a-prv",
"Key": "Name"
}
],
"AvailableIpAddressCount": 218,
"DefaultForAz": false,
"SubnetArn": "arn:aws:ec2:eu-west-1:ACCOUNT:subnet/subnet-c8c9d1ac",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-a44d47c0",
"State": "available",
"AvailabilityZone": "eu-west-1a",
"SubnetId": "subnet-c8c9d1ac",
"OwnerId": "ACCOUNT",
"CidrBlock": "10.111.0.0/24",
"AssignIpv6AddressOnCreation": false
},
{
"MapPublicIpOnLaunch": true,
"AvailabilityZoneId": "euw1-az2",
"Tags": [
{
"Value": "customer-prod-b-elb-pub",
"Key": "Name"
}
],
"AvailableIpAddressCount": 122,
"DefaultForAz": false,
"SubnetArn": "arn:aws:ec2:eu-west-1:ACCOUNT:subnet/subnet-a3e8f0d5",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-a44d47c0",
"State": "available",
"AvailabilityZone": "eu-west-1b",
"SubnetId": "subnet-a3e8f0d5",
"OwnerId": "ACCOUNT",
"CidrBlock": "10.111.3.128/25",
"AssignIpv6AddressOnCreation": false
},
{
"MapPublicIpOnLaunch": true,
"AvailabilityZoneId": "euw1-az1",
"Tags": [
{
"Value": "customer-prod-a-fe-pub",
"Key": "Name"
}
],
"AvailableIpAddressCount": 112,
"DefaultForAz": false,
"SubnetArn": "arn:aws:ec2:eu-west-1:ACCOUNT:subnet/subnet-73cad217",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-a44d47c0",
"State": "available",
"AvailabilityZone": "eu-west-1a",
"SubnetId": "subnet-73cad217",
"OwnerId": "ACCOUNT",
"CidrBlock": "10.111.2.0/25",
"AssignIpv6AddressOnCreation": false
},
{
"MapPublicIpOnLaunch": true,
"AvailabilityZoneId": "euw1-az1",
"Tags": [
{
"Value": "customer-prod-a-elb-pub",
"Key": "Name"
}
],
"AvailableIpAddressCount": 122,
"DefaultForAz": false,
"SubnetArn": "arn:aws:ec2:eu-west-1:ACCOUNT:subnet/subnet-81cad2e5",
"Ipv6CidrBlockAssociationSet": [],
"VpcId": "vpc-a44d47c0",
"State": "available",
"AvailabilityZone": "eu-west-1a",
"SubnetId": "subnet-81cad2e5",
"OwnerId": "ACCOUNT",
"CidrBlock": "10.111.3.0/25",
"AssignIpv6AddressOnCreation": false
}
]
}
this is the piece of code.
alb = elbv2.ApplicationLoadBalancer(
self, "LB",
vpc=vpc,
internet_facing=False,
load_balancer_name="my_alb",
vpc_subnets=ec2.SubnetSelection(one_per_az=True, subnet_type=ec2.SubnetType.PRIVATE))
@joemcclane85 i cannot see the subnet tags set on your subnets as per this entire thread. you need PUBLIC, PRIVATE and ISOLATED tags on non-CDK generated subnets.
If you generate via CDK then the subnets come tagged automatically.
@joemcclane85 i cannot see the subnet tags set on your subnets as per this entire thread. you need PUBLIC, PRIVATE and ISOLATED tags on non-CDK generated subnets.
If you generate via CDK then the subnets come tagged automatically.
@reeseyc ok, but How Can I use only the customer-prod-a-prv and the customer-prod-b-prv?
Which tags do I 've to use? instead to use subnet_type in the ApplicationLoadBalancer construct I need to use sub_net_group_name, but what values do I've to use? Do I need to use some tags?
I've to tag with aws-cdk:subnet-type: Public/Private and then
aws-cdk:subnet-name: $name
in my code then I selected the subnets by name
and it works.
You should update the documentation to say: if you use an existing VPC you must tag every single subnet with aws-cdk:subnet-type: 'Public' or 'Private' and aws-cdk:subnet-name: something
We should make the following changes:
Changes to the VPC context provider and potentially the CX protocol should derive from these.
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.
Most helpful comment
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