From 6a295b1eecd8fad02f7b9978d15dec7482e0c74f Mon Sep 17 00:00:00 2001 From: Yogesh Chopra Date: Sun, 30 Oct 2022 14:26:33 -0700 Subject: [PATCH] feat(ec2): support reserving azs space in VPCs --- packages/@aws-cdk/aws-ec2/README.md | 25 + packages/@aws-cdk/aws-ec2/lib/vpc.ts | 18 + .../aws-ec2/test/integ.vpc-reserved-azs.ts | 15 + .../vpc-reserved-azs.integ.snapshot/cdk.out | 1 + .../integ.json | 12 + .../integtest-vpc-reserved-azs.assets.json | 19 + .../integtest-vpc-reserved-azs.template.json | 429 +++++++++++ .../manifest.json | 243 ++++++ .../vpc-reserved-azs.integ.snapshot/tree.json | 710 ++++++++++++++++++ ...efaultTestDeployAssertE48D2C6D.assets.json | 19 + ...aultTestDeployAssertE48D2C6D.template.json | 36 + packages/@aws-cdk/aws-ec2/test/vpc.test.ts | 29 + 12 files changed, 1556 insertions(+) create mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-reserved-azs.ts create mode 100644 packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/cdk.out create mode 100644 packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/integ.json create mode 100644 packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/integtest-vpc-reserved-azs.assets.json create mode 100644 packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/integtest-vpc-reserved-azs.template.json create mode 100644 packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/manifest.json create mode 100644 packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/tree.json create mode 100644 packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/vpcreservedazsDefaultTestDeployAssertE48D2C6D.assets.json create mode 100644 packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/vpcreservedazsDefaultTestDeployAssertE48D2C6D.template.json diff --git a/packages/@aws-cdk/aws-ec2/README.md b/packages/@aws-cdk/aws-ec2/README.md index 43048983fd705..a689705ee0b14 100644 --- a/packages/@aws-cdk/aws-ec2/README.md +++ b/packages/@aws-cdk/aws-ec2/README.md @@ -273,6 +273,31 @@ new ec2.Vpc(stack, 'TheVPC', { With this method of IP address management, no attempt is made to guess at subnet group sizes or to exhaustively allocate the IP range. All subnet groups must have an explicit `cidrMask` set as part of their subnet configuration, or `defaultSubnetIpv4NetmaskLength` must be set for a default size. If not, synthesis will fail and you must provide one or the other. +### Reserving availability zones + +There are situations where the IP space for availability zones will +need to be reserved. This is useful in situations where availability +zones would need to be added after the vpc is originally deployed, +without causing IP renumbering for availability zones subnets. The IP +space for reserving `n` availability zones can be done by setting the +`reservedAzs` to `n` in vpc props, as shown below: + +```ts +const vpc = new ec2.Vpc(this, 'TheVPC', { + cidr: '10.0.0.0/21', + maxAzs: 3, + reservedAzs: 1, +}); +``` + +In the example above, the subnets for reserved availability zones is not +actually provisioned but its IP space is still reserved. If, in the future, +new availability zones needs to be provisioned, then we would decrement +the value of `reservedAzs` and increment the `maxAzs` or `availabilityZones` +accordingly. This action would not cause the IP address of subnets to get +renumbered, but rather the IP space that was previously reserved will be +used for the new availability zones subnets. + ### Advanced Subnet Configuration If the default VPC configuration (public and private subnets spanning the diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index 719c1f9df4bdf..e2e4485fe43a1 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -21,6 +21,7 @@ import { VpcLookupOptions } from './vpc-lookup'; import { EnableVpnGatewayOptions, VpnConnection, VpnConnectionOptions, VpnConnectionType, VpnGateway } from './vpn'; const VPC_SUBNET_SYMBOL = Symbol.for('@aws-cdk/aws-ec2.VpcSubnet'); +const FAKE_AZ_NAME = 'fake-az'; export interface ISubnet extends IResource { /** @@ -888,6 +889,16 @@ export interface VpcProps { */ readonly maxAzs?: number; + /** + * Define the number of AZs to reserve. + * + * When specified, the IP space is reserved for the azs but no actual + * resources are provisioned. + * + * @default 0 + */ + readonly reservedAzs?: number; + /** * Availability zones this VPC spans. * @@ -1396,6 +1407,9 @@ export class Vpc extends VpcBase { const maxAZs = props.maxAzs ?? 3; this.availabilityZones = stack.availabilityZones.slice(0, maxAZs); } + for (let i = 0; props.reservedAzs && i < props.reservedAzs; i++) { + this.availabilityZones.push(FAKE_AZ_NAME); + } this.vpcId = this.resource.ref; @@ -1561,6 +1575,10 @@ export class Vpc extends VpcBase { // For reserved subnets, do not create any resources return; } + if (availabilityZone === FAKE_AZ_NAME) { + // For reserved azs, do not create any resources + return; + } // mapPublicIpOnLaunch true in Subnet.Public, false in Subnet.Private or Subnet.Isolated. let mapPublicIpOnLaunch = false; diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-reserved-azs.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc-reserved-azs.ts new file mode 100644 index 0000000000000..f434db8a52527 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-reserved-azs.ts @@ -0,0 +1,15 @@ +import * as cdk from '@aws-cdk/core'; +import { IntegTest } from '@aws-cdk/integ-tests'; +import * as ec2 from '../lib'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'integtest-vpc-reserved-azs'); + +new ec2.Vpc(stack, 'MyVpc', { + reservedAzs: 2, + maxAzs: 3, +}); + +new IntegTest(app, 'vpc-reserved-azs', { + testCases: [stack], +}); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/cdk.out new file mode 100644 index 0000000000000..8ecc185e9dbee --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"21.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/integ.json b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/integ.json new file mode 100644 index 0000000000000..401d95f9eade9 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "21.0.0", + "testCases": { + "vpc-reserved-azs/DefaultTest": { + "stacks": [ + "integtest-vpc-reserved-azs" + ], + "assertionStack": "vpc-reserved-azs/DefaultTest/DeployAssert", + "assertionStackName": "vpcreservedazsDefaultTestDeployAssertE48D2C6D" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/integtest-vpc-reserved-azs.assets.json b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/integtest-vpc-reserved-azs.assets.json new file mode 100644 index 0000000000000..b1bf2c2192276 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/integtest-vpc-reserved-azs.assets.json @@ -0,0 +1,19 @@ +{ + "version": "21.0.0", + "files": { + "2316c1d0bd29529a3dc0b6ffcefa3aa88c8d79ea1b90aff8056d49f0de23e53b": { + "source": { + "path": "integtest-vpc-reserved-azs.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "2316c1d0bd29529a3dc0b6ffcefa3aa88c8d79ea1b90aff8056d49f0de23e53b.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/integtest-vpc-reserved-azs.template.json b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/integtest-vpc-reserved-azs.template.json new file mode 100644 index 0000000000000..98924cc702938 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/integtest-vpc-reserved-azs.template.json @@ -0,0 +1,429 @@ +{ + "Resources": { + "MyVpcF9F0CA6F": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc" + } + ] + } + }, + "MyVpcPublicSubnet1SubnetF6608456": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.0.0/19", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1" + } + ] + } + }, + "MyVpcPublicSubnet1RouteTableC46AB2F4": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1" + } + ] + } + }, + "MyVpcPublicSubnet1RouteTableAssociation2ECEE1CB": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPublicSubnet1RouteTableC46AB2F4" + }, + "SubnetId": { + "Ref": "MyVpcPublicSubnet1SubnetF6608456" + } + } + }, + "MyVpcPublicSubnet1DefaultRoute95FDF9EB": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPublicSubnet1RouteTableC46AB2F4" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "MyVpcIGW5C4A4F63" + } + }, + "DependsOn": [ + "MyVpcVPCGW488ACE0D" + ] + }, + "MyVpcPublicSubnet1EIP096967CB": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1" + } + ] + } + }, + "MyVpcPublicSubnet1NATGatewayAD3400C1": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "MyVpcPublicSubnet1SubnetF6608456" + }, + "AllocationId": { + "Fn::GetAtt": [ + "MyVpcPublicSubnet1EIP096967CB", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1" + } + ] + }, + "DependsOn": [ + "MyVpcPublicSubnet1DefaultRoute95FDF9EB", + "MyVpcPublicSubnet1RouteTableAssociation2ECEE1CB" + ] + }, + "MyVpcPublicSubnet2Subnet492B6BFB": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.32.0/19", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2" + } + ] + } + }, + "MyVpcPublicSubnet2RouteTable1DF17386": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2" + } + ] + } + }, + "MyVpcPublicSubnet2RouteTableAssociation227DE78D": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" + }, + "SubnetId": { + "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" + } + } + }, + "MyVpcPublicSubnet2DefaultRoute052936F6": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "MyVpcIGW5C4A4F63" + } + }, + "DependsOn": [ + "MyVpcVPCGW488ACE0D" + ] + }, + "MyVpcPublicSubnet2EIP8CCBA239": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2" + } + ] + } + }, + "MyVpcPublicSubnet2NATGateway91BFBEC9": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" + }, + "AllocationId": { + "Fn::GetAtt": [ + "MyVpcPublicSubnet2EIP8CCBA239", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2" + } + ] + }, + "DependsOn": [ + "MyVpcPublicSubnet2DefaultRoute052936F6", + "MyVpcPublicSubnet2RouteTableAssociation227DE78D" + ] + }, + "MyVpcPrivateSubnet1Subnet5057CF7E": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.128.0/19", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1" + } + ] + } + }, + "MyVpcPrivateSubnet1RouteTable8819E6E2": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1" + } + ] + } + }, + "MyVpcPrivateSubnet1RouteTableAssociation56D38C7E": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPrivateSubnet1RouteTable8819E6E2" + }, + "SubnetId": { + "Ref": "MyVpcPrivateSubnet1Subnet5057CF7E" + } + } + }, + "MyVpcPrivateSubnet1DefaultRouteA8CDE2FA": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPrivateSubnet1RouteTable8819E6E2" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "MyVpcPublicSubnet1NATGatewayAD3400C1" + } + } + }, + "MyVpcPrivateSubnet2Subnet0040C983": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.160.0/19", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2" + } + ] + } + }, + "MyVpcPrivateSubnet2RouteTableCEDCEECE": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2" + } + ] + } + }, + "MyVpcPrivateSubnet2RouteTableAssociation86A610DA": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPrivateSubnet2RouteTableCEDCEECE" + }, + "SubnetId": { + "Ref": "MyVpcPrivateSubnet2Subnet0040C983" + } + } + }, + "MyVpcPrivateSubnet2DefaultRoute9CE96294": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPrivateSubnet2RouteTableCEDCEECE" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "MyVpcPublicSubnet2NATGateway91BFBEC9" + } + } + }, + "MyVpcIGW5C4A4F63": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "integtest-vpc-reserved-azs/MyVpc" + } + ] + } + }, + "MyVpcVPCGW488ACE0D": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "InternetGatewayId": { + "Ref": "MyVpcIGW5C4A4F63" + } + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/manifest.json new file mode 100644 index 0000000000000..711d45862b95b --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/manifest.json @@ -0,0 +1,243 @@ +{ + "version": "21.0.0", + "artifacts": { + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, + "integtest-vpc-reserved-azs.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integtest-vpc-reserved-azs.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integtest-vpc-reserved-azs": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integtest-vpc-reserved-azs.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/2316c1d0bd29529a3dc0b6ffcefa3aa88c8d79ea1b90aff8056d49f0de23e53b.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "integtest-vpc-reserved-azs.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "integtest-vpc-reserved-azs.assets" + ], + "metadata": { + "/integtest-vpc-reserved-azs/MyVpc/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcF9F0CA6F" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PublicSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPublicSubnet1SubnetF6608456" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PublicSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPublicSubnet1RouteTableC46AB2F4" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PublicSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPublicSubnet1RouteTableAssociation2ECEE1CB" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PublicSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPublicSubnet1DefaultRoute95FDF9EB" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PublicSubnet1/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPublicSubnet1EIP096967CB" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PublicSubnet1/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPublicSubnet1NATGatewayAD3400C1" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PublicSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPublicSubnet2Subnet492B6BFB" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PublicSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPublicSubnet2RouteTable1DF17386" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PublicSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPublicSubnet2RouteTableAssociation227DE78D" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PublicSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPublicSubnet2DefaultRoute052936F6" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PublicSubnet2/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPublicSubnet2EIP8CCBA239" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PublicSubnet2/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPublicSubnet2NATGateway91BFBEC9" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPrivateSubnet1Subnet5057CF7E" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPrivateSubnet1RouteTable8819E6E2" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPrivateSubnet1RouteTableAssociation56D38C7E" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPrivateSubnet1DefaultRouteA8CDE2FA" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPrivateSubnet2Subnet0040C983" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPrivateSubnet2RouteTableCEDCEECE" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPrivateSubnet2RouteTableAssociation86A610DA" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcPrivateSubnet2DefaultRoute9CE96294" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/IGW": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcIGW5C4A4F63" + } + ], + "/integtest-vpc-reserved-azs/MyVpc/VPCGW": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcVPCGW488ACE0D" + } + ], + "/integtest-vpc-reserved-azs/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integtest-vpc-reserved-azs/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integtest-vpc-reserved-azs" + }, + "vpcreservedazsDefaultTestDeployAssertE48D2C6D.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "vpcreservedazsDefaultTestDeployAssertE48D2C6D.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "vpcreservedazsDefaultTestDeployAssertE48D2C6D": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "vpcreservedazsDefaultTestDeployAssertE48D2C6D.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "vpcreservedazsDefaultTestDeployAssertE48D2C6D.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "vpcreservedazsDefaultTestDeployAssertE48D2C6D.assets" + ], + "metadata": { + "/vpc-reserved-azs/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/vpc-reserved-azs/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "vpc-reserved-azs/DefaultTest/DeployAssert" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/tree.json b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/tree.json new file mode 100644 index 0000000000000..f72f174341639 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/tree.json @@ -0,0 +1,710 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.129" + } + }, + "integtest-vpc-reserved-azs": { + "id": "integtest-vpc-reserved-azs", + "path": "integtest-vpc-reserved-azs", + "children": { + "MyVpc": { + "id": "MyVpc", + "path": "integtest-vpc-reserved-azs/MyVpc", + "children": { + "Resource": { + "id": "Resource", + "path": "integtest-vpc-reserved-azs/MyVpc/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.0.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default", + "tags": [ + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnVPC", + "version": "0.0.0" + } + }, + "PublicSubnet1": { + "id": "PublicSubnet1", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.0.0/19", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "tags": [ + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "MyVpcPublicSubnet1RouteTableC46AB2F4" + }, + "subnetId": { + "Ref": "MyVpcPublicSubnet1SubnetF6608456" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "MyVpcPublicSubnet1RouteTableC46AB2F4" + }, + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "MyVpcIGW5C4A4F63" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "subnetId": { + "Ref": "MyVpcPublicSubnet1SubnetF6608456" + }, + "allocationId": { + "Fn::GetAtt": [ + "MyVpcPublicSubnet1EIP096967CB", + "AllocationId" + ] + }, + "tags": [ + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PublicSubnet2": { + "id": "PublicSubnet2", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.32.0/19", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "tags": [ + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" + }, + "subnetId": { + "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" + }, + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "MyVpcIGW5C4A4F63" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "subnetId": { + "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" + }, + "allocationId": { + "Fn::GetAtt": [ + "MyVpcPublicSubnet2EIP8CCBA239", + "AllocationId" + ] + }, + "tags": [ + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet1": { + "id": "PrivateSubnet1", + "path": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.128.0/19", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "tags": [ + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "MyVpcPrivateSubnet1RouteTable8819E6E2" + }, + "subnetId": { + "Ref": "MyVpcPrivateSubnet1Subnet5057CF7E" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "MyVpcPrivateSubnet1RouteTable8819E6E2" + }, + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "MyVpcPublicSubnet1NATGatewayAD3400C1" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet2": { + "id": "PrivateSubnet2", + "path": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.160.0/19", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2/Acl", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "tags": [ + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "MyVpcPrivateSubnet2RouteTableCEDCEECE" + }, + "subnetId": { + "Ref": "MyVpcPrivateSubnet2Subnet0040C983" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "integtest-vpc-reserved-azs/MyVpc/PrivateSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "MyVpcPrivateSubnet2RouteTableCEDCEECE" + }, + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "MyVpcPublicSubnet2NATGateway91BFBEC9" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "IGW": { + "id": "IGW", + "path": "integtest-vpc-reserved-azs/MyVpc/IGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "integtest-vpc-reserved-azs/MyVpc" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnInternetGateway", + "version": "0.0.0" + } + }, + "VPCGW": { + "id": "VPCGW", + "path": "integtest-vpc-reserved-azs/MyVpc/VPCGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "internetGatewayId": { + "Ref": "MyVpcIGW5C4A4F63" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.CfnVPCGatewayAttachment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-ec2.Vpc", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "vpc-reserved-azs": { + "id": "vpc-reserved-azs", + "path": "vpc-reserved-azs", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "vpc-reserved-azs/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "vpc-reserved-azs/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.129" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "vpc-reserved-azs/DefaultTest/DeployAssert", + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/vpcreservedazsDefaultTestDeployAssertE48D2C6D.assets.json b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/vpcreservedazsDefaultTestDeployAssertE48D2C6D.assets.json new file mode 100644 index 0000000000000..79939c1deec2c --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/vpcreservedazsDefaultTestDeployAssertE48D2C6D.assets.json @@ -0,0 +1,19 @@ +{ + "version": "21.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "vpcreservedazsDefaultTestDeployAssertE48D2C6D.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/vpcreservedazsDefaultTestDeployAssertE48D2C6D.template.json b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/vpcreservedazsDefaultTestDeployAssertE48D2C6D.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-reserved-azs.integ.snapshot/vpcreservedazsDefaultTestDeployAssertE48D2C6D.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc.test.ts b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts index e350b1a45b0c8..afe61c6e0a320 100644 --- a/packages/@aws-cdk/aws-ec2/test/vpc.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts @@ -2086,6 +2086,35 @@ describe('vpc', () => { }); }); }); + + describe('Using reserved azs', () => { + test.each([ + [{ maxAzs: 2, reservedAzs: 1 }, { maxAzs: 3 }], + [{ maxAzs: 2, reservedAzs: 2 }, { maxAzs: 3, reservedAzs: 1 }], + [{ maxAzs: 2, reservedAzs: 1, subnetConfiguration: [{ cidrMask: 22, name: 'Public', subnetType: SubnetType.PUBLIC }, { cidrMask: 23, name: 'Private', subnetType: SubnetType.PRIVATE_WITH_EGRESS }] }, + { maxAzs: 3, subnetConfiguration: [{ cidrMask: 22, name: 'Public', subnetType: SubnetType.PUBLIC }, { cidrMask: 23, name: 'Private', subnetType: SubnetType.PRIVATE_WITH_EGRESS }] }], + [{ maxAzs: 2, reservedAzs: 1, subnetConfiguration: [{ cidrMask: 22, name: 'Public', subnetType: SubnetType.PUBLIC }, { cidrMask: 23, name: 'Private', subnetType: SubnetType.PRIVATE_WITH_EGRESS, reserved: true }] }, + { maxAzs: 3, subnetConfiguration: [{ cidrMask: 22, name: 'Public', subnetType: SubnetType.PUBLIC }, { cidrMask: 23, name: 'Private', subnetType: SubnetType.PRIVATE_WITH_EGRESS, reserved: true }] }], + [{ maxAzs: 2, reservedAzs: 1, ipAddresses: IpAddresses.cidr('192.168.0.0/16') }, { maxAzs: 3, ipAddresses: IpAddresses.cidr('192.168.0.0/16') }], + [{ availabilityZones: ['dummy1a', 'dummy1b'], reservedAzs: 1 }, { availabilityZones: ['dummy1a', 'dummy1b', 'dummy1c'] }], + ])('subnets should remain the same going from %p to %p', (propsWithReservedAz, propsWithUsedReservedAz) => { + const stackWithReservedAz = getTestStack(); + const stackWithUsedReservedAz = getTestStack(); + + new Vpc(stackWithReservedAz, 'Vpc', propsWithReservedAz); + new Vpc(stackWithUsedReservedAz, 'Vpc', propsWithUsedReservedAz); + + const templateWithReservedAz = Template.fromStack(stackWithReservedAz); + const templateWithUsedReservedAz = Template.fromStack(stackWithUsedReservedAz); + + const subnetsOfTemplateWithReservedAz = templateWithReservedAz.findResources('AWS::EC2::Subnet'); + const subnetsOfTemplateWithUsedReservedAz = templateWithUsedReservedAz.findResources('AWS::EC2::Subnet'); + for (const [logicalId, subnetOfTemplateWithReservedAz] of Object.entries(subnetsOfTemplateWithReservedAz)) { + const subnetOfTemplateWithUsedReservedAz = subnetsOfTemplateWithUsedReservedAz[logicalId]; + expect(subnetOfTemplateWithUsedReservedAz).toEqual(subnetOfTemplateWithReservedAz); + } + }); + }); }); function getTestStack(): Stack {