diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index c607ab434f112..8ac0472755643 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -763,6 +763,13 @@ export interface VpcAttributes { * VPN gateway's identifier */ readonly vpnGatewayId?: string; + + /** + * The region the VPC is in + * + * @default - The region of the stack where the VPC belongs to + */ + readonly region?: string; } export interface SubnetAttributes { @@ -1203,7 +1210,7 @@ export class Vpc extends VpcBase { dummyValue: undefined, }).value; - return new LookedUpVpc(scope, id, attributes || DUMMY_VPC_PROPS, attributes === undefined); + return new LookedUpVpc(scope, id, attributes ?? DUMMY_VPC_PROPS, attributes === undefined); /** * Prefixes all keys in the argument with `tag:`.` @@ -2008,7 +2015,9 @@ class ImportedVpc extends VpcBase { private readonly cidr?: string | undefined; constructor(scope: Construct, id: string, props: VpcAttributes, isIncomplete: boolean) { - super(scope, id); + super(scope, id, { + region: props.region, + }); this.vpcId = props.vpcId; this.vpcArn = Arn.format({ @@ -2058,7 +2067,9 @@ class LookedUpVpc extends VpcBase { private readonly cidr?: string | undefined; constructor(scope: Construct, id: string, props: cxapi.VpcContextResponse, isIncomplete: boolean) { - super(scope, id); + super(scope, id, { + region: props.region, + }); this.vpcId = props.vpcId; this.vpcArn = Arn.format({ diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-lookup.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc-lookup.ts new file mode 100644 index 0000000000000..3ce324f2a1e08 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-lookup.ts @@ -0,0 +1,48 @@ +import * as cdk from '@aws-cdk/core'; +import { IntegTest } from '@aws-cdk/integ-tests'; +import * as ec2 from '../lib'; + +const appWithVpc = new cdk.App(); +const stack = new cdk.Stack(appWithVpc, 'StackWithVpc', { + env: { + region: 'eu-west-1', + account: '123456', + }, +}); + +const testVpc = new ec2.Vpc(stack, 'MyVpc', { + vpcName: 'my-vpc-name', +}); + +const appUnderTest = new cdk.App(); +const stackLookup = new cdk.Stack(appUnderTest, 'StackUnderTest', { + env: { + region: 'us-east-2', + account: '123456', + }, +}); + +const vpcFromVpcAttributes = ec2.Vpc.fromVpcAttributes(stackLookup, 'VpcFromVpcAttributes', { + region: 'eu-west-1', + availabilityZones: ['eu-west-1a'], + vpcId: testVpc.vpcId, +}); + +const vpcFromLookup = ec2.Vpc.fromLookup(stack, 'VpcFromLookup', { + region: 'eu-west-1', + vpcName: 'my-vpc-name', +}); + +new cdk.CfnOutput(stackLookup, 'OutputFromVpcAttributes', { + value: `Region fromVpcAttributes: ${vpcFromVpcAttributes.env.region}`, +}); + +new cdk.CfnOutput(stackLookup, 'OutputFromLookup', { + value: `Region fromLookup: ${vpcFromLookup.env.region}`, +}); + +new IntegTest(appUnderTest, 'ArchiveTest', { + testCases: [stackLookup], +}); +appWithVpc.synth(); +appUnderTest.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/ArchiveTestDefaultTestDeployAssert3405726A.assets.json b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/ArchiveTestDefaultTestDeployAssert3405726A.assets.json new file mode 100644 index 0000000000000..c18c34e7e9601 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/ArchiveTestDefaultTestDeployAssert3405726A.assets.json @@ -0,0 +1,19 @@ +{ + "version": "21.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "ArchiveTestDefaultTestDeployAssert3405726A.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-lookup.integ.snapshot/ArchiveTestDefaultTestDeployAssert3405726A.template.json b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/ArchiveTestDefaultTestDeployAssert3405726A.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/ArchiveTestDefaultTestDeployAssert3405726A.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-lookup.integ.snapshot/StackUnderTest.assets.json b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/StackUnderTest.assets.json new file mode 100644 index 0000000000000..62e4b8863c352 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/StackUnderTest.assets.json @@ -0,0 +1,20 @@ +{ + "version": "21.0.0", + "files": { + "cfac1423efb7c99cadc3f40367c753fe5b1527d9a6950c096ba326fabac4c89f": { + "source": { + "path": "StackUnderTest.template.json", + "packaging": "file" + }, + "destinations": { + "123456-us-east-2": { + "bucketName": "cdk-hnb659fds-assets-123456-us-east-2", + "objectKey": "cfac1423efb7c99cadc3f40367c753fe5b1527d9a6950c096ba326fabac4c89f.json", + "region": "us-east-2", + "assumeRoleArn": "arn:${AWS::Partition}:iam::123456:role/cdk-hnb659fds-file-publishing-role-123456-us-east-2" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/StackUnderTest.template.json b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/StackUnderTest.template.json new file mode 100644 index 0000000000000..6215386397ad3 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/StackUnderTest.template.json @@ -0,0 +1,44 @@ +{ + "Outputs": { + "OutputFromVpcAttributes": { + "Value": "Region fromVpcAttributes: eu-west-1" + }, + "OutputFromLookup": { + "Value": "Region fromLookup: eu-west-1" + } + }, + "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-lookup.integ.snapshot/StackWithVpc.assets.json b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/StackWithVpc.assets.json new file mode 100644 index 0000000000000..502d2f22aa209 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/StackWithVpc.assets.json @@ -0,0 +1,20 @@ +{ + "version": "21.0.0", + "files": { + "628a32283150d3af24efb3a11967996306884a3835ac731ab35822da2ce7e9ff": { + "source": { + "path": "StackWithVpc.template.json", + "packaging": "file" + }, + "destinations": { + "123456-eu-west-1": { + "bucketName": "cdk-hnb659fds-assets-123456-eu-west-1", + "objectKey": "628a32283150d3af24efb3a11967996306884a3835ac731ab35822da2ce7e9ff.json", + "region": "eu-west-1", + "assumeRoleArn": "arn:${AWS::Partition}:iam::123456:role/cdk-hnb659fds-file-publishing-role-123456-eu-west-1" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/StackWithVpc.template.json b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/StackWithVpc.template.json new file mode 100644 index 0000000000000..6c194bc628b8f --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/StackWithVpc.template.json @@ -0,0 +1,564 @@ +{ + "Resources": { + "MyVpcF9F0CA6F": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "my-vpc-name" + } + ] + } + }, + "MyVpcPublicSubnet1SubnetF6608456": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "AvailabilityZone": "dummy1a", + "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": "StackWithVpc/MyVpc/PublicSubnet1" + } + ] + } + }, + "MyVpcPublicSubnet1RouteTableC46AB2F4": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "StackWithVpc/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": "StackWithVpc/MyVpc/PublicSubnet1" + } + ] + } + }, + "MyVpcPublicSubnet1NATGatewayAD3400C1": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "MyVpcPublicSubnet1SubnetF6608456" + }, + "AllocationId": { + "Fn::GetAtt": [ + "MyVpcPublicSubnet1EIP096967CB", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "StackWithVpc/MyVpc/PublicSubnet1" + } + ] + }, + "DependsOn": [ + "MyVpcPublicSubnet1DefaultRoute95FDF9EB", + "MyVpcPublicSubnet1RouteTableAssociation2ECEE1CB" + ] + }, + "MyVpcPublicSubnet2Subnet492B6BFB": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "AvailabilityZone": "dummy1b", + "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": "StackWithVpc/MyVpc/PublicSubnet2" + } + ] + } + }, + "MyVpcPublicSubnet2RouteTable1DF17386": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "StackWithVpc/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": "StackWithVpc/MyVpc/PublicSubnet2" + } + ] + } + }, + "MyVpcPublicSubnet2NATGateway91BFBEC9": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" + }, + "AllocationId": { + "Fn::GetAtt": [ + "MyVpcPublicSubnet2EIP8CCBA239", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "StackWithVpc/MyVpc/PublicSubnet2" + } + ] + }, + "DependsOn": [ + "MyVpcPublicSubnet2DefaultRoute052936F6", + "MyVpcPublicSubnet2RouteTableAssociation227DE78D" + ] + }, + "MyVpcPublicSubnet3Subnet57EEE236": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "AvailabilityZone": "dummy1c", + "CidrBlock": "10.0.64.0/19", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "StackWithVpc/MyVpc/PublicSubnet3" + } + ] + } + }, + "MyVpcPublicSubnet3RouteTable15028F08": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "StackWithVpc/MyVpc/PublicSubnet3" + } + ] + } + }, + "MyVpcPublicSubnet3RouteTableAssociation5C27DDA4": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPublicSubnet3RouteTable15028F08" + }, + "SubnetId": { + "Ref": "MyVpcPublicSubnet3Subnet57EEE236" + } + } + }, + "MyVpcPublicSubnet3DefaultRoute3A83AB36": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPublicSubnet3RouteTable15028F08" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "MyVpcIGW5C4A4F63" + } + }, + "DependsOn": [ + "MyVpcVPCGW488ACE0D" + ] + }, + "MyVpcPublicSubnet3EIPC5ACADAB": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "StackWithVpc/MyVpc/PublicSubnet3" + } + ] + } + }, + "MyVpcPublicSubnet3NATGatewayD4B50EBE": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "MyVpcPublicSubnet3Subnet57EEE236" + }, + "AllocationId": { + "Fn::GetAtt": [ + "MyVpcPublicSubnet3EIPC5ACADAB", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "StackWithVpc/MyVpc/PublicSubnet3" + } + ] + }, + "DependsOn": [ + "MyVpcPublicSubnet3DefaultRoute3A83AB36", + "MyVpcPublicSubnet3RouteTableAssociation5C27DDA4" + ] + }, + "MyVpcPrivateSubnet1Subnet5057CF7E": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "AvailabilityZone": "dummy1a", + "CidrBlock": "10.0.96.0/19", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "StackWithVpc/MyVpc/PrivateSubnet1" + } + ] + } + }, + "MyVpcPrivateSubnet1RouteTable8819E6E2": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "StackWithVpc/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": "dummy1b", + "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": "StackWithVpc/MyVpc/PrivateSubnet2" + } + ] + } + }, + "MyVpcPrivateSubnet2RouteTableCEDCEECE": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "StackWithVpc/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" + } + } + }, + "MyVpcPrivateSubnet3Subnet772D6AD7": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "AvailabilityZone": "dummy1c", + "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": "StackWithVpc/MyVpc/PrivateSubnet3" + } + ] + } + }, + "MyVpcPrivateSubnet3RouteTableB790927C": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "StackWithVpc/MyVpc/PrivateSubnet3" + } + ] + } + }, + "MyVpcPrivateSubnet3RouteTableAssociationD951741C": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPrivateSubnet3RouteTableB790927C" + }, + "SubnetId": { + "Ref": "MyVpcPrivateSubnet3Subnet772D6AD7" + } + } + }, + "MyVpcPrivateSubnet3DefaultRouteEC11C0C5": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPrivateSubnet3RouteTableB790927C" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "MyVpcPublicSubnet3NATGatewayD4B50EBE" + } + } + }, + "MyVpcIGW5C4A4F63": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "my-vpc-name" + } + ] + } + }, + "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-lookup.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/cdk.out new file mode 100644 index 0000000000000..8ecc185e9dbee --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.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-lookup.integ.snapshot/integ.json b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/integ.json new file mode 100644 index 0000000000000..8d00f60c22e15 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "21.0.0", + "testCases": { + "ArchiveTest/DefaultTest": { + "stacks": [ + "StackUnderTest" + ], + "assertionStack": "ArchiveTest/DefaultTest/DeployAssert", + "assertionStackName": "ArchiveTestDefaultTestDeployAssert3405726A" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/manifest.json new file mode 100644 index 0000000000000..fbf4ce0e2ea74 --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/manifest.json @@ -0,0 +1,117 @@ +{ + "version": "21.0.0", + "artifacts": { + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, + "StackUnderTest.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "StackUnderTest.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "StackUnderTest": { + "type": "aws:cloudformation:stack", + "environment": "aws://123456/us-east-2", + "properties": { + "templateFile": "StackUnderTest.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::123456:role/cdk-hnb659fds-deploy-role-123456-us-east-2", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::123456:role/cdk-hnb659fds-cfn-exec-role-123456-us-east-2", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-123456-us-east-2/cfac1423efb7c99cadc3f40367c753fe5b1527d9a6950c096ba326fabac4c89f.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "StackUnderTest.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::123456:role/cdk-hnb659fds-lookup-role-123456-us-east-2", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "StackUnderTest.assets" + ], + "metadata": { + "/StackUnderTest/OutputFromVpcAttributes": [ + { + "type": "aws:cdk:logicalId", + "data": "OutputFromVpcAttributes" + } + ], + "/StackUnderTest/OutputFromLookup": [ + { + "type": "aws:cdk:logicalId", + "data": "OutputFromLookup" + } + ], + "/StackUnderTest/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/StackUnderTest/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "StackUnderTest" + }, + "ArchiveTestDefaultTestDeployAssert3405726A.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "ArchiveTestDefaultTestDeployAssert3405726A.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "ArchiveTestDefaultTestDeployAssert3405726A": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "ArchiveTestDefaultTestDeployAssert3405726A.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": [ + "ArchiveTestDefaultTestDeployAssert3405726A.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": [ + "ArchiveTestDefaultTestDeployAssert3405726A.assets" + ], + "metadata": { + "/ArchiveTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/ArchiveTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "ArchiveTest/DefaultTest/DeployAssert" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/tree.json b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/tree.json new file mode 100644 index 0000000000000..cf1089e7c66cc --- /dev/null +++ b/packages/@aws-cdk/aws-ec2/test/vpc-lookup.integ.snapshot/tree.json @@ -0,0 +1,91 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.92" + } + }, + "StackUnderTest": { + "id": "StackUnderTest", + "path": "StackUnderTest", + "children": { + "VpcFromVpcAttributes": { + "id": "VpcFromVpcAttributes", + "path": "StackUnderTest/VpcFromVpcAttributes", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "OutputFromVpcAttributes": { + "id": "OutputFromVpcAttributes", + "path": "StackUnderTest/OutputFromVpcAttributes", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + }, + "OutputFromLookup": { + "id": "OutputFromLookup", + "path": "StackUnderTest/OutputFromLookup", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnOutput", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "ArchiveTest": { + "id": "ArchiveTest", + "path": "ArchiveTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "ArchiveTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "ArchiveTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.92" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "ArchiveTest/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.from-lookup.test.ts b/packages/@aws-cdk/aws-ec2/test/vpc.from-lookup.test.ts index 0d133e9673fb2..ba439b8d68211 100644 --- a/packages/@aws-cdk/aws-ec2/test/vpc.from-lookup.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc.from-lookup.test.ts @@ -268,12 +268,32 @@ describe('vpc from lookup', () => { restoreContextProvider(previous); }); + + test('passes region to LookedUpVpc correctly', () => { + const previous = mockVpcContextProviderWith({ + vpcId: 'vpc-1234', + subnetGroups: [], + region: 'region-1234', + }, options => { + expect(options.region).toEqual('region-1234'); + }); + + const stack = new Stack(); + const vpc = Vpc.fromLookup(stack, 'Vpc', { + vpcId: 'vpc-1234', + region: 'region-1234', + }); + + expect(vpc.env.region).toEqual('region-1234'); + restoreContextProvider(previous); + }); }); }); interface MockVcpContextResponse { readonly vpcId: string; readonly subnetGroups: cxapi.VpcSubnetGroup[]; + readonly region?: string; } function mockVpcContextProviderWith( diff --git a/packages/@aws-cdk/aws-ec2/test/vpc.test.ts b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts index b12eb7c788b07..a509aed7d062e 100644 --- a/packages/@aws-cdk/aws-ec2/test/vpc.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts @@ -1220,6 +1220,23 @@ describe('vpc', () => { }); + + test('fromVpcAttributes passes region correctly', () => { + // GIVEN + const stack = getTestStack(); + + const vpcId = Fn.importValue('myVpcId'); + + // WHEN + const vpc = Vpc.fromVpcAttributes(stack, 'VPC', { + vpcId, + availabilityZones: ['region-12345a', 'region-12345b', 'region-12345c'], + region: 'region-12345', + }); + + // THEN + expect(vpc.env.region).toEqual('region-12345'); + }); }); describe('NAT instances', () => { diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts index c965021665b52..1fb05d111d822 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts @@ -181,7 +181,7 @@ export class HostedZone extends Resource implements IHostedZone { * @param vpc the other VPC to add. */ public addVpc(vpc: ec2.IVpc) { - this.vpcs.push({ vpcId: vpc.vpcId, vpcRegion: Stack.of(vpc).region }); + this.vpcs.push({ vpcId: vpc.vpcId, vpcRegion: vpc.env.region ?? Stack.of(vpc).region }); } } diff --git a/packages/@aws-cdk/aws-route53/test/hosted-zone.test.ts b/packages/@aws-cdk/aws-route53/test/hosted-zone.test.ts index b659e41446d75..70af6f1c802ae 100644 --- a/packages/@aws-cdk/aws-route53/test/hosted-zone.test.ts +++ b/packages/@aws-cdk/aws-route53/test/hosted-zone.test.ts @@ -1,7 +1,8 @@ -import { Template } from '@aws-cdk/assertions'; +import { Match, Template } from '@aws-cdk/assertions'; +import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; -import { HostedZone, PublicHostedZone } from '../lib'; +import { HostedZone, PrivateHostedZone, PublicHostedZone } from '../lib'; describe('hosted zone', () => { describe('Hosted Zone', () => { @@ -192,3 +193,33 @@ describe('hosted zone', () => { }).toThrow(/Cannot use undefined value for attribute `domainName`/); }); }); + +describe('Vpc', () => { + test('different region in vpc and hosted zone', () => { + // GIVEN + const stack = new cdk.Stack(undefined, 'TestStack', { + env: { account: '123456789012', region: 'us-east-1' }, + }); + + // WHEN + new PrivateHostedZone(stack, 'HostedZone', { + vpc: ec2.Vpc.fromVpcAttributes(stack, 'Vpc', { + vpcId: '1234', + availabilityZones: ['region-12345a', 'region-12345b', 'region-12345c'], + region: 'region-12345', + }), + zoneName: 'SomeZone', + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Route53::HostedZone', { + VPCs: [ + { + VPCId: '1234', + VPCRegion: 'region-12345', + }, + ], + Name: Match.anyValue(), + }); + }); +}); \ No newline at end of file diff --git a/packages/@aws-cdk/cx-api/lib/context/vpc.ts b/packages/@aws-cdk/cx-api/lib/context/vpc.ts index 8d7bbf34f28ea..3a4adc0910303 100644 --- a/packages/@aws-cdk/cx-api/lib/context/vpc.ts +++ b/packages/@aws-cdk/cx-api/lib/context/vpc.ts @@ -161,4 +161,11 @@ export interface VpcContextResponse { * @default - no subnet groups will be returned unless {@link VpcContextQuery.returnAsymmetricSubnets} is true */ readonly subnetGroups?: VpcSubnetGroup[]; + + /** + * The region in which the VPC is in. + * + * @default - Region of the parent stack + */ + readonly region?: string; }