From 097fe19c1ffbaf2554b9c81ea6fa10b61e1c45bd Mon Sep 17 00:00:00 2001 From: Cory Hall <43035978+corymhall@users.noreply.github.com> Date: Fri, 1 Apr 2022 15:15:51 -0400 Subject: [PATCH 1/6] chore(aws-ec2): fix broken integration tests (#19690) Couple of fixes: - `integ.instance-init`: Create a new VPC instead of performing a lookup in order to make the stack env agnostic - `integ.vpc-endpoint-service`: Moved this test to the elasticloadbalancingv2 package since for the test to actually do anything it needs to create NLBs. - `integ.vpc-endpoint-service-cn`: Removed this test since it is the same as the above test except for creating it in china - `integ.vpc-flow-logs`: Added `autoDeleteObjects` so that the stack can be deleted. Also added the bucket policy to the bucket to avoid some race conditions when the stack tries to delete the bucket while AWS is attempting to add this policy to the bucket. - `integ.vpn-pre-shared-key-token`: The purpose of this test seemed to be validating that a token can be used so I changed this to just use `Lazy`. Also, that property does not support SSM Secure references. ---- ### All Submissions: * [ ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/master/INTEGRATION_TESTS.md)? * [ ] Did you use `cdk-integ` to deploy the infrastructure and generate the snapshot (i.e. `cdk-integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../test/integ.instance-init.expected.json | 542 ++++++++++++++- .../aws-ec2/test/integ.instance-init.ts | 9 +- ...nteg.vpc-endpoint-service-cn.expected.json | 35 - .../test/integ.vpc-endpoint-service-cn.ts | 46 -- .../integ.vpc-endpoint-service.expected.json | 64 -- .../test/integ.vpc-flow-logs.expected.json | 340 +++++++++- .../aws-ec2/test/integ.vpc-flow-logs.ts | 39 +- ...teg.vpn-pre-shared-key-token.expected.json | 32 +- .../test/integ.vpn-pre-shared-key-token.ts | 2 +- .../integ.vpc-endpoint-service.expected.json | 630 ++++++++++++++++++ .../test/integ.vpc-endpoint-service.ts | 27 +- 11 files changed, 1540 insertions(+), 226 deletions(-) delete mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service-cn.expected.json delete mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service-cn.ts delete mode 100644 packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service.expected.json create mode 100644 packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.vpc-endpoint-service.expected.json rename packages/@aws-cdk/{aws-ec2 => aws-elasticloadbalancingv2}/test/integ.vpc-endpoint-service.ts (66%) diff --git a/packages/@aws-cdk/aws-ec2/test/integ.instance-init.expected.json b/packages/@aws-cdk/aws-ec2/test/integ.instance-init.expected.json index e287246eda0a7..576efc96d2057 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.instance-init.expected.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.instance-init.expected.json @@ -1,5 +1,519 @@ { "Resources": { + "IntegInitVpc0D4FCCB3": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc" + } + ] + } + }, + "IntegInitVpcPublicSubnet1Subnet41A6F6D4": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + }, + "AvailabilityZone": "test-region-1a", + "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": "integ-init/IntegInitVpc/PublicSubnet1" + } + ] + } + }, + "IntegInitVpcPublicSubnet1RouteTable837CD5FB": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc/PublicSubnet1" + } + ] + } + }, + "IntegInitVpcPublicSubnet1RouteTableAssociation00D33741": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "IntegInitVpcPublicSubnet1RouteTable837CD5FB" + }, + "SubnetId": { + "Ref": "IntegInitVpcPublicSubnet1Subnet41A6F6D4" + } + } + }, + "IntegInitVpcPublicSubnet1DefaultRoute5BB90E8C": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "IntegInitVpcPublicSubnet1RouteTable837CD5FB" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "IntegInitVpcIGWF019AC85" + } + }, + "DependsOn": [ + "IntegInitVpcVPCGW85EDC292" + ] + }, + "IntegInitVpcPublicSubnet1EIP46FCC3D6": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc/PublicSubnet1" + } + ] + } + }, + "IntegInitVpcPublicSubnet1NATGateway46F32F7F": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "IntegInitVpcPublicSubnet1Subnet41A6F6D4" + }, + "AllocationId": { + "Fn::GetAtt": [ + "IntegInitVpcPublicSubnet1EIP46FCC3D6", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc/PublicSubnet1" + } + ] + } + }, + "IntegInitVpcPublicSubnet2Subnet9A384F16": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + }, + "AvailabilityZone": "test-region-1b", + "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": "integ-init/IntegInitVpc/PublicSubnet2" + } + ] + } + }, + "IntegInitVpcPublicSubnet2RouteTableF7E8F920": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc/PublicSubnet2" + } + ] + } + }, + "IntegInitVpcPublicSubnet2RouteTableAssociationB816F9F3": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "IntegInitVpcPublicSubnet2RouteTableF7E8F920" + }, + "SubnetId": { + "Ref": "IntegInitVpcPublicSubnet2Subnet9A384F16" + } + } + }, + "IntegInitVpcPublicSubnet2DefaultRoute2393995F": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "IntegInitVpcPublicSubnet2RouteTableF7E8F920" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "IntegInitVpcIGWF019AC85" + } + }, + "DependsOn": [ + "IntegInitVpcVPCGW85EDC292" + ] + }, + "IntegInitVpcPublicSubnet2EIP553B40DC": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc/PublicSubnet2" + } + ] + } + }, + "IntegInitVpcPublicSubnet2NATGateway9CCB4A9C": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "IntegInitVpcPublicSubnet2Subnet9A384F16" + }, + "AllocationId": { + "Fn::GetAtt": [ + "IntegInitVpcPublicSubnet2EIP553B40DC", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc/PublicSubnet2" + } + ] + } + }, + "IntegInitVpcPublicSubnet3Subnet30A34DA1": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + }, + "AvailabilityZone": "test-region-1c", + "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": "integ-init/IntegInitVpc/PublicSubnet3" + } + ] + } + }, + "IntegInitVpcPublicSubnet3RouteTable53FB2E26": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc/PublicSubnet3" + } + ] + } + }, + "IntegInitVpcPublicSubnet3RouteTableAssociation73A6B648": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "IntegInitVpcPublicSubnet3RouteTable53FB2E26" + }, + "SubnetId": { + "Ref": "IntegInitVpcPublicSubnet3Subnet30A34DA1" + } + } + }, + "IntegInitVpcPublicSubnet3DefaultRoute3781AD26": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "IntegInitVpcPublicSubnet3RouteTable53FB2E26" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "IntegInitVpcIGWF019AC85" + } + }, + "DependsOn": [ + "IntegInitVpcVPCGW85EDC292" + ] + }, + "IntegInitVpcPublicSubnet3EIP59DDAB7B": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc/PublicSubnet3" + } + ] + } + }, + "IntegInitVpcPublicSubnet3NATGatewayA7A986C7": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "IntegInitVpcPublicSubnet3Subnet30A34DA1" + }, + "AllocationId": { + "Fn::GetAtt": [ + "IntegInitVpcPublicSubnet3EIP59DDAB7B", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc/PublicSubnet3" + } + ] + } + }, + "IntegInitVpcPrivateSubnet1Subnet259B51C1": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + }, + "AvailabilityZone": "test-region-1a", + "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": "integ-init/IntegInitVpc/PrivateSubnet1" + } + ] + } + }, + "IntegInitVpcPrivateSubnet1RouteTableCB37994B": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc/PrivateSubnet1" + } + ] + } + }, + "IntegInitVpcPrivateSubnet1RouteTableAssociation067DEF9D": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "IntegInitVpcPrivateSubnet1RouteTableCB37994B" + }, + "SubnetId": { + "Ref": "IntegInitVpcPrivateSubnet1Subnet259B51C1" + } + } + }, + "IntegInitVpcPrivateSubnet1DefaultRoute654ACECF": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "IntegInitVpcPrivateSubnet1RouteTableCB37994B" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "IntegInitVpcPublicSubnet1NATGateway46F32F7F" + } + } + }, + "IntegInitVpcPrivateSubnet2Subnet1643B059": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + }, + "AvailabilityZone": "test-region-1b", + "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": "integ-init/IntegInitVpc/PrivateSubnet2" + } + ] + } + }, + "IntegInitVpcPrivateSubnet2RouteTable030EC93B": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc/PrivateSubnet2" + } + ] + } + }, + "IntegInitVpcPrivateSubnet2RouteTableAssociation6B52BD72": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "IntegInitVpcPrivateSubnet2RouteTable030EC93B" + }, + "SubnetId": { + "Ref": "IntegInitVpcPrivateSubnet2Subnet1643B059" + } + } + }, + "IntegInitVpcPrivateSubnet2DefaultRoute6A10B6EA": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "IntegInitVpcPrivateSubnet2RouteTable030EC93B" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "IntegInitVpcPublicSubnet2NATGateway9CCB4A9C" + } + } + }, + "IntegInitVpcPrivateSubnet3Subnet2FEDC394": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + }, + "AvailabilityZone": "test-region-1c", + "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": "integ-init/IntegInitVpc/PrivateSubnet3" + } + ] + } + }, + "IntegInitVpcPrivateSubnet3RouteTable276D284C": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc/PrivateSubnet3" + } + ] + } + }, + "IntegInitVpcPrivateSubnet3RouteTableAssociation2706BC76": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "IntegInitVpcPrivateSubnet3RouteTable276D284C" + }, + "SubnetId": { + "Ref": "IntegInitVpcPrivateSubnet3Subnet2FEDC394" + } + } + }, + "IntegInitVpcPrivateSubnet3DefaultRoute932A56DC": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "IntegInitVpcPrivateSubnet3RouteTable276D284C" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "IntegInitVpcPublicSubnet3NATGatewayA7A986C7" + } + } + }, + "IntegInitVpcIGWF019AC85": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "integ-init/IntegInitVpc" + } + ] + } + }, + "IntegInitVpcVPCGW85EDC292": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + }, + "InternetGatewayId": { + "Ref": "IntegInitVpcIGWF019AC85" + } + } + }, "Instance2InstanceSecurityGroupC6129B1D": { "Type": "AWS::EC2::SecurityGroup", "Properties": { @@ -17,7 +531,9 @@ "Value": "integ-init/Instance2" } ], - "VpcId": "vpc-60900905" + "VpcId": { + "Ref": "IntegInitVpc0D4FCCB3" + } } }, "Instance2InstanceRole03DD7CB2": { @@ -130,10 +646,10 @@ ] } }, - "Instance255F352654dd5de862574bd14": { + "Instance255F352651ad64873f230a4d2": { "Type": "AWS::EC2::Instance", "Properties": { - "AvailabilityZone": "us-east-1a", + "AvailabilityZone": "test-region-1a", "IamInstanceProfile": { "Ref": "Instance2InstanceProfile582F915C" }, @@ -149,7 +665,9 @@ ] } ], - "SubnetId": "subnet-e19455ca", + "SubnetId": { + "Ref": "IntegInitVpcPublicSubnet1Subnet41A6F6D4" + }, "Tags": [ { "Key": "Name", @@ -161,7 +679,7 @@ "Fn::Join": [ "", [ - "#!/bin/bash\n# fingerprint: 336ad3625c000098\n(\n set +e\n /opt/aws/bin/cfn-init -v --region ", + "#!/bin/bash\n# fingerprint: 8ef54c03058b2a11\n(\n set +e\n /opt/aws/bin/cfn-init -v --region ", { "Ref": "AWS::Region" }, @@ -169,7 +687,7 @@ { "Ref": "AWS::StackName" }, - " --resource Instance255F352654dd5de862574bd14 -c default\n /opt/aws/bin/cfn-signal -e $? --region ", + " --resource Instance255F352651ad64873f230a4d2 -c default\n /opt/aws/bin/cfn-signal -e $? --region ", { "Ref": "AWS::Region" }, @@ -177,7 +695,7 @@ { "Ref": "AWS::StackName" }, - " --resource Instance255F352654dd5de862574bd14\n cat /var/log/cfn-init.log >&2\n)" + " --resource Instance255F352651ad64873f230a4d2\n cat /var/log/cfn-init.log >&2\n)" ] ] } @@ -230,7 +748,11 @@ "Fn::Join": [ "", [ - "https://s3.test-region.", + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", { "Ref": "AWS::URLSuffix" }, @@ -276,7 +798,9 @@ "Ref": "AWS::StackId" }, "stackName": "integ-init", - "region": "test-region" + "region": { + "Ref": "AWS::Region" + } }, "mode": "000644", "owner": "root", diff --git a/packages/@aws-cdk/aws-ec2/test/integ.instance-init.ts b/packages/@aws-cdk/aws-ec2/test/integ.instance-init.ts index c7c5204fe6e21..2f133693e1165 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.instance-init.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.instance-init.ts @@ -5,14 +5,9 @@ import * as cdk from '@aws-cdk/core'; import * as ec2 from '../lib'; const app = new cdk.App(); -const stack = new cdk.Stack(app, 'integ-init', { - env: { - account: process.env.CDK_INTEG_ACCOUNT || process.env.CDK_DEFAULT_ACCOUNT, - region: process.env.CDK_INTEG_REGION || process.env.CDK_DEFAULT_REGION, - }, -}); +const stack = new cdk.Stack(app, 'integ-init'); -const vpc = ec2.Vpc.fromLookup(stack, 'VPC', { isDefault: true }); +const vpc = new ec2.Vpc(stack, 'IntegInitVpc'); const tmpDir = fs.mkdtempSync('/tmp/cfn-init-test'); fs.writeFileSync(path.resolve(tmpDir, 'testFile'), 'Hello World!\n'); diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service-cn.expected.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service-cn.expected.json deleted file mode 100644 index 99a898633a82f..0000000000000 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service-cn.expected.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "Resources": { - "MyCnVpcEndpointService7463420F": { - "Type": "AWS::EC2::VPCEndpointService", - "Properties": { - "NetworkLoadBalancerArns": [ - "arn:aws-cn:elasticloadbalancing:cn-north-1:123456789012:loadbalancer/net/Test/9bn6qkf4e9jrw77a" - ], - "AcceptanceRequired": false - } - } - }, - "Outputs": { - "MyCnVpcEndpointServiceServiceName": { - "Description": "Give this to service consumers so they can connect via VPC Endpoint", - "Value": { - "Fn::Join": [ - ".", - [ - "cn.com.amazonaws.vpce", - { - "Ref": "AWS::Region" - }, - { - "Ref": "MyCnVpcEndpointService7463420F" - } - ] - ] - }, - "Export": { - "Name": "ServiceName" - } - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service-cn.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service-cn.ts deleted file mode 100644 index 3b67c986477c7..0000000000000 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service-cn.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as cdk from '@aws-cdk/core'; -import * as ec2 from '../lib'; - -const app = new cdk.App(); - -/** - * A load balancer that can host a VPC Endpoint Service - */ -class DummyEndpointLoadBalacer implements ec2.IVpcEndpointServiceLoadBalancer { - /** - * The ARN of the load balancer that hosts the VPC Endpoint Service - */ - public readonly loadBalancerArn: string; - constructor(arn: string) { - this.loadBalancerArn = arn; - } -} - -class CnVpcEndpointServiceStack extends cdk.Stack { - constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { - super(scope, id, props); - - const nlb = new DummyEndpointLoadBalacer( - 'arn:aws-cn:elasticloadbalancing:cn-north-1:123456789012:loadbalancer/net/Test/9bn6qkf4e9jrw77a'); - - const service1 = new ec2.VpcEndpointService(this, 'MyCnVpcEndpointService', { - vpcEndpointServiceLoadBalancers: [nlb], - acceptanceRequired: false, - }); - - new cdk.CfnOutput(this, 'MyCnVpcEndpointServiceServiceName', { - exportName: 'ServiceName', - value: service1.vpcEndpointServiceName, - description: 'Give this to service consumers so they can connect via VPC Endpoint', - }); - - } -} - -new CnVpcEndpointServiceStack(app, 'aws-cdk-ec2-cn-vpc-endpoint-service', { - env: { - account: '123456789012', - region: 'cn-north-1', - }, -}); -app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service.expected.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service.expected.json deleted file mode 100644 index 48b0f9d07d40e..0000000000000 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service.expected.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "Resources": { - "MyVpcEndpointServiceWithNoPrincipals9B24276E": { - "Type": "AWS::EC2::VPCEndpointService", - "Properties": { - "NetworkLoadBalancerArns": [ - "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/net/Test/9bn6qkf4e9jrw77a" - ], - "AcceptanceRequired": false - } - }, - "MyVpcEndpointServiceWithPrincipals41EE2DF2": { - "Type": "AWS::EC2::VPCEndpointService", - "Properties": { - "NetworkLoadBalancerArns": [ - "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/net/Test/1jd81k39sa421ffs" - ], - "AcceptanceRequired": false - } - }, - "MyVpcEndpointServiceWithPrincipalsPermissions29F9BD5A": { - "Type": "AWS::EC2::VPCEndpointServicePermissions", - "Properties": { - "ServiceId": { - "Ref": "MyVpcEndpointServiceWithPrincipals41EE2DF2" - }, - "AllowedPrincipals": [ - "arn:aws:iam::123456789012:root" - ] - } - } - }, - "Outputs": { - "MyVpcEndpointServiceWithNoPrincipalsServiceName": { - "Description": "Give this to service consumers so they can connect via VPC Endpoint", - "Value": { - "Fn::Join": [ - ".", - [ - "com.amazonaws.vpce", - { - "Ref": "AWS::Region" - }, - { - "Ref": "MyVpcEndpointServiceWithNoPrincipals9B24276E" - } - ] - ] - }, - "Export": { - "Name": "ServiceName" - } - }, - "MyVpcEndpointServiceWithPrincipalsEndpointServiceId": { - "Description": "Reference this service from other stacks", - "Value": { - "Ref": "MyVpcEndpointServiceWithPrincipals41EE2DF2" - }, - "Export": { - "Name": "EndpointServiceId" - } - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.expected.json b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.expected.json index 24d55d814adad..9d43a7553f127 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.expected.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.expected.json @@ -10,7 +10,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC" + "Value": "FlowLogsTestStack/VPC" } ] } @@ -18,11 +18,11 @@ "VPCPublicSubnet1SubnetB4246D30": { "Type": "AWS::EC2::Subnet", "Properties": { - "CidrBlock": "10.0.0.0/19", "VpcId": { "Ref": "VPCB9E5F0B4" }, "AvailabilityZone": "test-region-1a", + "CidrBlock": "10.0.0.0/19", "MapPublicIpOnLaunch": true, "Tags": [ { @@ -35,7 +35,7 @@ }, { "Key": "Name", - "Value": "TestStack/VPC/PublicSubnet1" + "Value": "FlowLogsTestStack/VPC/PublicSubnet1" } ] } @@ -49,7 +49,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC/PublicSubnet1" + "Value": "FlowLogsTestStack/VPC/PublicSubnet1" } ] } @@ -87,7 +87,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC/PublicSubnet1" + "Value": "FlowLogsTestStack/VPC/PublicSubnet1" } ] } @@ -107,7 +107,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC/PublicSubnet1" + "Value": "FlowLogsTestStack/VPC/PublicSubnet1" } ] } @@ -115,11 +115,11 @@ "VPCPublicSubnet2Subnet74179F39": { "Type": "AWS::EC2::Subnet", "Properties": { - "CidrBlock": "10.0.32.0/19", "VpcId": { "Ref": "VPCB9E5F0B4" }, "AvailabilityZone": "test-region-1b", + "CidrBlock": "10.0.32.0/19", "MapPublicIpOnLaunch": true, "Tags": [ { @@ -132,7 +132,7 @@ }, { "Key": "Name", - "Value": "TestStack/VPC/PublicSubnet2" + "Value": "FlowLogsTestStack/VPC/PublicSubnet2" } ] } @@ -146,7 +146,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC/PublicSubnet2" + "Value": "FlowLogsTestStack/VPC/PublicSubnet2" } ] } @@ -184,7 +184,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC/PublicSubnet2" + "Value": "FlowLogsTestStack/VPC/PublicSubnet2" } ] } @@ -204,7 +204,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC/PublicSubnet2" + "Value": "FlowLogsTestStack/VPC/PublicSubnet2" } ] } @@ -212,11 +212,11 @@ "VPCPublicSubnet3Subnet631C5E25": { "Type": "AWS::EC2::Subnet", "Properties": { - "CidrBlock": "10.0.64.0/19", "VpcId": { "Ref": "VPCB9E5F0B4" }, "AvailabilityZone": "test-region-1c", + "CidrBlock": "10.0.64.0/19", "MapPublicIpOnLaunch": true, "Tags": [ { @@ -229,7 +229,7 @@ }, { "Key": "Name", - "Value": "TestStack/VPC/PublicSubnet3" + "Value": "FlowLogsTestStack/VPC/PublicSubnet3" } ] } @@ -243,7 +243,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC/PublicSubnet3" + "Value": "FlowLogsTestStack/VPC/PublicSubnet3" } ] } @@ -281,7 +281,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC/PublicSubnet3" + "Value": "FlowLogsTestStack/VPC/PublicSubnet3" } ] } @@ -301,7 +301,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC/PublicSubnet3" + "Value": "FlowLogsTestStack/VPC/PublicSubnet3" } ] } @@ -309,11 +309,11 @@ "VPCPrivateSubnet1Subnet8BCA10E0": { "Type": "AWS::EC2::Subnet", "Properties": { - "CidrBlock": "10.0.96.0/19", "VpcId": { "Ref": "VPCB9E5F0B4" }, "AvailabilityZone": "test-region-1a", + "CidrBlock": "10.0.96.0/19", "MapPublicIpOnLaunch": false, "Tags": [ { @@ -326,7 +326,7 @@ }, { "Key": "Name", - "Value": "TestStack/VPC/PrivateSubnet1" + "Value": "FlowLogsTestStack/VPC/PrivateSubnet1" } ] } @@ -340,7 +340,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC/PrivateSubnet1" + "Value": "FlowLogsTestStack/VPC/PrivateSubnet1" } ] } @@ -371,11 +371,11 @@ "VPCPrivateSubnet2SubnetCFCDAA7A": { "Type": "AWS::EC2::Subnet", "Properties": { - "CidrBlock": "10.0.128.0/19", "VpcId": { "Ref": "VPCB9E5F0B4" }, "AvailabilityZone": "test-region-1b", + "CidrBlock": "10.0.128.0/19", "MapPublicIpOnLaunch": false, "Tags": [ { @@ -388,7 +388,7 @@ }, { "Key": "Name", - "Value": "TestStack/VPC/PrivateSubnet2" + "Value": "FlowLogsTestStack/VPC/PrivateSubnet2" } ] } @@ -402,7 +402,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC/PrivateSubnet2" + "Value": "FlowLogsTestStack/VPC/PrivateSubnet2" } ] } @@ -433,11 +433,11 @@ "VPCPrivateSubnet3Subnet3EDCD457": { "Type": "AWS::EC2::Subnet", "Properties": { - "CidrBlock": "10.0.160.0/19", "VpcId": { "Ref": "VPCB9E5F0B4" }, "AvailabilityZone": "test-region-1c", + "CidrBlock": "10.0.160.0/19", "MapPublicIpOnLaunch": false, "Tags": [ { @@ -450,7 +450,7 @@ }, { "Key": "Name", - "Value": "TestStack/VPC/PrivateSubnet3" + "Value": "FlowLogsTestStack/VPC/PrivateSubnet3" } ] } @@ -464,7 +464,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC/PrivateSubnet3" + "Value": "FlowLogsTestStack/VPC/PrivateSubnet3" } ] } @@ -498,7 +498,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC" + "Value": "FlowLogsTestStack/VPC" } ] } @@ -520,7 +520,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC" + "Value": "FlowLogsTestStack/VPC" } ] }, @@ -545,7 +545,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC" + "Value": "FlowLogsTestStack/VPC" } ] } @@ -576,7 +576,7 @@ "Tags": [ { "Key": "Name", - "Value": "TestStack/VPC" + "Value": "FlowLogsTestStack/VPC" } ] } @@ -668,8 +668,290 @@ }, "Bucket83908E77": { "Type": "AWS::S3::Bucket", + "Properties": { + "Tags": [ + { + "Key": "aws-cdk:auto-delete-objects", + "Value": "true" + } + ] + }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" + }, + "BucketPolicyE9A3008A": { + "Type": "AWS::S3::BucketPolicy", + "Properties": { + "Bucket": { + "Ref": "Bucket83908E77" + }, + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + } + }, + "Resource": [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "StringEquals": { + "s3:x-amz-acl": "bucket-owner-full-control", + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + }, + "ArnLike": { + "aws:SourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":*" + ] + ] + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "delivery.logs.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "/AWSLogs/", + { + "Ref": "AWS::AccountId" + }, + "/*" + ] + ] + } + }, + { + "Action": [ + "s3:GetBucketAcl", + "s3:ListBucket" + ], + "Condition": { + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + }, + "ArnLike": { + "aws:SourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":*" + ] + ] + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "delivery.logs.amazonaws.com" + }, + "Resource": { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "BucketAutoDeleteObjectsCustomResourceBAFD23C2": { + "Type": "Custom::S3AutoDeleteObjects", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", + "Arn" + ] + }, + "BucketName": { + "Ref": "Bucket83908E77" + } + }, + "DependsOn": [ + "BucketPolicyE9A3008A" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ] + } + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3Bucket09A62232" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3VersionKeyA28118BE" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3VersionKeyA28118BE" + } + ] + } + ] + } + ] + ] + } + }, + "Timeout": 900, + "MemorySize": 128, + "Handler": "__entrypoint__.handler", + "Role": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + }, + "Runtime": "nodejs12.x", + "Description": { + "Fn::Join": [ + "", + [ + "Lambda function for auto-deleting objects in ", + { + "Ref": "Bucket83908E77" + }, + " S3 bucket." + ] + ] + } + }, + "DependsOn": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092" + ] + } + }, + "Parameters": { + "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3Bucket09A62232": { + "Type": "String", + "Description": "S3 bucket for asset \"be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824\"" + }, + "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824S3VersionKeyA28118BE": { + "Type": "String", + "Description": "S3 key for asset version \"be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824\"" + }, + "AssetParametersbe270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824ArtifactHash76F8FCF2": { + "Type": "String", + "Description": "Artifact hash for asset \"be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92824\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.ts index c9b87c51bf7fd..6ce95c09bb662 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-flow-logs.ts @@ -1,4 +1,5 @@ /// !cdk-integ * +import { PolicyStatement, Effect, ServicePrincipal } from '@aws-cdk/aws-iam'; import * as s3 from '@aws-cdk/aws-s3'; import { App, RemovalPolicy, Stack, StackProps } from '@aws-cdk/core'; import { FlowLog, FlowLogDestination, FlowLogResourceType, Vpc } from '../lib'; @@ -21,7 +22,43 @@ class TestStack extends Stack { const bucket = new s3.Bucket(this, 'Bucket', { removalPolicy: RemovalPolicy.DESTROY, + autoDeleteObjects: true, }); + bucket.addToResourcePolicy(new PolicyStatement({ + effect: Effect.ALLOW, + principals: [new ServicePrincipal('delivery.logs.amazonaws.com')], + actions: ['s3:PutObject'], + resources: [bucket.arnForObjects(`AWSLogs/${this.account}/*`)], + conditions: { + StringEquals: { + 's3:x-amz-acl': 'bucket-owner-full-control', + 'aws:SourceAccount': this.account, + }, + ArnLike: { + 'aws:SourceArn': this.formatArn({ + service: 'logs', + resource: '*', + }), + }, + }, + })); + bucket.addToResourcePolicy(new PolicyStatement({ + effect: Effect.ALLOW, + principals: [new ServicePrincipal('delivery.logs.amazonaws.com')], + actions: ['s3:GetBucketAcl', 's3:ListBucket'], + resources: [bucket.bucketArn], + conditions: { + StringEquals: { + 'aws:SourceAccount': this.account, + }, + ArnLike: { + 'aws:SourceArn': this.formatArn({ + service: 'logs', + resource: '*', + }), + }, + }, + })); vpc.addFlowLog('FlowLogsS3KeyPrefix', { destination: FlowLogDestination.toS3(bucket, 'prefix/'), @@ -29,6 +66,6 @@ class TestStack extends Stack { } } -new TestStack(app, 'TestStack'); +new TestStack(app, 'FlowLogsTestStack'); app.synth(); diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpn-pre-shared-key-token.expected.json b/packages/@aws-cdk/aws-ec2/test/integ.vpn-pre-shared-key-token.expected.json index e35654d4ac5ac..7895454898cbc 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpn-pre-shared-key-token.expected.json +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpn-pre-shared-key-token.expected.json @@ -18,11 +18,11 @@ "MyVpcPublicSubnet1SubnetF6608456": { "Type": "AWS::EC2::Subnet", "Properties": { - "CidrBlock": "10.10.0.0/19", "VpcId": { "Ref": "MyVpcF9F0CA6F" }, "AvailabilityZone": "test-region-1a", + "CidrBlock": "10.10.0.0/19", "MapPublicIpOnLaunch": true, "Tags": [ { @@ -95,15 +95,15 @@ "MyVpcPublicSubnet1NATGatewayAD3400C1": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "MyVpcPublicSubnet1SubnetF6608456" + }, "AllocationId": { "Fn::GetAtt": [ "MyVpcPublicSubnet1EIP096967CB", "AllocationId" ] }, - "SubnetId": { - "Ref": "MyVpcPublicSubnet1SubnetF6608456" - }, "Tags": [ { "Key": "Name", @@ -115,11 +115,11 @@ "MyVpcPublicSubnet2Subnet492B6BFB": { "Type": "AWS::EC2::Subnet", "Properties": { - "CidrBlock": "10.10.32.0/19", "VpcId": { "Ref": "MyVpcF9F0CA6F" }, "AvailabilityZone": "test-region-1b", + "CidrBlock": "10.10.32.0/19", "MapPublicIpOnLaunch": true, "Tags": [ { @@ -192,15 +192,15 @@ "MyVpcPublicSubnet2NATGateway91BFBEC9": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" + }, "AllocationId": { "Fn::GetAtt": [ "MyVpcPublicSubnet2EIP8CCBA239", "AllocationId" ] }, - "SubnetId": { - "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" - }, "Tags": [ { "Key": "Name", @@ -212,11 +212,11 @@ "MyVpcPublicSubnet3Subnet57EEE236": { "Type": "AWS::EC2::Subnet", "Properties": { - "CidrBlock": "10.10.64.0/19", "VpcId": { "Ref": "MyVpcF9F0CA6F" }, "AvailabilityZone": "test-region-1c", + "CidrBlock": "10.10.64.0/19", "MapPublicIpOnLaunch": true, "Tags": [ { @@ -289,15 +289,15 @@ "MyVpcPublicSubnet3NATGatewayD4B50EBE": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "MyVpcPublicSubnet3Subnet57EEE236" + }, "AllocationId": { "Fn::GetAtt": [ "MyVpcPublicSubnet3EIPC5ACADAB", "AllocationId" ] }, - "SubnetId": { - "Ref": "MyVpcPublicSubnet3Subnet57EEE236" - }, "Tags": [ { "Key": "Name", @@ -309,11 +309,11 @@ "MyVpcPrivateSubnet1Subnet5057CF7E": { "Type": "AWS::EC2::Subnet", "Properties": { - "CidrBlock": "10.10.96.0/19", "VpcId": { "Ref": "MyVpcF9F0CA6F" }, "AvailabilityZone": "test-region-1a", + "CidrBlock": "10.10.96.0/19", "MapPublicIpOnLaunch": false, "Tags": [ { @@ -371,11 +371,11 @@ "MyVpcPrivateSubnet2Subnet0040C983": { "Type": "AWS::EC2::Subnet", "Properties": { - "CidrBlock": "10.10.128.0/19", "VpcId": { "Ref": "MyVpcF9F0CA6F" }, "AvailabilityZone": "test-region-1b", + "CidrBlock": "10.10.128.0/19", "MapPublicIpOnLaunch": false, "Tags": [ { @@ -433,11 +433,11 @@ "MyVpcPrivateSubnet3Subnet772D6AD7": { "Type": "AWS::EC2::Subnet", "Properties": { - "CidrBlock": "10.10.160.0/19", "VpcId": { "Ref": "MyVpcF9F0CA6F" }, "AvailabilityZone": "test-region-1c", + "CidrBlock": "10.10.160.0/19", "MapPublicIpOnLaunch": false, "Tags": [ { @@ -592,7 +592,7 @@ }, "VpnTunnelOptionsSpecifications": [ { - "PreSharedKey": "{{resolve:ssm-secure:ssm-pw:1}}" + "PreSharedKey": "ssmpwaaa" } ] } diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpn-pre-shared-key-token.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpn-pre-shared-key-token.ts index fb5bb45119b08..a4747938c57e8 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpn-pre-shared-key-token.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpn-pre-shared-key-token.ts @@ -11,7 +11,7 @@ const vpc = new ec2.Vpc(stack, 'MyVpc', { ip: '52.85.255.164', tunnelOptions: [ { - preSharedKey: cdk.SecretValue.ssmSecure('ssm-pw', '1').toString(), + preSharedKey: cdk.Lazy.string({ produce: () => 'ssmpwaaa' }), }, ], }, diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.vpc-endpoint-service.expected.json b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.vpc-endpoint-service.expected.json new file mode 100644 index 0000000000000..18a3482e70715 --- /dev/null +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.vpc-endpoint-service.expected.json @@ -0,0 +1,630 @@ +{ + "Resources": { + "VPCB9E5F0B4": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC" + } + ] + } + }, + "VPCPublicSubnet1SubnetB4246D30": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1a", + "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": "aws-cdk-ec2-vpc-endpoint-service/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1RouteTableFEE4B781": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1RouteTableAssociation0B0896DC": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "VPCPublicSubnet1DefaultRoute91CEF279": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet1EIP6AD938E8": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1NATGatewayE0556630": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet2Subnet74179F39": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1b", + "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": "aws-cdk-ec2-vpc-endpoint-service/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2RouteTable6F1A15F1": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2RouteTableAssociation5A808732": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "VPCPublicSubnet2DefaultRouteB7481BBA": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet2EIP4947BC00": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2NATGateway3C070193": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet3Subnet631C5E25": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1c", + "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": "aws-cdk-ec2-vpc-endpoint-service/VPC/PublicSubnet3" + } + ] + } + }, + "VPCPublicSubnet3RouteTable98AE0E14": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC/PublicSubnet3" + } + ] + } + }, + "VPCPublicSubnet3RouteTableAssociation427FE0C6": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet3RouteTable98AE0E14" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet3Subnet631C5E25" + } + } + }, + "VPCPublicSubnet3DefaultRouteA0D29D46": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet3RouteTable98AE0E14" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet3EIPAD4BC883": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC/PublicSubnet3" + } + ] + } + }, + "VPCPublicSubnet3NATGatewayD3048F5C": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet3Subnet631C5E25" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet3EIPAD4BC883", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC/PublicSubnet3" + } + ] + } + }, + "VPCPrivateSubnet1Subnet8BCA10E0": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1a", + "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": "aws-cdk-ec2-vpc-endpoint-service/VPC/PrivateSubnet1" + } + ] + } + }, + "VPCPrivateSubnet1RouteTableBE8A6027": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC/PrivateSubnet1" + } + ] + } + }, + "VPCPrivateSubnet1RouteTableAssociation347902D1": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "VPCPrivateSubnet1DefaultRouteAE1D6490": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + } + } + }, + "VPCPrivateSubnet2SubnetCFCDAA7A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1b", + "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": "aws-cdk-ec2-vpc-endpoint-service/VPC/PrivateSubnet2" + } + ] + } + }, + "VPCPrivateSubnet2RouteTable0A19E10E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC/PrivateSubnet2" + } + ] + } + }, + "VPCPrivateSubnet2RouteTableAssociation0C73D413": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "VPCPrivateSubnet2DefaultRouteF4F5CFD2": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet2NATGateway3C070193" + } + } + }, + "VPCPrivateSubnet3Subnet3EDCD457": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1c", + "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": "aws-cdk-ec2-vpc-endpoint-service/VPC/PrivateSubnet3" + } + ] + } + }, + "VPCPrivateSubnet3RouteTable192186F8": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC/PrivateSubnet3" + } + ] + } + }, + "VPCPrivateSubnet3RouteTableAssociationC28D144E": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet3RouteTable192186F8" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet3Subnet3EDCD457" + } + } + }, + "VPCPrivateSubnet3DefaultRoute27F311AE": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet3RouteTable192186F8" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet3NATGatewayD3048F5C" + } + } + }, + "VPCIGWB7E252D3": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint-service/VPC" + } + ] + } + }, + "VPCVPCGW99B986DC": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "InternetGatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "NLBNoPrincipals25B7CFB1": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "LoadBalancerAttributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "false" + } + ], + "Scheme": "internal", + "Subnets": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + }, + { + "Ref": "VPCPrivateSubnet3Subnet3EDCD457" + } + ], + "Type": "network" + } + }, + "MyVpcEndpointServiceWithNoPrincipals9B24276E": { + "Type": "AWS::EC2::VPCEndpointService", + "Properties": { + "AcceptanceRequired": false, + "NetworkLoadBalancerArns": [ + { + "Ref": "NLBNoPrincipals25B7CFB1" + } + ] + } + }, + "NLBWithPrincipals912E28FF": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "LoadBalancerAttributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "false" + } + ], + "Scheme": "internal", + "Subnets": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + }, + { + "Ref": "VPCPrivateSubnet3Subnet3EDCD457" + } + ], + "Type": "network" + } + }, + "MyVpcEndpointServiceWithPrincipals41EE2DF2": { + "Type": "AWS::EC2::VPCEndpointService", + "Properties": { + "AcceptanceRequired": false, + "NetworkLoadBalancerArns": [ + { + "Ref": "NLBWithPrincipals912E28FF" + } + ] + } + }, + "MyVpcEndpointServiceWithPrincipalsPermissions29F9BD5A": { + "Type": "AWS::EC2::VPCEndpointServicePermissions", + "Properties": { + "ServiceId": { + "Ref": "MyVpcEndpointServiceWithPrincipals41EE2DF2" + }, + "AllowedPrincipals": [ + "arn:aws:iam::123456789012:root" + ] + } + } + }, + "Outputs": { + "MyVpcEndpointServiceWithNoPrincipalsServiceName": { + "Description": "Give this to service consumers so they can connect via VPC Endpoint", + "Value": { + "Fn::Join": [ + ".", + [ + "com.amazonaws.vpce", + { + "Ref": "AWS::Region" + }, + { + "Ref": "MyVpcEndpointServiceWithNoPrincipals9B24276E" + } + ] + ] + }, + "Export": { + "Name": "ServiceName" + } + }, + "MyVpcEndpointServiceWithPrincipalsEndpointServiceId": { + "Description": "Reference this service from other stacks", + "Value": { + "Ref": "MyVpcEndpointServiceWithPrincipals41EE2DF2" + }, + "Export": { + "Name": "EndpointServiceId" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.vpc-endpoint-service.ts similarity index 66% rename from packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service.ts rename to packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.vpc-endpoint-service.ts index 01d22ea92c444..92a39f118637c 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint-service.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.vpc-endpoint-service.ts @@ -1,28 +1,18 @@ +import * as ec2 from '@aws-cdk/aws-ec2'; import { ArnPrincipal } from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; -import * as ec2 from '../lib'; +import * as elbv2 from '../lib'; const app = new cdk.App(); -/** - * A load balancer that can host a VPC Endpoint Service - */ -class DummyEndpointLoadBalacer implements ec2.IVpcEndpointServiceLoadBalancer { - /** - * The ARN of the load balancer that hosts the VPC Endpoint Service - */ - public readonly loadBalancerArn: string; - constructor(arn: string) { - this.loadBalancerArn = arn; - } -} - class VpcEndpointServiceStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); - const nlbNoPrincipals = new DummyEndpointLoadBalacer( - 'arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/net/Test/9bn6qkf4e9jrw77a'); + const vpc = new ec2.Vpc(this, 'VPC'); + const nlbNoPrincipals = new elbv2.NetworkLoadBalancer(this, 'NLBNoPrincipals', { + vpc, + }); const service1 = new ec2.VpcEndpointService(this, 'MyVpcEndpointServiceWithNoPrincipals', { vpcEndpointServiceLoadBalancers: [nlbNoPrincipals], @@ -30,8 +20,9 @@ class VpcEndpointServiceStack extends cdk.Stack { allowedPrincipals: [], }); - const nlbWithPrincipals = new DummyEndpointLoadBalacer( - 'arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/net/Test/1jd81k39sa421ffs'); + const nlbWithPrincipals = new elbv2.NetworkLoadBalancer(this, 'NLBWithPrincipals', { + vpc, + }); const principalArn = new ArnPrincipal('arn:aws:iam::123456789012:root'); const service2 = new ec2.VpcEndpointService(this, 'MyVpcEndpointServiceWithPrincipals', { From 7f26fad5241756cdb6b15c9fb20995a96bba71f2 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 1 Apr 2022 21:58:37 +0200 Subject: [PATCH 2/6] fix(core): `Fn.select` incorrectly short-circuits complex expressions (#19680) In CloudFormation, it is possible to do the following: ``` 'Fn::Select': - 0 - - { 'Fn::If': ['Cond1', 'Value1', { Ref: 'AWS::NoValue' } } - { 'Fn::If': ['Cond2', 'Value2', { Ref: 'AWS::NoValue' } } - { 'Fn::If': ['Cond3', 'Value3', { Ref: 'AWS::NoValue' } } ``` Because the `AWS::NoValue`s will disappear from the array, this will evaluate to the first condition that is true. CDK is unlikely to generate expressions like this, but people may have written this in CloudFormation templates. The eager short-circuiting behavior of `Fn.select` was breaking the roundtrippability of this template's condition cascade through `cloudformation-include`, by unconditionally picking out the first element from the array. We can't get rid of the short-circuiting completely (as bunch of templates and tests may already depend on it), but we can catch this happening and guard against it, by not short-circuiting if we can't look into all values. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../fn-select-with-novalue.json | 23 +++++++++++++++++++ .../test/valid-templates.test.ts | 8 +++++++ packages/@aws-cdk/core/lib/cfn-fn.ts | 2 +- packages/@aws-cdk/core/test/fn.test.ts | 18 ++++++++++++++- 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 packages/@aws-cdk/cloudformation-include/test/test-templates/fn-select-with-novalue.json diff --git a/packages/@aws-cdk/cloudformation-include/test/test-templates/fn-select-with-novalue.json b/packages/@aws-cdk/cloudformation-include/test/test-templates/fn-select-with-novalue.json new file mode 100644 index 0000000000000..861387e330ee7 --- /dev/null +++ b/packages/@aws-cdk/cloudformation-include/test/test-templates/fn-select-with-novalue.json @@ -0,0 +1,23 @@ +{ + "Parameters": { + "DoIt": { + "Type": "String" + } + }, + "Conditions": { + "MyCondition": { + "Fn::Equals": [{ "Ref": "DoIt" }, "Yes"] + } + }, + "Resources": { + "Bucket": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketName": { "Fn::Select": [0, [ + { "Fn::If": ["MyCondition", "doing-it", { "Ref": "AWS::NoValue" }] }, + "not-doingit" + ]]} + } + } + } +} diff --git a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts index 65cd7e981cc81..eec714ac5d7d6 100644 --- a/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts +++ b/packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts @@ -1081,6 +1081,14 @@ describe('CDK Include', () => { loadTestFileToJsObject('properties-not-in-cfn-spec.json'), ); }); + + test('roundtrip a fn-select with a fn-if/ref-novalue in it', () => { + includeTestTemplate(stack, 'fn-select-with-novalue.json'); + + Template.fromStack(stack).templateMatches( + loadTestFileToJsObject('fn-select-with-novalue.json'), + ); + }); }); interface IncludeTestTemplateProps { diff --git a/packages/@aws-cdk/core/lib/cfn-fn.ts b/packages/@aws-cdk/core/lib/cfn-fn.ts index 3ef1c265654bd..673784e0e2a5b 100644 --- a/packages/@aws-cdk/core/lib/cfn-fn.ts +++ b/packages/@aws-cdk/core/lib/cfn-fn.ts @@ -127,7 +127,7 @@ export class Fn { * @returns a token represented as a string */ public static select(index: number, array: string[]): string { - if (!Token.isUnresolved(array)) { + if (!Token.isUnresolved(index) && !Token.isUnresolved(array) && !array.some(Token.isUnresolved)) { return array[index]; } diff --git a/packages/@aws-cdk/core/test/fn.test.ts b/packages/@aws-cdk/core/test/fn.test.ts index 221a7b6e811a1..343c3e0ea0422 100644 --- a/packages/@aws-cdk/core/test/fn.test.ts +++ b/packages/@aws-cdk/core/test/fn.test.ts @@ -1,6 +1,6 @@ import * as fc from 'fast-check'; import * as _ from 'lodash'; -import { App, CfnOutput, Fn, Stack, Token } from '../lib'; +import { App, Aws, CfnOutput, Fn, Stack, Token } from '../lib'; import { Intrinsic } from '../lib/private/intrinsic'; function asyncTest(cb: () => Promise): () => void { @@ -27,8 +27,24 @@ describe('fn', () => { describe('eager resolution for non-tokens', () => { test('Fn.select', () => { expect(Fn.select(2, ['hello', 'you', 'dude'])).toEqual('dude'); + }); + + test('Fn.select does not short-circuit if there are tokens in the array', () => { + const stack = new Stack(); + expect(stack.resolve(Fn.select(2, [ + Fn.conditionIf('xyz', 'yep', Aws.NO_VALUE).toString(), + 'you', + 'dude', + ]))).toEqual({ + 'Fn::Select': [2, [ + { 'Fn::If': ['xyz', 'yep', { Ref: 'AWS::NoValue' }] }, + 'you', + 'dude', + ]], + }); }); + test('Fn.split', () => { expect(Fn.split(':', 'hello:world:yeah')).toEqual(['hello', 'world', 'yeah']); From 77a5fa1f0ecc2dcaa270212c8d61479f9a1c8ccd Mon Sep 17 00:00:00 2001 From: Peter Woodworth <44349620+peterwoodworth@users.noreply.github.com> Date: Fri, 1 Apr 2022 14:01:44 -0700 Subject: [PATCH 3/6] chore: use pat token for pr triage (#19727) ---- ### All Submissions: * [ ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/master/INTEGRATION_TESTS.md)? * [ ] Did you use `cdk-integ` to deploy the infrastructure and generate the snapshot (i.e. `cdk-integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .github/workflows/issue-label-assign.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/issue-label-assign.yml b/.github/workflows/issue-label-assign.yml index b38072a275697..e581de6146a03 100644 --- a/.github/workflows/issue-label-assign.yml +++ b/.github/workflows/issue-label-assign.yml @@ -48,7 +48,7 @@ jobs: steps: - uses: aws-github-ops/aws-issue-triage-manager@main with: - github-token: "${{ secrets.GITHUB_TOKEN }}" + github-token: "${{ secrets.PROJEN_GITHUB_TOKEN }}" target: "pull-requests" area-is-keyword: true default-area: > From 91850423db97e7fa244d125a115477fa007a12a0 Mon Sep 17 00:00:00 2001 From: Mina Asham Date: Sat, 2 Apr 2022 01:14:41 +0100 Subject: [PATCH 4/6] fix(codedeploy): add name validation for Application, Deployment Group and Deployment Configuration (#19473) - Naming rules from: https://docs.aws.amazon.com/codedeploy/latest/userguide/limits.html ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](../CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](../CONTRIBUTING.md/#adding-new-unconventional-dependencies) *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-codedeploy/lib/ecs/application.ts | 6 ++++- .../aws-codedeploy/lib/lambda/application.ts | 6 ++++- .../lib/lambda/custom-deployment-config.ts | 6 ++++- .../lib/lambda/deployment-group.ts | 6 ++++- .../aws-codedeploy/lib/server/application.ts | 6 ++++- .../lib/server/deployment-config.ts | 6 ++++- .../lib/server/deployment-group.ts | 6 ++++- packages/@aws-cdk/aws-codedeploy/lib/utils.ts | 17 +++++++++++- .../test/ecs/application.test.ts | 20 ++++++++++++++ .../test/lambda/application.test.ts | 20 ++++++++++++++ .../lambda/custom-deployment-config.test.ts | 26 +++++++++++++++++++ .../test/lambda/deployment-group.test.ts | 24 +++++++++++++++++ .../test/server/deployment-config.test.ts | 22 ++++++++++++++++ .../test/server/deployment-group.test.ts | 21 +++++++++++++++ 14 files changed, 184 insertions(+), 8 deletions(-) diff --git a/packages/@aws-cdk/aws-codedeploy/lib/ecs/application.ts b/packages/@aws-cdk/aws-codedeploy/lib/ecs/application.ts index dc136abb87ee4..77ef2af9c416c 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/ecs/application.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/ecs/application.ts @@ -1,7 +1,7 @@ import { ArnFormat, IResource, Resource } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnApplication } from '../codedeploy.generated'; -import { arnForApplication } from '../utils'; +import { arnForApplication, validateName } from '../utils'; /** * Represents a reference to a CodeDeploy Application deploying to Amazon ECS. @@ -77,4 +77,8 @@ export class EcsApplication extends Resource implements IEcsApplication { arnFormat: ArnFormat.COLON_RESOURCE_NAME, }); } + + protected validate(): string[] { + return validateName('Application', this.physicalName); + } } diff --git a/packages/@aws-cdk/aws-codedeploy/lib/lambda/application.ts b/packages/@aws-cdk/aws-codedeploy/lib/lambda/application.ts index 03449cf00b229..321fb50ca0689 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/lambda/application.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/lambda/application.ts @@ -1,7 +1,7 @@ import { ArnFormat, IResource, Resource } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnApplication } from '../codedeploy.generated'; -import { arnForApplication } from '../utils'; +import { arnForApplication, validateName } from '../utils'; /** * Represents a reference to a CodeDeploy Application deploying to AWS Lambda. @@ -77,4 +77,8 @@ export class LambdaApplication extends Resource implements ILambdaApplication { arnFormat: ArnFormat.COLON_RESOURCE_NAME, }); } + + protected validate(): string[] { + return validateName('Application', this.physicalName); + } } diff --git a/packages/@aws-cdk/aws-codedeploy/lib/lambda/custom-deployment-config.ts b/packages/@aws-cdk/aws-codedeploy/lib/lambda/custom-deployment-config.ts index 55077fe93f273..85d20d77d942a 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/lambda/custom-deployment-config.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/lambda/custom-deployment-config.ts @@ -1,7 +1,7 @@ import { Duration, Names, Resource } from '@aws-cdk/core'; import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId } from '@aws-cdk/custom-resources'; import { Construct } from 'constructs'; -import { arnForDeploymentConfig } from '../utils'; +import { arnForDeploymentConfig, validateName } from '../utils'; import { ILambdaDeploymentConfig } from './deployment-config'; /** @@ -143,6 +143,10 @@ export class CustomLambdaDeploymentConfig extends Resource implements ILambdaDep }); } + protected validate(): string[] { + return validateName('Deployment config', this.deploymentConfigName); + } + // Validate the inputs. The percentage/interval limits come from CodeDeploy private validateParameters(props: CustomLambdaDeploymentConfigProps): void { if ( !(1 <= props.percentage && props.percentage <= 99) ) { diff --git a/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts index 2449ff87f31fd..3f009d93a9477 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts @@ -5,7 +5,7 @@ import * as cdk from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnDeploymentGroup } from '../codedeploy.generated'; import { AutoRollbackConfig } from '../rollback-config'; -import { arnForDeploymentGroup, renderAlarmConfiguration, renderAutoRollbackConfiguration } from '../utils'; +import { arnForDeploymentGroup, renderAlarmConfiguration, renderAutoRollbackConfiguration, validateName } from '../utils'; import { ILambdaApplication, LambdaApplication } from './application'; import { ILambdaDeploymentConfig, LambdaDeploymentConfig } from './deployment-config'; @@ -254,6 +254,10 @@ export class LambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploy actions: ['codedeploy:PutLifecycleEventHookExecutionStatus'], }); } + + protected validate(): string[] { + return validateName('Deployment group', this.physicalName); + } } /** diff --git a/packages/@aws-cdk/aws-codedeploy/lib/server/application.ts b/packages/@aws-cdk/aws-codedeploy/lib/server/application.ts index b6f7324ef5985..fd596ca3bb0fb 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/server/application.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/server/application.ts @@ -1,7 +1,7 @@ import { ArnFormat, IResource, Resource } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnApplication } from '../codedeploy.generated'; -import { arnForApplication } from '../utils'; +import { arnForApplication, validateName } from '../utils'; /** * Represents a reference to a CodeDeploy Application deploying to EC2/on-premise instances. @@ -78,4 +78,8 @@ export class ServerApplication extends Resource implements IServerApplication { arnFormat: ArnFormat.COLON_RESOURCE_NAME, }); } + + protected validate(): string[] { + return validateName('Application', this.physicalName); + } } diff --git a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-config.ts b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-config.ts index 058fad91341ad..18239217472c1 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-config.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-config.ts @@ -1,7 +1,7 @@ import * as cdk from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnDeploymentConfig } from '../codedeploy.generated'; -import { arnForDeploymentConfig } from '../utils'; +import { arnForDeploymentConfig, validateName } from '../utils'; /** * The Deployment Configuration of an EC2/on-premise Deployment Group. @@ -119,6 +119,10 @@ export class ServerDeploymentConfig extends cdk.Resource implements IServerDeplo this.deploymentConfigName = resource.ref; this.deploymentConfigArn = arnForDeploymentConfig(this.deploymentConfigName); } + + protected validate(): string[] { + return validateName('Deployment config', this.physicalName); + } } function deploymentConfig(name: string): IServerDeploymentConfig { diff --git a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts index f4f3cad0774cc..59ec7afa65170 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts @@ -8,7 +8,7 @@ import { ArnFormat } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnDeploymentGroup } from '../codedeploy.generated'; import { AutoRollbackConfig } from '../rollback-config'; -import { arnForDeploymentGroup, renderAlarmConfiguration, renderAutoRollbackConfiguration } from '../utils'; +import { arnForDeploymentGroup, renderAlarmConfiguration, renderAutoRollbackConfiguration, validateName } from '../utils'; import { IServerApplication, ServerApplication } from './application'; import { IServerDeploymentConfig, ServerDeploymentConfig } from './deployment-config'; import { LoadBalancer, LoadBalancerGeneration } from './load-balancer'; @@ -341,6 +341,10 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupBase { return this._autoScalingGroups.slice(); } + protected validate(): string[] { + return validateName('Deployment group', this.physicalName); + } + private addCodeDeployAgentInstallUserData(asg: autoscaling.IAutoScalingGroup): void { if (!this.installAgent) { return; diff --git a/packages/@aws-cdk/aws-codedeploy/lib/utils.ts b/packages/@aws-cdk/aws-codedeploy/lib/utils.ts index 7bdf6bc9162da..6c5381b0de96b 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/utils.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/utils.ts @@ -1,5 +1,5 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; -import { Aws } from '@aws-cdk/core'; +import { Aws, Token } from '@aws-cdk/core'; import { CfnDeploymentGroup } from './codedeploy.generated'; import { AutoRollbackConfig } from './rollback-config'; @@ -65,3 +65,18 @@ CfnDeploymentGroup.AutoRollbackConfigurationProperty | undefined { } : undefined; } + +export function validateName(type: 'Application' | 'Deployment group' | 'Deployment config', name: string): string[] { + const ret = []; + + if (!Token.isUnresolved(name) && name !== undefined) { + if (name.length > 100) { + ret.push(`${type} name: "${name}" can be a max of 100 characters.`); + } + if (!/^[a-z0-9._+=,@-]+$/i.test(name)) { + ret.push(`${type} name: "${name}" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).`); + } + } + + return ret; +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codedeploy/test/ecs/application.test.ts b/packages/@aws-cdk/aws-codedeploy/test/ecs/application.test.ts index ec130559aaff8..a5661c3538f14 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/ecs/application.test.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/ecs/application.test.ts @@ -23,4 +23,24 @@ describe('CodeDeploy ECS Application', () => { ComputePlatform: 'ECS', }); }); + + test('fail with more than 100 characters in name', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app); + new codedeploy.EcsApplication(stack, 'MyApp', { + applicationName: 'a'.repeat(101), + }); + + expect(() => app.synth()).toThrow(`Application name: "${'a'.repeat(101)}" can be a max of 100 characters.`); + }); + + test('fail with unallowed characters in name', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app); + new codedeploy.EcsApplication(stack, 'MyApp', { + applicationName: 'my name', + }); + + expect(() => app.synth()).toThrow('Application name: "my name" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).'); + }); }); diff --git a/packages/@aws-cdk/aws-codedeploy/test/lambda/application.test.ts b/packages/@aws-cdk/aws-codedeploy/test/lambda/application.test.ts index 6ccbd816935ba..4b870c53c0e1d 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/lambda/application.test.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/lambda/application.test.ts @@ -21,4 +21,24 @@ describe('CodeDeploy Lambda Application', () => { ComputePlatform: 'Lambda', }); }); + + test('fail with more than 100 characters in name', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app); + new codedeploy.LambdaApplication(stack, 'MyApp', { + applicationName: 'a'.repeat(101), + }); + + expect(() => app.synth()).toThrow(`Application name: "${'a'.repeat(101)}" can be a max of 100 characters.`); + }); + + test('fail with unallowed characters in name', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app); + new codedeploy.LambdaApplication(stack, 'MyApp', { + applicationName: 'my name', + }); + + expect(() => app.synth()).toThrow('Application name: "my name" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).'); + }); }); diff --git a/packages/@aws-cdk/aws-codedeploy/test/lambda/custom-deployment-config.test.ts b/packages/@aws-cdk/aws-codedeploy/test/lambda/custom-deployment-config.test.ts index 7755402502857..618479726a3f2 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/lambda/custom-deployment-config.test.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/lambda/custom-deployment-config.test.ts @@ -97,6 +97,32 @@ test('custom resource created with specific name', () => { }); }); +test('fail with more than 100 characters in name', () => { + const app = new cdk.App(); + const stackWithApp = new cdk.Stack(app); + new codedeploy.CustomLambdaDeploymentConfig(stackWithApp, 'CustomConfig', { + type: codedeploy.CustomLambdaDeploymentConfigType.CANARY, + interval: cdk.Duration.minutes(1), + percentage: 5, + deploymentConfigName: 'a'.repeat(101), + }); + + expect(() => app.synth()).toThrow(`Deployment config name: "${'a'.repeat(101)}" can be a max of 100 characters.`); +}); + +test('fail with unallowed characters in name', () => { + const app = new cdk.App(); + const stackWithApp = new cdk.Stack(app); + new codedeploy.CustomLambdaDeploymentConfig(stackWithApp, 'CustomConfig', { + type: codedeploy.CustomLambdaDeploymentConfigType.CANARY, + interval: cdk.Duration.minutes(1), + percentage: 5, + deploymentConfigName: 'my name', + }); + + expect(() => app.synth()).toThrow('Deployment config name: "my name" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).'); +}); + test('can create linear custom config', () => { // WHEN const config = new codedeploy.CustomLambdaDeploymentConfig(stack, 'CustomConfig', { diff --git a/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts b/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts index c6ecfde1ae2de..396f61a3999ae 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts @@ -132,6 +132,30 @@ describe('CodeDeploy Lambda DeploymentGroup', () => { }); }); + test('fail with more than 100 characters in name', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app); + const alias = mockAlias(stack); + new codedeploy.LambdaDeploymentGroup(stack, 'MyDG', { + alias, + deploymentGroupName: 'a'.repeat(101), + }); + + expect(() => app.synth()).toThrow(`Deployment group name: "${'a'.repeat(101)}" can be a max of 100 characters.`); + }); + + test('fail with unallowed characters in name', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app); + const alias = mockAlias(stack); + new codedeploy.LambdaDeploymentGroup(stack, 'MyDG', { + alias, + deploymentGroupName: 'my name', + }); + + expect(() => app.synth()).toThrow('Deployment group name: "my name" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).'); + }); + test('can be created with explicit role', () => { const stack = new cdk.Stack(); const application = new codedeploy.LambdaApplication(stack, 'MyApp'); diff --git a/packages/@aws-cdk/aws-codedeploy/test/server/deployment-config.test.ts b/packages/@aws-cdk/aws-codedeploy/test/server/deployment-config.test.ts index 52652e8024b28..8523518c68a34 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/server/deployment-config.test.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/server/deployment-config.test.ts @@ -42,4 +42,26 @@ describe('CodeDeploy DeploymentConfig', () => { expect(deploymentConfig).not.toEqual(undefined); }); + + test('fail with more than 100 characters in name', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app); + new codedeploy.ServerDeploymentConfig(stack, 'DeploymentConfig', { + minimumHealthyHosts: codedeploy.MinimumHealthyHosts.percentage(75), + deploymentConfigName: 'a'.repeat(101), + }); + + expect(() => app.synth()).toThrow(`Deployment config name: "${'a'.repeat(101)}" can be a max of 100 characters.`); + }); + + test('fail with unallowed characters in name', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app); + new codedeploy.ServerDeploymentConfig(stack, 'DeploymentConfig', { + minimumHealthyHosts: codedeploy.MinimumHealthyHosts.percentage(75), + deploymentConfigName: 'my name', + }); + + expect(() => app.synth()).toThrow('Deployment config name: "my name" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).'); + }); }); diff --git a/packages/@aws-cdk/aws-codedeploy/test/server/deployment-group.test.ts b/packages/@aws-cdk/aws-codedeploy/test/server/deployment-group.test.ts index 43acaadc3e7fc..c01a8ae8ef34d 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/server/deployment-group.test.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/server/deployment-group.test.ts @@ -437,4 +437,25 @@ describe('CodeDeploy Server Deployment Group', () => { }); }); + test('fail with more than 100 characters in name', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app); + new codedeploy.ServerDeploymentGroup(stack, 'MyDG', { + deploymentGroupName: 'a'.repeat(101), + }); + + expect(() => app.synth()).toThrow(`Deployment group name: "${'a'.repeat(101)}" can be a max of 100 characters.`); + }); + + test('fail with unallowed characters in name', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app); + new codedeploy.ServerDeploymentGroup(stack, 'MyDG', { + + deploymentGroupName: 'my name', + }); + + expect(() => app.synth()).toThrow('Deployment group name: "my name" can only contain letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), + (plus signs), = (equals signs), , (commas), @ (at signs), - (minus signs).'); + }); + }); From 7c752e066082749a3083fa1dae2b8fc4a5774940 Mon Sep 17 00:00:00 2001 From: Peter Woodworth <44349620+peterwoodworth@users.noreply.github.com> Date: Fri, 1 Apr 2022 18:00:29 -0700 Subject: [PATCH 5/6] chore: don't run triage action on PR source (#19731) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit currently failing on the source run. This is unnecessary to have anyway (goofed up and got source and target mixed up initially on the first commit 🙈) ---- ### All Submissions: * [ ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/master/INTEGRATION_TESTS.md)? * [ ] Did you use `cdk-integ` to deploy the infrastructure and generate the snapshot (i.e. `cdk-integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .github/workflows/issue-label-assign.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/issue-label-assign.yml b/.github/workflows/issue-label-assign.yml index e581de6146a03..723dcca374661 100644 --- a/.github/workflows/issue-label-assign.yml +++ b/.github/workflows/issue-label-assign.yml @@ -2,8 +2,6 @@ name: "Set Issue Label and Assignee" on: issues: types: [opened, edited] - pull_request: - types: [opened] pull_request_target: types: [opened] From 7e9a43dcad55645a8e816e39af54feeb04d7a8cf Mon Sep 17 00:00:00 2001 From: Adam Ruka Date: Sat, 2 Apr 2022 10:14:42 -0700 Subject: [PATCH 6/6] fix(codedeploy): the Service Principal is wrong in isolated regions (#19729) Turns out, the Service Principal for CodeDeploy in the isolated regions is not regional like in all other regions, but rather universal (`codedeploy.amazonaws.com`). Fixes #19399 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/master/INTEGRATION_TESTS.md)? * [ ] Did you use `cdk-integ` to deploy the infrastructure and generate the snapshot (i.e. `cdk-integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../test/lambda/deployment-group.test.ts | 27 ++++++++++++++++++- packages/@aws-cdk/aws-iam/lib/principals.ts | 10 ++----- .../@aws-cdk/region-info/lib/aws-entities.ts | 11 -------- packages/@aws-cdk/region-info/lib/default.ts | 11 ++++---- packages/@aws-cdk/region-info/lib/fact.ts | 2 +- .../__snapshots__/region-info.test.js.snap | 6 ++--- 6 files changed, 38 insertions(+), 29 deletions(-) diff --git a/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts b/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts index 396f61a3999ae..5dbd5c98258ab 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts @@ -115,7 +115,6 @@ describe('CodeDeploy Lambda DeploymentGroup', () => { }); }); - test('can be created with explicit name', () => { const stack = new cdk.Stack(); const application = new codedeploy.LambdaApplication(stack, 'MyApp'); @@ -589,6 +588,32 @@ describe('CodeDeploy Lambda DeploymentGroup', () => { }, }); }); + + test('uses the correct Service Principal in the us-isob-east-1 region', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'CodeDeployLambdaStack', { + env: { region: 'us-isob-east-1' }, + }); + const alias = mockAlias(stack); + new codedeploy.LambdaDeploymentGroup(stack, 'MyDG', { + alias, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'codedeploy.amazonaws.com', + }, + }, + ], + Version: '2012-10-17', + }, + }); + }); }); describe('imported with fromLambdaDeploymentGroupAttributes', () => { diff --git a/packages/@aws-cdk/aws-iam/lib/principals.ts b/packages/@aws-cdk/aws-iam/lib/principals.ts index aecd493192142..a52e8d1e0dda2 100644 --- a/packages/@aws-cdk/aws-iam/lib/principals.ts +++ b/packages/@aws-cdk/aws-iam/lib/principals.ts @@ -767,14 +767,8 @@ class ServicePrincipalToken implements cdk.IResolvable { public resolve(ctx: cdk.IResolveContext) { if (this.opts.region) { // Special case, handle it separately to not break legacy behavior. - return ( - RegionInfo.get(this.opts.region).servicePrincipal(this.service) ?? - Default.servicePrincipal( - this.service, - this.opts.region, - cdk.Aws.URL_SUFFIX, - ) - ); + return RegionInfo.get(this.opts.region).servicePrincipal(this.service) ?? + Default.servicePrincipal(this.service, this.opts.region, cdk.Aws.URL_SUFFIX); } const stack = cdk.Stack.of(ctx.scope); diff --git a/packages/@aws-cdk/region-info/lib/aws-entities.ts b/packages/@aws-cdk/region-info/lib/aws-entities.ts index 9c14e89605607..0c28399449434 100644 --- a/packages/@aws-cdk/region-info/lib/aws-entities.ts +++ b/packages/@aws-cdk/region-info/lib/aws-entities.ts @@ -133,14 +133,3 @@ export function partitionInformation(region: string): Region { } return PARTITION_MAP.default; } - -/** - * Build a lookup map for all regions - */ -export function generateRegionMap(cb: (region: string) => string): Record { - const ret: Record = {}; - for (const region of AWS_REGIONS) { - ret[region] = cb(region); - } - return ret; -} diff --git a/packages/@aws-cdk/region-info/lib/default.ts b/packages/@aws-cdk/region-info/lib/default.ts index e306bd8c1fc25..c4e02d42bca3d 100644 --- a/packages/@aws-cdk/region-info/lib/default.ts +++ b/packages/@aws-cdk/region-info/lib/default.ts @@ -35,10 +35,10 @@ export class Default { } function determineConfiguration(service: string): (service: string, region: string, urlSuffix: string) => string { - function universal(s: string) { return `${s}.amazonaws.com`; }; - function partitional(s: string, _: string, u: string) { return `${s}.${u}`; }; - function regional(s: string, r: string) { return `${s}.${r}.amazonaws.com`; }; - function regionalPartitional(s: string, r: string, u: string) { return `${s}.${r}.${u}`; }; + function universal(s: string) { return `${s}.amazonaws.com`; } + function partitional(s: string, _: string, u: string) { return `${s}.${u}`; } + function regional(s: string, r: string) { return `${s}.${r}.amazonaws.com`; } + function regionalPartitional(s: string, r: string, u: string) { return `${s}.${r}.${u}`; } // Exceptions for Service Principals in us-iso-* const US_ISO_EXCEPTIONS = new Set([ @@ -91,7 +91,8 @@ export class Default { case 'codedeploy': return region.startsWith('cn-') ? regionalPartitional - : regional; + // ...except in the isolated regions, where it's universal + : (region.startsWith('us-iso') ? universal : regional); // Services with a regional AND partitional principal case 'logs': diff --git a/packages/@aws-cdk/region-info/lib/fact.ts b/packages/@aws-cdk/region-info/lib/fact.ts index 9c2831f67d2c6..583a4ac68450f 100644 --- a/packages/@aws-cdk/region-info/lib/fact.ts +++ b/packages/@aws-cdk/region-info/lib/fact.ts @@ -182,7 +182,7 @@ export class FactName { * The `.amazonaws.com` and `.amazonaws.com.cn` domains are stripped from service names, so they are * canonicalized in that respect. */ - public static servicePrincipal(service: string) { + public static servicePrincipal(service: string): string { return `service-principal:${service.replace(/\.amazonaws\.com(\.cn)?$/, '')}`; } } diff --git a/packages/@aws-cdk/region-info/test/__snapshots__/region-info.test.js.snap b/packages/@aws-cdk/region-info/test/__snapshots__/region-info.test.js.snap index 678a65fb4ccc3..5a3c0e2683c2c 100644 --- a/packages/@aws-cdk/region-info/test/__snapshots__/region-info.test.js.snap +++ b/packages/@aws-cdk/region-info/test/__snapshots__/region-info.test.js.snap @@ -795,7 +795,7 @@ Object { "servicePrincipals": Object { "application-autoscaling": "application-autoscaling.amazonaws.com", "autoscaling": "autoscaling.amazonaws.com", - "codedeploy": "codedeploy.us-iso-east-1.amazonaws.com", + "codedeploy": "codedeploy.amazonaws.com", "ec2": "ec2.c2s.ic.gov", "events": "events.amazonaws.com", "lambda": "lambda.amazonaws.com", @@ -826,7 +826,7 @@ Object { "servicePrincipals": Object { "application-autoscaling": "application-autoscaling.amazonaws.com", "autoscaling": "autoscaling.amazonaws.com", - "codedeploy": "codedeploy.us-iso-west-1.amazonaws.com", + "codedeploy": "codedeploy.amazonaws.com", "ec2": "ec2.c2s.ic.gov", "events": "events.amazonaws.com", "lambda": "lambda.amazonaws.com", @@ -857,7 +857,7 @@ Object { "servicePrincipals": Object { "application-autoscaling": "application-autoscaling.amazonaws.com", "autoscaling": "autoscaling.amazonaws.com", - "codedeploy": "codedeploy.us-isob-east-1.amazonaws.com", + "codedeploy": "codedeploy.amazonaws.com", "ec2": "ec2.sc2s.sgov.gov", "events": "events.amazonaws.com", "lambda": "lambda.amazonaws.com",