From 15b255ca2093975c19e2bc05a0551e781e086514 Mon Sep 17 00:00:00 2001 From: Clare Liguori Date: Tue, 13 Nov 2018 08:07:21 -0800 Subject: [PATCH] fix(aws-ec2): add dependency on gateway attachment for public routes (#1142) Currently there is a race condition when creating the public subnet routes for the ec2.VpcNetwork construct. CloudFormation can attempt to create the public subnet routes to the IGW before the IGW is attached to the VPC. This change adds a dependency to the public routes on the IGW attachment. Fixes #1140. BREAKING CHANGE: Method signature of VpcPublicSubnet.addDefaultIGWRouteEntry changed in order to add a dependency on gateway attachment completing before creating the public route to the gateway. Instead of passing a gateway ID string, pass in a cloudformation.InternetGatewayResource object and a cloudformation.VPCGatewayAttachmentResource object. --- .../test/integ.amazonlinux2.expected.json | 8 ++++++- ...g.asg-w-classic-loadbalancer.expected.json | 9 +++++++ .../test/integ.asg-w-elbv2.expected.json | 6 +++++ .../test/integ.deployment-group.expected.json | 9 +++++++ packages/@aws-cdk/aws-ec2/lib/vpc.ts | 24 +++++++++++++------ .../aws-ec2/test/integ.vpc.expected.json | 9 +++++++ .../test/ec2/integ.lb-awsvpc-nw.expected.json | 8 ++++++- .../test/ec2/integ.lb-bridge-nw.expected.json | 8 ++++++- .../fargate/integ.asset-image.expected.json | 8 ++++++- .../fargate/integ.lb-awsvpc-nw.expected.json | 8 ++++++- .../test/integ.elb.expected.json | 3 +++ .../test/integ.alb-alias-target.expected.json | 6 +++++ .../test/integ.alb.expected.json | 6 +++++ .../test/integ.nlb.expected.json | 8 ++++++- .../test/integ.vpc-lambda.expected.json | 6 +++++ .../aws-rds/test/integ.cluster.expected.json | 6 +++++ .../test/integ.route53.expected.json | 11 ++++++++- 17 files changed, 129 insertions(+), 14 deletions(-) diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.expected.json b/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.expected.json index 2cea5b897dfec..75177d33e0f5a 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.expected.json +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.expected.json @@ -59,6 +59,9 @@ }, "VPCPublicSubnet1DefaultRoute91CEF279": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet1RouteTableFEE4B781" @@ -139,6 +142,9 @@ }, "VPCPublicSubnet2DefaultRouteB7481BBA": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" @@ -411,4 +417,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.expected.json b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.expected.json index 0ca90cc9a329f..9a0f6425887fe 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.expected.json +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.expected.json @@ -85,6 +85,9 @@ }, "VPCPublicSubnet1DefaultRoute91CEF279": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet1RouteTableFEE4B781" @@ -165,6 +168,9 @@ }, "VPCPublicSubnet2DefaultRouteB7481BBA": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" @@ -245,6 +251,9 @@ }, "VPCPublicSubnet3DefaultRouteA0D29D46": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet3RouteTable98AE0E14" diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.expected.json b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.expected.json index 167f41eed8cac..d229da238d349 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.expected.json +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.expected.json @@ -85,6 +85,9 @@ }, "VPCPublicSubnet1DefaultRoute91CEF279": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet1RouteTableFEE4B781" @@ -165,6 +168,9 @@ }, "VPCPublicSubnet2DefaultRouteB7481BBA": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" diff --git a/packages/@aws-cdk/aws-codedeploy/test/integ.deployment-group.expected.json b/packages/@aws-cdk/aws-codedeploy/test/integ.deployment-group.expected.json index 3cb6c923102c3..14423dcc00eb4 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/integ.deployment-group.expected.json +++ b/packages/@aws-cdk/aws-codedeploy/test/integ.deployment-group.expected.json @@ -59,6 +59,9 @@ }, "VPCPublicSubnet1DefaultRoute91CEF279": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet1RouteTableFEE4B781" @@ -139,6 +142,9 @@ }, "VPCPublicSubnet2DefaultRouteB7481BBA": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" @@ -219,6 +225,9 @@ }, "VPCPublicSubnet3DefaultRouteA0D29D46": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet3RouteTable98AE0E14" diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index 41bc9b97bcfdc..dc09030a08006 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -319,7 +319,7 @@ export class VpcNetwork extends VpcNetworkRef implements cdk.ITaggable { this.dependencyElements.push(igw, att); (this.publicSubnets as VpcPublicSubnet[]).forEach(publicSubnet => { - publicSubnet.addDefaultIGWRouteEntry(igw.ref); + publicSubnet.addDefaultIGWRouteEntry(igw, att); }); // if gateways are needed create them @@ -520,12 +520,19 @@ export class VpcSubnet extends VpcSubnetRef implements cdk.ITaggable { }); } - protected addDefaultRouteToIGW(gatewayId: string) { - new cloudformation.RouteResource(this, `DefaultRoute`, { + /** + * Create a default route that points to a passed IGW, with a dependency + * on the IGW's attachment to the VPC. + */ + protected addDefaultRouteToIGW( + gateway: cloudformation.InternetGatewayResource, + gatewayAttachment: cloudformation.VPCGatewayAttachmentResource) { + const route = new cloudformation.RouteResource(this, `DefaultRoute`, { routeTableId: this.routeTableId, destinationCidrBlock: '0.0.0.0/0', - gatewayId + gatewayId: gateway.ref }); + route.addDependency(gatewayAttachment); } } @@ -538,10 +545,13 @@ export class VpcPublicSubnet extends VpcSubnet { } /** - * Create a default route that points to a passed IGW + * Create a default route that points to a passed IGW, with a dependency + * on the IGW's attachment to the VPC. */ - public addDefaultIGWRouteEntry(gatewayId: string) { - this.addDefaultRouteToIGW(gatewayId); + public addDefaultIGWRouteEntry( + gateway: cloudformation.InternetGatewayResource, + gatewayAttachment: cloudformation.VPCGatewayAttachmentResource) { + this.addDefaultRouteToIGW(gateway, gatewayAttachment); } /** diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc.expected.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc.expected.json index 3df9527a9028f..6699c85efbb48 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc.expected.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc.expected.json @@ -85,6 +85,9 @@ }, "MyVpcPublicSubnet1DefaultRoute95FDF9EB": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "MyVpcVPCGW488ACE0D" + ], "Properties": { "RouteTableId": { "Ref": "MyVpcPublicSubnet1RouteTableC46AB2F4" @@ -165,6 +168,9 @@ }, "MyVpcPublicSubnet2DefaultRoute052936F6": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "MyVpcVPCGW488ACE0D" + ], "Properties": { "RouteTableId": { "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" @@ -245,6 +251,9 @@ }, "MyVpcPublicSubnet3DefaultRoute3A83AB36": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "MyVpcVPCGW488ACE0D" + ], "Properties": { "RouteTableId": { "Ref": "MyVpcPublicSubnet3RouteTable15028F08" diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.expected.json index c655174233d6e..056c03d04281d 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.expected.json @@ -59,6 +59,9 @@ }, "VpcPublicSubnet1DefaultRoute3DA9E72A": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VpcVPCGWBF912B6E" + ], "Properties": { "RouteTableId": { "Ref": "VpcPublicSubnet1RouteTable6C95E38E" @@ -139,6 +142,9 @@ }, "VpcPublicSubnet2DefaultRoute97F91067": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VpcVPCGWBF912B6E" + ], "Properties": { "RouteTableId": { "Ref": "VpcPublicSubnet2RouteTable94F7E489" @@ -722,4 +728,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.expected.json index 7e26702951204..a49def3f4b680 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.expected.json @@ -59,6 +59,9 @@ }, "VpcPublicSubnet1DefaultRoute3DA9E72A": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VpcVPCGWBF912B6E" + ], "Properties": { "RouteTableId": { "Ref": "VpcPublicSubnet1RouteTable6C95E38E" @@ -139,6 +142,9 @@ }, "VpcPublicSubnet2DefaultRoute97F91067": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VpcVPCGWBF912B6E" + ], "Properties": { "RouteTableId": { "Ref": "VpcPublicSubnet2RouteTable94F7E489" @@ -685,4 +691,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-ecs/test/fargate/integ.asset-image.expected.json b/packages/@aws-cdk/aws-ecs/test/fargate/integ.asset-image.expected.json index 083b5b9ba3d22..fb0ae46ef8f3d 100644 --- a/packages/@aws-cdk/aws-ecs/test/fargate/integ.asset-image.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/fargate/integ.asset-image.expected.json @@ -59,6 +59,9 @@ }, "VpcPublicSubnet1DefaultRoute3DA9E72A": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VpcVPCGWBF912B6E" + ], "Properties": { "RouteTableId": { "Ref": "VpcPublicSubnet1RouteTable6C95E38E" @@ -139,6 +142,9 @@ }, "VpcPublicSubnet2DefaultRoute97F91067": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VpcVPCGWBF912B6E" + ], "Properties": { "RouteTableId": { "Ref": "VpcPublicSubnet2RouteTable94F7E489" @@ -801,4 +807,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.expected.json b/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.expected.json index d4f7ba85f8c29..039f526419214 100644 --- a/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.expected.json @@ -59,6 +59,9 @@ }, "VpcPublicSubnet1DefaultRoute3DA9E72A": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VpcVPCGWBF912B6E" + ], "Properties": { "RouteTableId": { "Ref": "VpcPublicSubnet1RouteTable6C95E38E" @@ -139,6 +142,9 @@ }, "VpcPublicSubnet2DefaultRoute97F91067": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VpcVPCGWBF912B6E" + ], "Properties": { "RouteTableId": { "Ref": "VpcPublicSubnet2RouteTable94F7E489" @@ -631,4 +637,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.expected.json b/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.expected.json index 50513f3f5ba0f..9155d42d526b6 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.expected.json +++ b/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.expected.json @@ -85,6 +85,9 @@ }, "VPCPublicSubnet1DefaultRoute91CEF279": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet1RouteTableFEE4B781" diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.expected.json b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.expected.json index 689e2b1378871..e1cab64dac4c1 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.expected.json +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb-alias-target.expected.json @@ -59,6 +59,9 @@ }, "VPCPublicSubnet1DefaultRoute91CEF279": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet1RouteTableFEE4B781" @@ -139,6 +142,9 @@ }, "VPCPublicSubnet2DefaultRouteB7481BBA": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.expected.json b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.expected.json index 6e2cd595b15b8..a920725179f4a 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.expected.json +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.expected.json @@ -85,6 +85,9 @@ }, "VPCPublicSubnet1DefaultRoute91CEF279": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet1RouteTableFEE4B781" @@ -165,6 +168,9 @@ }, "VPCPublicSubnet2DefaultRouteB7481BBA": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.expected.json b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.expected.json index a27c8b8c2db10..8371578b42a29 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.expected.json +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.expected.json @@ -85,6 +85,9 @@ }, "VPCPublicSubnet1DefaultRoute91CEF279": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet1RouteTableFEE4B781" @@ -165,6 +168,9 @@ }, "VPCPublicSubnet2DefaultRouteB7481BBA": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" @@ -362,4 +368,4 @@ ] } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-lambda/test/integ.vpc-lambda.expected.json b/packages/@aws-cdk/aws-lambda/test/integ.vpc-lambda.expected.json index 386f53a95073c..c062ac71ba8b4 100644 --- a/packages/@aws-cdk/aws-lambda/test/integ.vpc-lambda.expected.json +++ b/packages/@aws-cdk/aws-lambda/test/integ.vpc-lambda.expected.json @@ -59,6 +59,9 @@ }, "VPCPublicSubnet1DefaultRoute91CEF279": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet1RouteTableFEE4B781" @@ -139,6 +142,9 @@ }, "VPCPublicSubnet2DefaultRouteB7481BBA": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" diff --git a/packages/@aws-cdk/aws-rds/test/integ.cluster.expected.json b/packages/@aws-cdk/aws-rds/test/integ.cluster.expected.json index 35e7814dcf7eb..d880c015af506 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster.expected.json +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster.expected.json @@ -85,6 +85,9 @@ }, "VPCPublicSubnet1DefaultRoute91CEF279": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet1RouteTableFEE4B781" @@ -165,6 +168,9 @@ }, "VPCPublicSubnet2DefaultRouteB7481BBA": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" diff --git a/packages/@aws-cdk/aws-route53/test/integ.route53.expected.json b/packages/@aws-cdk/aws-route53/test/integ.route53.expected.json index 363df70cd4d99..1d888b6f9eb1f 100644 --- a/packages/@aws-cdk/aws-route53/test/integ.route53.expected.json +++ b/packages/@aws-cdk/aws-route53/test/integ.route53.expected.json @@ -85,6 +85,9 @@ }, "VPCPublicSubnet1DefaultRoute91CEF279": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet1RouteTableFEE4B781" @@ -165,6 +168,9 @@ }, "VPCPublicSubnet2DefaultRouteB7481BBA": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" @@ -245,6 +251,9 @@ }, "VPCPublicSubnet3DefaultRouteA0D29D46": { "Type": "AWS::EC2::Route", + "DependsOn": [ + "VPCVPCGW99B986DC" + ], "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet3RouteTable98AE0E14" @@ -494,4 +503,4 @@ } } } -} \ No newline at end of file +}