Aws-cdk: VpcPlacement: allow picking subset of subnets

Created on 20 Jan 2019  ยท  4Comments  ยท  Source: aws/aws-cdk

Is there a way to control which subnets are used by the ApplicationLoadBalancer from the provided vpc?

I have a vpc defined outside of CDK which has many private subnets, I would like to place the AmazonElasticLoadBalancingV2 into two of the private subnets. Because the vpc has more than two private subnets I'm getting this error while deploying.

A load balancer cannot be attached to multiple subnets in the same Availability Zone (Service: AmazonElasticLoadBalancingV2; Status Code: 400; Error Code: InvalidConfigurationRequest; Request ID: 11cbe7e5-1c83-11e9-8fee-272af54085c6

Here's the relevant code

import ec2 = require('@aws-cdk/aws-ec2');
import alb = require('@aws-cdk/aws-elasticloadbalancingv2');

<snip>

const vpc = ec2.VpcNetwork.importFromContext(this, 'vpc', {
      vpcName: "vpc-name"
});

 var lb = new alb.ApplicationLoadBalancer(this, "alb", {
    vpc: vpc,
    internetFacing: false,
})

I see vpcPlacement on BaseLoadBalancerProps but I don't believe its flexible enough for my needs. It can only select all private subnets or a single subnet.

@aws-cdaws-ec2 feature-request

Most helpful comment

If you have more than 1 type of private subnet, you can give each of them a name, and then select by that name

Is it possible to give them a name when using ec2.VpcNetwork.importFromContext? The subnets have the tag Name on them, but I don't know how to use that from the cdk. (These subnets were created outside the cdk, so there are no aws-cdk tags on them)

whether you want (for example) to only place in 2 out of 3 AZs (and what the use case for that would be).

Yes this is the case. I would like to place in a subset of the AZs because there are specific AZs where we are running ECS cluster. Our VPC initially started with only 2 AZs but was expanded some time ago to cover 5 AZs, but this ECS cluster is still running in the original subset of two AZs.

So I think I have two separate issues.

  1. I have many private subnets in the same AZ, but no way to group them
  2. I only want to place in 2 (out of 5) AZs, but no way to filter them

I was able to work around this particular issue by using import instead of importFromContext but this seems less than ideal, since I know need to hardcode my network information.

const vpc = ec2.VpcNetwork.import(this, 'vpc', {
    vpcId: "vpc-123",
    availabilityZones: ['us-east-1a', 'us-east-1b'],
    privateSubnetIds: ['subnet-1', 'subnet-2']
});

All 4 comments

Can you explain the situation a bit more?

If you have more than 1 type of private subnet, you can give each of them a name, and then select by that name. I'm unsure whether this solves your question, or whether you want (for example) to only place in 2 out of 3 AZs (and what the use case for that would be).

In other words, from a set of 2 private subnets in 3 availability zones, are you trying to select this:

             co-rg-1a     co-rg-1b     co-rg-1c   
          โ”Œ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”ฌ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ 
                       โ”‚                         โ”‚
Private1  โ”‚                         โ”‚             
                       โ”‚                         โ”‚
          โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฌโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
          โ•‘            โ”‚                         โ•‘
Private2  โ•‘                         โ”‚            โ•‘
          โ•‘            โ”‚                         โ•‘
          โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฉโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Or this:

             co-rg-1a     co-rg-1b     co-rg-1c   
          โ”Œ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”ฌ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ 
                       โ”‚                         โ”‚
Private1  โ”‚                         โ”‚             
                       โ”‚                         โ”‚
          โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฌ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ 
          โ•‘            โ”‚            โ•‘            โ”‚
Private2  โ•‘                         โ•‘             
          โ•‘            โ”‚            โ•‘            โ”‚
          โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฉ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ 

?

The former is currently supported (by selecting based on "name"), the latter is not.

If you have more than 1 type of private subnet, you can give each of them a name, and then select by that name

Is it possible to give them a name when using ec2.VpcNetwork.importFromContext? The subnets have the tag Name on them, but I don't know how to use that from the cdk. (These subnets were created outside the cdk, so there are no aws-cdk tags on them)

whether you want (for example) to only place in 2 out of 3 AZs (and what the use case for that would be).

Yes this is the case. I would like to place in a subset of the AZs because there are specific AZs where we are running ECS cluster. Our VPC initially started with only 2 AZs but was expanded some time ago to cover 5 AZs, but this ECS cluster is still running in the original subset of two AZs.

So I think I have two separate issues.

  1. I have many private subnets in the same AZ, but no way to group them
  2. I only want to place in 2 (out of 5) AZs, but no way to filter them

I was able to work around this particular issue by using import instead of importFromContext but this seems less than ideal, since I know need to hardcode my network information.

const vpc = ec2.VpcNetwork.import(this, 'vpc', {
    vpcId: "vpc-123",
    availabilityZones: ['us-east-1a', 'us-east-1b'],
    privateSubnetIds: ['subnet-1', 'subnet-2']
});

@chris-smith-zocdoc - can you share the tags on your subnets?

I'm thinking if you look at the code in the context provider for VPC, you should be able to add a couple of tags and make this work. (I'm looking here https://github.com/awslabs/aws-cdk/blob/master/packages/aws-cdk/lib/context-providers/vpcs.ts#L58-L82)

So what I might try, and I haven't done this, is adding a tag like aws-cdk:subnet-name with the value ecs-private-subnet-1 and aws-cdk:subnet-type with the value private. Now the context import and placement has a chance.

@rix0rrr - is there a reason this shouldn't work? I'm not sure how we feel about asking existing VPC users to add tags to support our import?

Resolved recently.

Was this page helpful?
0 / 5 - 0 ratings