Aws-cdk: Consider providing CIDR in IVpc

Created on 10 Apr 2019  Â·  16Comments  Â·  Source: aws/aws-cdk

Currently, there's no easy way to get the CIDR of a VPC from IVpc interface although the Vpc implementation does via getCidr(). Please consider pulling up getCidr() to the interface.

_NOTE: Structure out of date. Request still valid_

@aws-cdaws-ec2 efforsmall feature-request p2

Most helpful comment

Any progress on this? Actually I often end-up wanting to write something like this:

let sg: SecurityGroup = ...
let vpc = Vpc.fromLookup(this, '...', { tags: { "mytag": "my-value"}} )
for ( let subnet of vpc.privateSubnets ){
      sg.addIngressRule(subnet, new TcpPort(443), 'Allow inbound HTTPS traffic from private subnet')
}

However, not being able to obtain the CIDR(s) of imported IVpc respectively ISubnet makes this impossible. Vpc.fromLookup(this, '...', { tags: { "mytag": "my-value"}} ) implies that we have to lookup facts (attributes like VpcId, ...) using AWS API anyway, so we could as well lookup the CIDR ranges.

All 16 comments

Seems straightforward enough - this would require we add CIDR to the exports and require users to know the CIDR when importing a VPC defined outside of the CDK. Anyone see a problem with this?

Hi @digitalsanctum, we can surely add it but I'm curious what you'd want to use the CDIR for.

For my particular case, it's for security groups that refer to the CIDR of the VPC. Relates to #2211

@sam-goodwin is there a way to make this change without the added hassle of a user knowing the CIDR when importing?

Not that I can see, since IVpcNetwork will now expose the CIDR and an imported VPC must implement IVpcNetwork, there will be no way to import a VPC without knowing the CIDR. I don't think this is necessarily a big deal but it is a pain. Perhaps we could do something with context providers to extract the information from the account, but I'm not sure.

I had started making the changes for this issue and I see what you mean.

On Fri, Apr 12, 2019 at 8:30 AM Sam Goodwin notifications@github.com
wrote:

Not that I can see, since IVpcNetwork will now expose the CIDR and an
imported VPC must implement IVpcNetwork, there will be no way to import a
VPC without knowing the CIDR. I don't think this is necessarily a big deal
but it is a pain. Perhaps we could do something with context providers to
extract the information from the account, but I'm not sure.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/awslabs/aws-cdk/issues/2232#issuecomment-482618191,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAB4y5zLa-85FB3IMkASQCoH5uGGU46aks5vgKZ-gaJpZM4cnzrt
.

--
-Shane

Any progress on this? Actually I often end-up wanting to write something like this:

let sg: SecurityGroup = ...
let vpc = Vpc.fromLookup(this, '...', { tags: { "mytag": "my-value"}} )
for ( let subnet of vpc.privateSubnets ){
      sg.addIngressRule(subnet, new TcpPort(443), 'Allow inbound HTTPS traffic from private subnet')
}

However, not being able to obtain the CIDR(s) of imported IVpc respectively ISubnet makes this impossible. Vpc.fromLookup(this, '...', { tags: { "mytag": "my-value"}} ) implies that we have to lookup facts (attributes like VpcId, ...) using AWS API anyway, so we could as well lookup the CIDR ranges.

_Updated title and initial request to reflect changes in VPC structure since initial posting.
We havent forgotten about you!_
😸

Ye I am also wondering if its possible to retrieve the cidr block for a given subnet, so that you can add security groups based on the IPeer with that ipv4 address. How would you achieve this with the CDK today?

Ye I am also wondering if its possible to retrieve the cidr block for a given subnet, so that you can add security groups based on the IPeer with that ipv4 address. How would you achieve this with the CDK today?

I'm very interested in this as well. I may simply be missing the standard way to look up data in an existing infrastructure.

Ye I am also wondering if its possible to retrieve the cidr block for a given subnet, so that you can add security groups based on the IPeer with that ipv4 address. How would you achieve this with the CDK today?

I'm very interested in this as well. I may simply be missing the standard way to look up data in an existing infrastructure.

What you can do apparently is to use the low level classes instead.
So something like this:

vpc.privateSubnets.forEach(subnet => {
            const defaultChild = subnet.node.defaultChild as CfnSubnet;
            console.log(defaultChild.cidrBlock);
        });

However I´ve noticed that the defaultChild property is not set when you for instance is looking up a subnet, but if you create the VPC and its subnets it works.

However I´ve noticed that the defaultChild property is not set when you for instance is looking up a subnet, but if you create the VPC and its subnets it works.

