/* I was curious as to whether it was possible to make resources created using CDK constructs work with raw CloudFormation resources and vice versa. This aws-cdk app demonstrates a VPC and an ELB that belongs to it in different, dependant stacks, leveraging CFN outputs / imports, and leveraging CDK's method of passing information from one stack to another. */ import cdk = require("@aws-cdk/cdk"); import ec2 = require("@aws-cdk/aws-ec2"); import elb = require("@aws-cdk/aws-elasticloadbalancing"); interface ElbProps { vpc: ec2.VpcNetworkRefProps; } // A VPC made using CDK constructs class VpcDemoStack extends cdk.Stack { public readonly vpcRef: ec2.VpcNetworkRefProps; constructor(parent: cdk.App, id: string, props?: cdk.StackProps) { super(parent, id, props); const vpc = new ec2.VpcNetwork(this, "DemoVPC"); this.vpcRef = vpc.export(); } } // A VPC made using Cloudformation primitives - much simpler than // what the CDK construct would produce, but enough for a demonstration. class VpcCFNDemoStack extends cdk.Stack { public readonly vpcRef: ec2.VpcNetworkRefProps; constructor(parent: cdk.App, id: string, props?: cdk.StackProps) { super(parent, id, props); const vpc = new ec2.cloudformation.VPCResource(this, "DemoCFNVPC", { cidrBlock: "10.0.0.0/16" }); const publicSubnet = new ec2.cloudformation.SubnetResource( this, "DemoCFNSubnet1", { cidrBlock: "10.0.54.0/24", availabilityZone: "us-east-1a", vpcId: vpc.ref } ); const privateSubnet = new ec2.cloudformation.SubnetResource( this, "DemoCFNSubnet2", { cidrBlock: "10.0.55.0/24", availabilityZone: "us-east-1a", vpcId: vpc.ref } ); // This is the exact same data type as what our CDK-based // VPC is exporting - we're just populating it manually! const vpcProps = { vpcId: vpc.ref, availabilityZones: ["us-east-1a"], publicSubnetIds: [publicSubnet.ref], privateSubnetIds: [privateSubnet.ref] }; this.vpcRef = ec2.VpcNetworkRef.import( this, "ExternalVPC", vpcProps ).export(); } } // A Load Balancer made using a CDK construct class ElbDemoStack extends cdk.Stack { constructor(parent: cdk.App, id: string, props: ElbProps) { super(parent, id); const vpc = ec2.VpcNetworkRef.import(this, "ExternalVPC", props.vpc); new ec2.ClassicLoadBalancer(this, "DemoELB", { vpc, listeners: [{ externalPort: 80 }] }); } } // A Load Balancer made using Cloudformation primitives class ElbCFNDemoStack extends cdk.Stack { constructor(parent: cdk.App, id: string, props: ElbProps) { super(parent, id); const vpc = ec2.VpcNetworkRef.import(this, "ExternalVPC", props.vpc); new elb.cloudformation.LoadBalancerResource(this, "DemoELBCFN", { subnets: vpc.privateSubnets.map(s => s.subnetId), scheme: "internal", listeners: [ { loadBalancerPort: "80", protocol: "HTTP", instancePort: "80", instanceProtocol: "HTTP" } ] }); } } class MyApp extends cdk.App { constructor(argv: string[]) { super(argv); const cdkVpcStack = new VpcDemoStack(this, "vpc-demo"); const cloudformationVpcStack = new VpcCFNDemoStack(this, "vpc-cfn-demo"); /* Demonstrate creating a VPC using a CDK construct and then using it with a CFK construct load balancer and a CloudFormation primitive load balancer */ new ElbDemoStack(this, "cdk-vpc-to-cdk-elb-demo", { vpc: cdkVpcStack.vpcRef }); new ElbCFNDemoStack(this, "cdk-vpc-to-cfn-elb-demo", { vpc: cdkVpcStack.vpcRef }); /* Demonstrate creating a VPC using Cloudformation primitives and then using it with a CDK construct and a Cloudformation primitive respectively */ new ElbDemoStack(this, "cfn-vpc-to-cdk-elb-demo", { vpc: cloudformationVpcStack.vpcRef }); new ElbCFNDemoStack(this, "cfn-vpc-to-cfn-elb-demo", { vpc: cloudformationVpcStack.vpcRef }); } } process.stdout.write(new MyApp(process.argv).run());