Search code examples
typescriptaws-cdkamazon-vpc

Is it possible to convert an L1 VPC (CfnVpc) to an L2 Vpc (IVpc)


Due to severe limitations of the Vpc construct, we've had to change our code to use CfnVpc so not to have to destroy the VPC when we add or remove subnets.

This has proven to be very problematic...

The primary issue is that a lot of constructs expect an IVpc when creating them BastionHostLinux is an example.

error TS2322: Type 'CfnVPC' is not assignable to type 'Vpc | IVpc'

When using the CfnVpc, I need to do this is a separate stack and them import it using a loopup in the new stack. This isn't a problem moving forward but all legacy deployments cannot be updated to work with the new code (100's of them).

I am currently trying to figure out a way to get the CfnVpc to convert to an IVpc but this has been a bit of a problem for me.

There is a ticket on GitHub already for this: https://github.com/aws/aws-cdk/issues/14809

Skinny85 responded that this is how you could accomplish this:

const cfnInclude = new cfn_inc.CfnInclude(this, 'VpcTemplate’,
    templateFile: ‘vpc-template.yaml',
});

const cfnVpc = cfnInclude.getResource('VPC') as ec2.CfnVPC;
const privateSubnet1 = cfnInclude.getResource('PrivateSubnet1') as ec2.CfnSubnet;
const privateSubnet2 = cfnInclude.getResource('PrivateSubnet2') as ec2.CfnSubnet;
const cfnRouteTable1 = cfnInclude.getResource('PrivateRouteTable1') as ec2.CfnRouteTable;
const cfnRouteTable2 = cfnInclude.getResource('PrivateRouteTable2') as ec2.CfnRouteTable;

const vpc = ec2.Vpc.fromVpcAttributes(this, ‘ImportedVpc', {
    vpcId: cfnVpc.ref,
    availabilityZones: cdk.Fn.getAzs(),
    privateSubnetIds: [privateSubnetl.ref, privateSubnet2.ref],
    privateSubnetRouteTableIds: [cfnRouteTablel.ref, cfnRouteTable2.ref],
});

The issue with this is that he is importing an CloudFormation template file.

I asked him about this but he responded:

It shouldn't matter where the CfnVPC is coming from - the same principle applies.

Ok, so he's saying it is possible but didn't clarify how:

const privateSubnet1 = cfnInclude.getResource('PrivateSubnet1') as ec2.CfnSubnet;
const privateSubnet2 = cfnInclude.getResource('PrivateSubnet2') as ec2.CfnSubnet;
const cfnRouteTable1 = cfnInclude.getResource('PrivateRouteTable1') as ec2.CfnRouteTable;
const cfnRouteTable2 = cfnInclude.getResource('PrivateRouteTable2') as ec2.CfnRouteTable;

Can be done with CfnVpc.

I have tried looking into using the node from my CfnVpc and I can see some of the data necessary like subnets but I am unable to get it to work with Typescript.

e.g. this.vpc.node.scope?.publicSubnets is just giving me an error saying publicSubnets are not part of IConstruct.

I haven't messed with Typescript for a year so I am a little rusty. I am not able to even get that to work.

Has anyone been able to get this to work? Am I missing something really simple that I am overlooking?

Any assistance on this is appreciated. Thanks


Solution

  • CfnVpc does not create any subnets - those are created with CfnSubnet. So you don't have to use cfnInclude, just use the CfnSubnet objects you created.