Which brings me back to my point: I may be missing how looking up information for existing infrastructure works.

It's pretty easy to get yourself in a situation where the VPC and SubNets are given and non-negotiably out of your control (corp delivers those things with a VPN endpoint back to on-prem and don't want anybody messing with it).

aws-cli has the entire set of describe-* functions and terraform has data resources for pretty much everything.

I'm sure that CDK must have something similar.

Ye I am also wondering if its possible to retrieve the cidr block for a given subnet, so that you can add security groups based on the IPeer with that ipv4 address. How would you achieve this with the CDK today?

I've managed to handle my lookup problems using a custom resource and a standard CloudFormation trick for looking up parameters.

It's not pretty.

I've run into the same problem today and found a way around it.

Instead of trying to manage access rules based on CIDR blocks you can dynamically manage access rules based on security groups.

From the aws_cdk.aws_ec2-1.19.0.dist-info package metadata:

Any object that has a security group can itself be used as a connection peer:

  • use => connections.allow_to()

Here's some sample code:

    # Create Jumphost

    jumphost = ec2.Instance(self, 'jumphost',
                            instance_type=ec2.InstanceType('t3a.small'),
                            machine_image=jumphost_image,
                            vpc=fargate_vpc,
                            key_name='xxxx',
                            vpc_subnets=jumphost_subnet_selection,)

    jumphost.connections.security_groups[0].add_ingress_rule(
        peer=ec2.Peer.ipv4('0.0.0.0/0'),
        connection=ec2.Port.tcp(3389),
        description='Inbound RDP traffic'
    )


    # Create Domain Management Server

    domain_manager = ec2.Instance(self, 'domain-manager',
                                  instance_type=ec2.InstanceType('t3a.micro'),
                                  machine_image=domain_manager_image,
                                  vpc=fargate_vpc,
                                  key_name='xxxx',
                                  vpc_subnets=domain_manager_subnet_selection)

    jumphost.connections.allow_to(domain_manager, ec2.Port.tcp(3389), 'Allow RDP Access from the jumphost to the domain manager server')

I want to deploy an RDS instance and grant the private subnets of its VPC ingress to the RDS instance. The VPC is defined in a completely separate CDK application/stack, shared as an NPM module. That application/module exposes a "Lookups" class which uses an SSM parameter sharing the same base logical name with the "child" project, to then create and return an IVpc to other CDK applications. I really don't want to hard code the CIDRs into other CDK applications that are dependent on the VPC. Looking up the CIDR of a subnet seems like a pretty critical thing to be able to do.

In the meantime, I may wind up having to have the VPC application store the subnet values in a JSON string stored in an SSM string parameter, seems like overkill to have to do though.

The problem with the SSM paramter workaround is that you get back dummy values during a diff so now my diff is not necessarily accurate.

    private _getSubnetAttributesJSON() {
        const value = StringParameter.valueFromLookup(this._properties.stack, `${this._basePropertyPath}subnets`);
        if (value.startsWith('dummy-')) {
            // During diff, a dummy value is returned that will not JSON parse.  We have to provide a dummy value.
            return JSON.stringify({
                'publicSubnets': [{
                    'availabilityZone': 'us-east-1a',
                    'ipv4CidrBlock': '10.54.0.0/23',
                    'routeTableId': 'rtb-02d6dcdbac29b4f72',
                    'subnetId': 'subnet-0b2d15193afb11de0'
                }, {
                    'availabilityZone': 'us-east-1b',
                    'ipv4CidrBlock': '10.54.2.0/23',
                    'routeTableId': 'rtb-0709dd52314764acb',
                    'subnetId': 'subnet-05b737332f69c626f'
                }],
                'privateSubnets': [{
                    'availabilityZone': 'us-east-1a',
                    'ipv4CidrBlock': '10.54.4.0/23',
                    'routeTableId': 'rtb-082b7e8ccfae3ab04',
                    'subnetId': 'subnet-07f5692e4a17572ed'
                }, {
                    'availabilityZone': 'us-east-1b',
                    'ipv4CidrBlock': '10.54.6.0/23',
                    'routeTableId': 'rtb-0d77be05ccb385f78',
                    'subnetId': 'subnet-012bce75cce77dfb7'
                }],
                'isolatedSubnets': []
            });
        }
        return value;
    }
Was this page helpful?
0 / 5 - 0 ratings

Related issues

cybergoof picture cybergoof  Â·  3Comments

kawamoto picture kawamoto  Â·  3Comments

pepastach picture pepastach  Â·  3Comments

ababra picture ababra  Â·  3Comments

abelmokadem picture abelmokadem  Â·  3Comments