diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/aws-cdk-ec2-vpc-endpoint.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/aws-cdk-ec2-vpc-endpoint.assets.json index 242191d193c64..fbe2a15a4b619 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/aws-cdk-ec2-vpc-endpoint.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/aws-cdk-ec2-vpc-endpoint.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "38.0.1", "files": { - "211c13487f1f150aef71cb67b4da3fe4727ea378abaff0cace0f9230b9e65b35": { + "682c0c54750397812543d2f9f0be89b6d5668e279b45ede909c9ef6ee4e67343": { "source": { "path": "aws-cdk-ec2-vpc-endpoint.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "211c13487f1f150aef71cb67b4da3fe4727ea378abaff0cace0f9230b9e65b35.json", + "objectKey": "682c0c54750397812543d2f9f0be89b6d5668e279b45ede909c9ef6ee4e67343.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/aws-cdk-ec2-vpc-endpoint.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/aws-cdk-ec2-vpc-endpoint.template.json index df7f7ab44ffc0..e717007a4ecf9 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/aws-cdk-ec2-vpc-endpoint.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/aws-cdk-ec2-vpc-endpoint.template.json @@ -18,9 +18,6 @@ "MyVpcPublicSubnet1SubnetF6608456": { "Type": "AWS::EC2::Subnet", "Properties": { - "VpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "AvailabilityZone": { "Fn::Select": [ 0, @@ -44,21 +41,24 @@ "Key": "Name", "Value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PublicSubnet1" } - ] + ], + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "MyVpcPublicSubnet1RouteTableC46AB2F4": { "Type": "AWS::EC2::RouteTable", "Properties": { - "VpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "Tags": [ { "Key": "Name", "Value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PublicSubnet1" } - ] + ], + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "MyVpcPublicSubnet1RouteTableAssociation2ECEE1CB": { @@ -75,12 +75,12 @@ "MyVpcPublicSubnet1DefaultRoute95FDF9EB": { "Type": "AWS::EC2::Route", "Properties": { - "RouteTableId": { - "Ref": "MyVpcPublicSubnet1RouteTableC46AB2F4" - }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { "Ref": "MyVpcIGW5C4A4F63" + }, + "RouteTableId": { + "Ref": "MyVpcPublicSubnet1RouteTableC46AB2F4" } }, "DependsOn": [ @@ -102,15 +102,15 @@ "MyVpcPublicSubnet1NATGatewayAD3400C1": { "Type": "AWS::EC2::NatGateway", "Properties": { - "SubnetId": { - "Ref": "MyVpcPublicSubnet1SubnetF6608456" - }, "AllocationId": { "Fn::GetAtt": [ "MyVpcPublicSubnet1EIP096967CB", "AllocationId" ] }, + "SubnetId": { + "Ref": "MyVpcPublicSubnet1SubnetF6608456" + }, "Tags": [ { "Key": "Name", @@ -126,9 +126,6 @@ "MyVpcPublicSubnet2Subnet492B6BFB": { "Type": "AWS::EC2::Subnet", "Properties": { - "VpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "AvailabilityZone": { "Fn::Select": [ 1, @@ -152,21 +149,24 @@ "Key": "Name", "Value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PublicSubnet2" } - ] + ], + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "MyVpcPublicSubnet2RouteTable1DF17386": { "Type": "AWS::EC2::RouteTable", "Properties": { - "VpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "Tags": [ { "Key": "Name", "Value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PublicSubnet2" } - ] + ], + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "MyVpcPublicSubnet2RouteTableAssociation227DE78D": { @@ -183,12 +183,12 @@ "MyVpcPublicSubnet2DefaultRoute052936F6": { "Type": "AWS::EC2::Route", "Properties": { - "RouteTableId": { - "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" - }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { "Ref": "MyVpcIGW5C4A4F63" + }, + "RouteTableId": { + "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" } }, "DependsOn": [ @@ -210,15 +210,15 @@ "MyVpcPublicSubnet2NATGateway91BFBEC9": { "Type": "AWS::EC2::NatGateway", "Properties": { - "SubnetId": { - "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" - }, "AllocationId": { "Fn::GetAtt": [ "MyVpcPublicSubnet2EIP8CCBA239", "AllocationId" ] }, + "SubnetId": { + "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" + }, "Tags": [ { "Key": "Name", @@ -234,9 +234,6 @@ "MyVpcPrivateSubnet1Subnet5057CF7E": { "Type": "AWS::EC2::Subnet", "Properties": { - "VpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "AvailabilityZone": { "Fn::Select": [ 0, @@ -260,21 +257,24 @@ "Key": "Name", "Value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PrivateSubnet1" } - ] + ], + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "MyVpcPrivateSubnet1RouteTable8819E6E2": { "Type": "AWS::EC2::RouteTable", "Properties": { - "VpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "Tags": [ { "Key": "Name", "Value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PrivateSubnet1" } - ] + ], + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "MyVpcPrivateSubnet1RouteTableAssociation56D38C7E": { @@ -291,21 +291,18 @@ "MyVpcPrivateSubnet1DefaultRouteA8CDE2FA": { "Type": "AWS::EC2::Route", "Properties": { - "RouteTableId": { - "Ref": "MyVpcPrivateSubnet1RouteTable8819E6E2" - }, "DestinationCidrBlock": "0.0.0.0/0", "NatGatewayId": { "Ref": "MyVpcPublicSubnet1NATGatewayAD3400C1" + }, + "RouteTableId": { + "Ref": "MyVpcPrivateSubnet1RouteTable8819E6E2" } } }, "MyVpcPrivateSubnet2Subnet0040C983": { "Type": "AWS::EC2::Subnet", "Properties": { - "VpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "AvailabilityZone": { "Fn::Select": [ 1, @@ -329,21 +326,24 @@ "Key": "Name", "Value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PrivateSubnet2" } - ] + ], + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "MyVpcPrivateSubnet2RouteTableCEDCEECE": { "Type": "AWS::EC2::RouteTable", "Properties": { - "VpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "Tags": [ { "Key": "Name", "Value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PrivateSubnet2" } - ] + ], + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "MyVpcPrivateSubnet2RouteTableAssociation86A610DA": { @@ -360,12 +360,12 @@ "MyVpcPrivateSubnet2DefaultRoute9CE96294": { "Type": "AWS::EC2::Route", "Properties": { - "RouteTableId": { - "Ref": "MyVpcPrivateSubnet2RouteTableCEDCEECE" - }, "DestinationCidrBlock": "0.0.0.0/0", "NatGatewayId": { "Ref": "MyVpcPublicSubnet2NATGateway91BFBEC9" + }, + "RouteTableId": { + "Ref": "MyVpcPrivateSubnet2RouteTableCEDCEECE" } } }, @@ -383,32 +383,17 @@ "MyVpcVPCGW488ACE0D": { "Type": "AWS::EC2::VPCGatewayAttachment", "Properties": { - "VpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "InternetGatewayId": { "Ref": "MyVpcIGW5C4A4F63" + }, + "VpcId": { + "Ref": "MyVpcF9F0CA6F" } } }, "MyVpcS3FADC1889": { "Type": "AWS::EC2::VPCEndpoint", "Properties": { - "ServiceName": { - "Fn::Join": [ - "", - [ - "com.amazonaws.", - { - "Ref": "AWS::Region" - }, - ".s3" - ] - ] - }, - "VpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "RouteTableIds": [ { "Ref": "MyVpcPrivateSubnet1RouteTable8819E6E2" @@ -423,12 +408,6 @@ "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" } ], - "VpcEndpointType": "Gateway" - } - }, - "MyVpcDynamoDbEndpointE6A39B0D": { - "Type": "AWS::EC2::VPCEndpoint", - "Properties": { "ServiceName": { "Fn::Join": [ "", @@ -437,13 +416,19 @@ { "Ref": "AWS::Region" }, - ".dynamodb" + ".s3" ] ] }, + "VpcEndpointType": "Gateway", "VpcId": { "Ref": "MyVpcF9F0CA6F" - }, + } + } + }, + "MyVpcDynamoDbEndpointE6A39B0D": { + "Type": "AWS::EC2::VPCEndpoint", + "Properties": { "PolicyDocument": { "Statement": [ { @@ -474,7 +459,22 @@ "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" } ], - "VpcEndpointType": "Gateway" + "ServiceName": { + "Fn::Join": [ + "", + [ + "com.amazonaws.", + { + "Ref": "AWS::Region" + }, + ".dynamodb" + ] + ] + }, + "VpcEndpointType": "Gateway", + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "MyVpcEcrDockerEndpointSecurityGroup47BB9CC1": { @@ -530,6 +530,15 @@ "MyVpcEcrDockerEndpoint0385050C": { "Type": "AWS::EC2::VPCEndpoint", "Properties": { + "PrivateDnsEnabled": true, + "SecurityGroupIds": [ + { + "Fn::GetAtt": [ + "MyVpcEcrDockerEndpointSecurityGroup47BB9CC1", + "GroupId" + ] + } + ], "ServiceName": { "Fn::Join": [ "", @@ -542,18 +551,94 @@ ] ] }, + "SubnetIds": [ + { + "Ref": "MyVpcPrivateSubnet1Subnet5057CF7E" + }, + { + "Ref": "MyVpcPrivateSubnet2Subnet0040C983" + } + ], + "VpcEndpointType": "Interface", "VpcId": { "Ref": "MyVpcF9F0CA6F" - }, - "PrivateDnsEnabled": true, + } + } + }, + "MyVpcDynamoDbInterfaceEndpointSecurityGroupD6D5A6EF": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-cdk-ec2-vpc-endpoint/MyVpc/DynamoDbInterfaceEndpoint/SecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "SecurityGroupIngress": [ + { + "CidrIp": { + "Fn::GetAtt": [ + "MyVpcF9F0CA6F", + "CidrBlock" + ] + }, + "Description": { + "Fn::Join": [ + "", + [ + "from ", + { + "Fn::GetAtt": [ + "MyVpcF9F0CA6F", + "CidrBlock" + ] + }, + ":443" + ] + ] + }, + "FromPort": 443, + "IpProtocol": "tcp", + "ToPort": 443 + } + ], + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-ec2-vpc-endpoint/MyVpc" + } + ], + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } + } + }, + "MyVpcDynamoDbInterfaceEndpointA97B3149": { + "Type": "AWS::EC2::VPCEndpoint", + "Properties": { + "PrivateDnsEnabled": false, "SecurityGroupIds": [ { "Fn::GetAtt": [ - "MyVpcEcrDockerEndpointSecurityGroup47BB9CC1", + "MyVpcDynamoDbInterfaceEndpointSecurityGroupD6D5A6EF", "GroupId" ] } ], + "ServiceName": { + "Fn::Join": [ + "", + [ + "com.amazonaws.", + { + "Ref": "AWS::Region" + }, + ".dynamodb" + ] + ] + }, "SubnetIds": [ { "Ref": "MyVpcPrivateSubnet1Subnet5057CF7E" @@ -562,7 +647,10 @@ "Ref": "MyVpcPrivateSubnet2Subnet0040C983" } ], - "VpcEndpointType": "Interface" + "VpcEndpointType": "Interface", + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } } } }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/cdk.out index 8ecc185e9dbee..c6e612584e352 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"21.0.0"} \ No newline at end of file +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/integ.json index a1e6ca7e8cd1c..c2b84e3e20ee8 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "38.0.1", "testCases": { "integ.vpc-endpoint.lit": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/manifest.json index 542140e0169c4..1f0923f541fae 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "38.0.1", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-ec2-vpc-endpoint.assets": { "type": "cdk:asset-manifest", "properties": { @@ -20,10 +14,12 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "aws-cdk-ec2-vpc-endpoint.template.json", + "terminationProtection": false, "validateOnSynth": false, + "notificationArns": [], "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}/211c13487f1f150aef71cb67b4da3fe4727ea378abaff0cace0f9230b9e65b35.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/682c0c54750397812543d2f9f0be89b6d5668e279b45ede909c9ef6ee4e67343.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -201,6 +197,18 @@ "data": "MyVpcEcrDockerEndpoint0385050C" } ], + "/aws-cdk-ec2-vpc-endpoint/MyVpc/DynamoDbInterfaceEndpoint/SecurityGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcDynamoDbInterfaceEndpointSecurityGroupD6D5A6EF" + } + ], + "/aws-cdk-ec2-vpc-endpoint/MyVpc/DynamoDbInterfaceEndpoint/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcDynamoDbInterfaceEndpointA97B3149" + } + ], "/aws-cdk-ec2-vpc-endpoint/BootstrapVersion": [ { "type": "aws:cdk:logicalId", @@ -215,6 +223,12 @@ ] }, "displayName": "aws-cdk-ec2-vpc-endpoint" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/tree.json index e30022e677238..fd791ab34b91e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.js.snapshot/tree.json @@ -4,14 +4,6 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, "aws-cdk-ec2-vpc-endpoint": { "id": "aws-cdk-ec2-vpc-endpoint", "path": "aws-cdk-ec2-vpc-endpoint", @@ -39,7 +31,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnVPC", + "fqn": "aws-cdk-lib.aws_ec2.CfnVPC", "version": "0.0.0" } }, @@ -53,9 +45,6 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", "aws:cdk:cloudformation:props": { - "vpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "availabilityZone": { "Fn::Select": [ 0, @@ -79,11 +68,14 @@ "key": "Name", "value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PublicSubnet1" } - ] + ], + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", "version": "0.0.0" } }, @@ -91,8 +83,8 @@ "id": "Acl", "path": "aws-cdk-ec2-vpc-endpoint/MyVpc/PublicSubnet1/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -101,19 +93,19 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", "aws:cdk:cloudformation:props": { - "vpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "tags": [ { "key": "Name", "value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PublicSubnet1" } - ] + ], + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", "version": "0.0.0" } }, @@ -132,7 +124,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", "version": "0.0.0" } }, @@ -142,17 +134,17 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Route", "aws:cdk:cloudformation:props": { - "routeTableId": { - "Ref": "MyVpcPublicSubnet1RouteTableC46AB2F4" - }, "destinationCidrBlock": "0.0.0.0/0", "gatewayId": { "Ref": "MyVpcIGW5C4A4F63" + }, + "routeTableId": { + "Ref": "MyVpcPublicSubnet1RouteTableC46AB2F4" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", "version": "0.0.0" } }, @@ -172,7 +164,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnEIP", + "fqn": "aws-cdk-lib.aws_ec2.CfnEIP", "version": "0.0.0" } }, @@ -182,15 +174,15 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", "aws:cdk:cloudformation:props": { - "subnetId": { - "Ref": "MyVpcPublicSubnet1SubnetF6608456" - }, "allocationId": { "Fn::GetAtt": [ "MyVpcPublicSubnet1EIP096967CB", "AllocationId" ] }, + "subnetId": { + "Ref": "MyVpcPublicSubnet1SubnetF6608456" + }, "tags": [ { "key": "Name", @@ -200,13 +192,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnNatGateway", + "fqn": "aws-cdk-lib.aws_ec2.CfnNatGateway", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.PublicSubnet", + "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet", "version": "0.0.0" } }, @@ -220,9 +212,6 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", "aws:cdk:cloudformation:props": { - "vpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "availabilityZone": { "Fn::Select": [ 1, @@ -246,11 +235,14 @@ "key": "Name", "value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PublicSubnet2" } - ] + ], + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", "version": "0.0.0" } }, @@ -258,8 +250,8 @@ "id": "Acl", "path": "aws-cdk-ec2-vpc-endpoint/MyVpc/PublicSubnet2/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -268,19 +260,19 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", "aws:cdk:cloudformation:props": { - "vpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "tags": [ { "key": "Name", "value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PublicSubnet2" } - ] + ], + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", "version": "0.0.0" } }, @@ -299,7 +291,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", "version": "0.0.0" } }, @@ -309,17 +301,17 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Route", "aws:cdk:cloudformation:props": { - "routeTableId": { - "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" - }, "destinationCidrBlock": "0.0.0.0/0", "gatewayId": { "Ref": "MyVpcIGW5C4A4F63" + }, + "routeTableId": { + "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", "version": "0.0.0" } }, @@ -339,7 +331,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnEIP", + "fqn": "aws-cdk-lib.aws_ec2.CfnEIP", "version": "0.0.0" } }, @@ -349,15 +341,15 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", "aws:cdk:cloudformation:props": { - "subnetId": { - "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" - }, "allocationId": { "Fn::GetAtt": [ "MyVpcPublicSubnet2EIP8CCBA239", "AllocationId" ] }, + "subnetId": { + "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" + }, "tags": [ { "key": "Name", @@ -367,13 +359,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnNatGateway", + "fqn": "aws-cdk-lib.aws_ec2.CfnNatGateway", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.PublicSubnet", + "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet", "version": "0.0.0" } }, @@ -387,9 +379,6 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", "aws:cdk:cloudformation:props": { - "vpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "availabilityZone": { "Fn::Select": [ 0, @@ -413,11 +402,14 @@ "key": "Name", "value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PrivateSubnet1" } - ] + ], + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", "version": "0.0.0" } }, @@ -425,8 +417,8 @@ "id": "Acl", "path": "aws-cdk-ec2-vpc-endpoint/MyVpc/PrivateSubnet1/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -435,19 +427,19 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", "aws:cdk:cloudformation:props": { - "vpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "tags": [ { "key": "Name", "value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PrivateSubnet1" } - ] + ], + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", "version": "0.0.0" } }, @@ -466,7 +458,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", "version": "0.0.0" } }, @@ -476,23 +468,23 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Route", "aws:cdk:cloudformation:props": { - "routeTableId": { - "Ref": "MyVpcPrivateSubnet1RouteTable8819E6E2" - }, "destinationCidrBlock": "0.0.0.0/0", "natGatewayId": { "Ref": "MyVpcPublicSubnet1NATGatewayAD3400C1" + }, + "routeTableId": { + "Ref": "MyVpcPrivateSubnet1RouteTable8819E6E2" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.PrivateSubnet", + "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet", "version": "0.0.0" } }, @@ -506,9 +498,6 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", "aws:cdk:cloudformation:props": { - "vpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "availabilityZone": { "Fn::Select": [ 1, @@ -532,11 +521,14 @@ "key": "Name", "value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PrivateSubnet2" } - ] + ], + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnSubnet", + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", "version": "0.0.0" } }, @@ -544,8 +536,8 @@ "id": "Acl", "path": "aws-cdk-ec2-vpc-endpoint/MyVpc/PrivateSubnet2/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -554,19 +546,19 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", "aws:cdk:cloudformation:props": { - "vpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "tags": [ { "key": "Name", "value": "aws-cdk-ec2-vpc-endpoint/MyVpc/PrivateSubnet2" } - ] + ], + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnRouteTable", + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", "version": "0.0.0" } }, @@ -585,7 +577,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation", + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", "version": "0.0.0" } }, @@ -595,23 +587,23 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Route", "aws:cdk:cloudformation:props": { - "routeTableId": { - "Ref": "MyVpcPrivateSubnet2RouteTableCEDCEECE" - }, "destinationCidrBlock": "0.0.0.0/0", "natGatewayId": { "Ref": "MyVpcPublicSubnet2NATGateway91BFBEC9" + }, + "routeTableId": { + "Ref": "MyVpcPrivateSubnet2RouteTableCEDCEECE" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnRoute", + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.PrivateSubnet", + "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet", "version": "0.0.0" } }, @@ -630,7 +622,7 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnInternetGateway", + "fqn": "aws-cdk-lib.aws_ec2.CfnInternetGateway", "version": "0.0.0" } }, @@ -640,16 +632,16 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", "aws:cdk:cloudformation:props": { - "vpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "internetGatewayId": { "Ref": "MyVpcIGW5C4A4F63" + }, + "vpcId": { + "Ref": "MyVpcF9F0CA6F" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnVPCGatewayAttachment", + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment", "version": "0.0.0" } }, @@ -663,21 +655,6 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::VPCEndpoint", "aws:cdk:cloudformation:props": { - "serviceName": { - "Fn::Join": [ - "", - [ - "com.amazonaws.", - { - "Ref": "AWS::Region" - }, - ".s3" - ] - ] - }, - "vpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "routeTableIds": [ { "Ref": "MyVpcPrivateSubnet1RouteTable8819E6E2" @@ -692,17 +669,32 @@ "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" } ], - "vpcEndpointType": "Gateway" + "serviceName": { + "Fn::Join": [ + "", + [ + "com.amazonaws.", + { + "Ref": "AWS::Region" + }, + ".s3" + ] + ] + }, + "vpcEndpointType": "Gateway", + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnVPCEndpoint", + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCEndpoint", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.GatewayVpcEndpoint", + "fqn": "aws-cdk-lib.aws_ec2.GatewayVpcEndpoint", "version": "0.0.0" } }, @@ -716,21 +708,6 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::VPCEndpoint", "aws:cdk:cloudformation:props": { - "serviceName": { - "Fn::Join": [ - "", - [ - "com.amazonaws.", - { - "Ref": "AWS::Region" - }, - ".dynamodb" - ] - ] - }, - "vpcId": { - "Ref": "MyVpcF9F0CA6F" - }, "policyDocument": { "Statement": [ { @@ -761,17 +738,32 @@ "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" } ], - "vpcEndpointType": "Gateway" + "serviceName": { + "Fn::Join": [ + "", + [ + "com.amazonaws.", + { + "Ref": "AWS::Region" + }, + ".dynamodb" + ] + ] + }, + "vpcEndpointType": "Gateway", + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnVPCEndpoint", + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCEndpoint", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.GatewayVpcEndpoint", + "fqn": "aws-cdk-lib.aws_ec2.GatewayVpcEndpoint", "version": "0.0.0" } }, @@ -837,13 +829,13 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnSecurityGroup", + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.SecurityGroup", + "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup", "version": "0.0.0" } }, @@ -853,6 +845,15 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::VPCEndpoint", "aws:cdk:cloudformation:props": { + "privateDnsEnabled": true, + "securityGroupIds": [ + { + "Fn::GetAtt": [ + "MyVpcEcrDockerEndpointSecurityGroup47BB9CC1", + "GroupId" + ] + } + ], "serviceName": { "Fn::Join": [ "", @@ -865,18 +866,130 @@ ] ] }, + "subnetIds": [ + { + "Ref": "MyVpcPrivateSubnet1Subnet5057CF7E" + }, + { + "Ref": "MyVpcPrivateSubnet2Subnet0040C983" + } + ], + "vpcEndpointType": "Interface", "vpcId": { "Ref": "MyVpcF9F0CA6F" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCEndpoint", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.InterfaceVpcEndpoint", + "version": "0.0.0" + } + }, + "DynamoDbInterfaceEndpoint": { + "id": "DynamoDbInterfaceEndpoint", + "path": "aws-cdk-ec2-vpc-endpoint/MyVpc/DynamoDbInterfaceEndpoint", + "children": { + "SecurityGroup": { + "id": "SecurityGroup", + "path": "aws-cdk-ec2-vpc-endpoint/MyVpc/DynamoDbInterfaceEndpoint/SecurityGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-ec2-vpc-endpoint/MyVpc/DynamoDbInterfaceEndpoint/SecurityGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "aws-cdk-ec2-vpc-endpoint/MyVpc/DynamoDbInterfaceEndpoint/SecurityGroup", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "securityGroupIngress": [ + { + "cidrIp": { + "Fn::GetAtt": [ + "MyVpcF9F0CA6F", + "CidrBlock" + ] + }, + "ipProtocol": "tcp", + "fromPort": 443, + "toPort": 443, + "description": { + "Fn::Join": [ + "", + [ + "from ", + { + "Fn::GetAtt": [ + "MyVpcF9F0CA6F", + "CidrBlock" + ] + }, + ":443" + ] + ] + } + } + ], + "tags": [ + { + "key": "Name", + "value": "aws-cdk-ec2-vpc-endpoint/MyVpc" + } + ], + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } + } }, - "privateDnsEnabled": true, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-ec2-vpc-endpoint/MyVpc/DynamoDbInterfaceEndpoint/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCEndpoint", + "aws:cdk:cloudformation:props": { + "privateDnsEnabled": false, "securityGroupIds": [ { "Fn::GetAtt": [ - "MyVpcEcrDockerEndpointSecurityGroup47BB9CC1", + "MyVpcDynamoDbInterfaceEndpointSecurityGroupD6D5A6EF", "GroupId" ] } ], + "serviceName": { + "Fn::Join": [ + "", + [ + "com.amazonaws.", + { + "Ref": "AWS::Region" + }, + ".dynamodb" + ] + ] + }, "subnetIds": [ { "Ref": "MyVpcPrivateSubnet1Subnet5057CF7E" @@ -885,36 +998,63 @@ "Ref": "MyVpcPrivateSubnet2Subnet0040C983" } ], - "vpcEndpointType": "Interface" + "vpcEndpointType": "Interface", + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnVPCEndpoint", + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCEndpoint", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.InterfaceVpcEndpoint", + "fqn": "aws-cdk-lib.aws_ec2.InterfaceVpcEndpoint", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.Vpc", + "fqn": "aws-cdk-lib.aws_ec2.Vpc", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-ec2-vpc-endpoint/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-ec2-vpc-endpoint/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.ts index 85b03505da83e..e10a3203a187f 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.vpc-endpoint.lit.ts @@ -42,6 +42,12 @@ class VpcEndpointStack extends cdk.Stack { // open: false }); /// !hide + + // Add an interface endpoint with privateDnsDefault false + vpc.addInterfaceEndpoint('DynamoDbInterfaceEndpoint', { + service: ec2.InterfaceVpcEndpointAwsService.DYNAMODB, + privateDnsEnabled: false, + }); } } diff --git a/packages/@aws-cdk/aws-lambda-python-alpha/test/lambda-handler-custom-build/requirements.txt b/packages/@aws-cdk/aws-lambda-python-alpha/test/lambda-handler-custom-build/requirements.txt index e57512c4102d5..a1d408571902e 100644 --- a/packages/@aws-cdk/aws-lambda-python-alpha/test/lambda-handler-custom-build/requirements.txt +++ b/packages/@aws-cdk/aws-lambda-python-alpha/test/lambda-handler-custom-build/requirements.txt @@ -2,6 +2,6 @@ certifi==2024.7.4 chardet==3.0.4 idna==3.7 -urllib3==1.26.18 +urllib3==1.26.19 # Requests used by this lambda requests==2.31.0 diff --git a/packages/@aws-cdk/cloudformation-diff/package.json b/packages/@aws-cdk/cloudformation-diff/package.json index 50b6baffb22de..5de262e0b45de 100644 --- a/packages/@aws-cdk/cloudformation-diff/package.json +++ b/packages/@aws-cdk/cloudformation-diff/package.json @@ -23,8 +23,8 @@ }, "license": "Apache-2.0", "dependencies": { - "@aws-cdk/aws-service-spec": "^0.1.24", - "@aws-cdk/service-spec-types": "^0.0.91", + "@aws-cdk/aws-service-spec": "^0.1.25", + "@aws-cdk/service-spec-types": "^0.0.92", "chalk": "^4", "diff": "^5.2.0", "fast-deep-equal": "^3.1.3", diff --git a/packages/@aws-cdk/integ-runner/package.json b/packages/@aws-cdk/integ-runner/package.json index 84312ef8dd01a..9851c3f9fc1ea 100644 --- a/packages/@aws-cdk/integ-runner/package.json +++ b/packages/@aws-cdk/integ-runner/package.json @@ -75,7 +75,7 @@ "@aws-cdk/cloudformation-diff": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "cdk-assets": "^2.154.0", - "@aws-cdk/aws-service-spec": "^0.1.24", + "@aws-cdk/aws-service-spec": "^0.1.25", "@aws-cdk/cdk-cli-wrapper": "0.0.0", "aws-cdk": "0.0.0", diff --git a/packages/aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts b/packages/aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts index 560f1bc7d37a8..1bed1dd748344 100644 --- a/packages/aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts +++ b/packages/aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts @@ -375,6 +375,7 @@ export class InterfaceVpcEndpointAwsService implements IInterfaceVpcEndpointServ public static readonly DEADLINE_CLOUD_SCHEDULING = new InterfaceVpcEndpointAwsService('deadline.scheduling'); public static readonly DEVOPS_GURU = new InterfaceVpcEndpointAwsService('devops-guru'); public static readonly DIRECTORY_SERVICE = new InterfaceVpcEndpointAwsService('ds'); + public static readonly DYNAMODB = new InterfaceVpcEndpointAwsService('dynamodb'); public static readonly EBS_DIRECT = new InterfaceVpcEndpointAwsService('ebs'); public static readonly EC2 = new InterfaceVpcEndpointAwsService('ec2'); public static readonly EC2_MESSAGES = new InterfaceVpcEndpointAwsService('ec2messages'); diff --git a/packages/aws-cdk-lib/aws-ec2/test/vpc-endpoint.test.ts b/packages/aws-cdk-lib/aws-ec2/test/vpc-endpoint.test.ts index 3c1c05ba8dfa8..6faa231a475dd 100644 --- a/packages/aws-cdk-lib/aws-ec2/test/vpc-endpoint.test.ts +++ b/packages/aws-cdk-lib/aws-ec2/test/vpc-endpoint.test.ts @@ -549,7 +549,7 @@ describe('vpc endpoint', () => { const stack = new Stack(undefined, 'TestStack', { env: { region: 'us-east-1' } }); const vpc = new Vpc(stack, 'VPC'); // WHEN - expect(() =>vpc.addInterfaceEndpoint('YourService', { + expect(() => vpc.addInterfaceEndpoint('YourService', { service: { name: 'com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', port: 443, @@ -563,7 +563,7 @@ describe('vpc endpoint', () => { const stack = new Stack(undefined, 'TestStack', { env: { account: '123456789012' } }); const vpc = new Vpc(stack, 'VPC'); // WHEN - expect(() =>vpc.addInterfaceEndpoint('YourService', { + expect(() => vpc.addInterfaceEndpoint('YourService', { service: { name: 'com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', port: 443, @@ -589,7 +589,7 @@ describe('vpc endpoint', () => { const vpc = new Vpc(stack, 'VPC'); // WHEN - expect(() =>vpc.addInterfaceEndpoint('YourService', { + expect(() => vpc.addInterfaceEndpoint('YourService', { service: { name: 'com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', port: 443, @@ -603,7 +603,7 @@ describe('vpc endpoint', () => { const stack = new Stack(undefined, 'TestStack', { env: { account: '123456789012', region: 'us-east-1' } }); const vpc = new Vpc(stack, 'VPC'); // WHEN - expect(() =>vpc.addInterfaceEndpoint('YourService', { + expect(() => vpc.addInterfaceEndpoint('YourService', { service: { name: 'com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', port: 443, @@ -934,5 +934,25 @@ describe('vpc endpoint', () => { ServiceName: 'aws.api.global.codecatalyst', }); }); + + test('test vpc interface endpoint with private dns disabled', () => { + //GIVEN + const stack = new Stack(undefined, 'TestStack', { env: { account: '123456789012', region: 'us-west-2' } }); + const vpc = new Vpc(stack, 'VPC'); + + //WHEN + vpc.addInterfaceEndpoint('DynamoDB Endpoint', { + service: InterfaceVpcEndpointAwsService.DYNAMODB, + privateDnsEnabled: false, + }); + + //THEN + Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCEndpoint', { + ServiceName: 'com.amazonaws.us-west-2.dynamodb', + VpcId: stack.resolve(vpc.vpcId), + PrivateDnsEnabled: false, + VpcEndpointType: 'Interface', + }); + }); }); }); diff --git a/packages/aws-cdk-lib/aws-rds/lib/cluster-engine.ts b/packages/aws-cdk-lib/aws-rds/lib/cluster-engine.ts index 002b3fb9bf3bd..07e28398e3f3e 100644 --- a/packages/aws-cdk-lib/aws-rds/lib/cluster-engine.ts +++ b/packages/aws-cdk-lib/aws-rds/lib/cluster-engine.ts @@ -962,6 +962,8 @@ export class AuroraPostgresEngineVersion { public static readonly VER_12_18 = AuroraPostgresEngineVersion.of('12.18', '12', { s3Import: true, s3Export: true }); /** Version "12.19". */ public static readonly VER_12_19 = AuroraPostgresEngineVersion.of('12.19', '12', { s3Import: true, s3Export: true }); + /** Version "12.20". */ + public static readonly VER_12_20 = AuroraPostgresEngineVersion.of('12.20', '12', { s3Import: true, s3Export: true }); /** * Version "13.3". * @deprecated Version 13.3 is no longer supported by Amazon RDS. @@ -1000,6 +1002,8 @@ export class AuroraPostgresEngineVersion { public static readonly VER_13_14 = AuroraPostgresEngineVersion.of('13.14', '13', { s3Import: true, s3Export: true }); /** Version "13.15". */ public static readonly VER_13_15 = AuroraPostgresEngineVersion.of('13.15', '13', { s3Import: true, s3Export: true }); + /** Version "13.16". */ + public static readonly VER_13_16 = AuroraPostgresEngineVersion.of('13.16', '13', { s3Import: true, s3Export: true }); /** Version "14.3". */ public static readonly VER_14_3 = AuroraPostgresEngineVersion.of('14.3', '14', { s3Import: true, s3Export: true }); /** Version "14.4". */ @@ -1020,6 +1024,8 @@ export class AuroraPostgresEngineVersion { public static readonly VER_14_11 = AuroraPostgresEngineVersion.of('14.11', '14', { s3Import: true, s3Export: true }); /** Version "14.12". */ public static readonly VER_14_12 = AuroraPostgresEngineVersion.of('14.12', '14', { s3Import: true, s3Export: true }); + /** Version "14.13". */ + public static readonly VER_14_13 = AuroraPostgresEngineVersion.of('14.13', '14', { s3Import: true, s3Export: true }); /** Version "15.2". */ public static readonly VER_15_2 = AuroraPostgresEngineVersion.of('15.2', '15', { s3Import: true, s3Export: true }); /** Version "15.3". */ @@ -1032,6 +1038,8 @@ export class AuroraPostgresEngineVersion { public static readonly VER_15_6 = AuroraPostgresEngineVersion.of('15.6', '15', { s3Import: true, s3Export: true }); /** Version "15.7". */ public static readonly VER_15_7 = AuroraPostgresEngineVersion.of('15.7', '15', { s3Import: true, s3Export: true }); + /** Version "15.8". */ + public static readonly VER_15_8 = AuroraPostgresEngineVersion.of('15.8', '15', { s3Import: true, s3Export: true }); /** * Version "16.0" * @deprecated Version 16.0 is no longer supported by Amazon RDS. @@ -1043,6 +1051,8 @@ export class AuroraPostgresEngineVersion { public static readonly VER_16_2 = AuroraPostgresEngineVersion.of('16.2', '16', { s3Import: true, s3Export: true }); /** Version "16.3". */ public static readonly VER_16_3 = AuroraPostgresEngineVersion.of('16.3', '16', { s3Import: true, s3Export: true }); + /** Version "16.4". */ + public static readonly VER_16_4 = AuroraPostgresEngineVersion.of('16.4', '16', { s3Import: true, s3Export: true }); /** * Create a new AuroraPostgresEngineVersion with an arbitrary version. diff --git a/packages/aws-cdk-lib/cloudformation-include/lib/cfn-include.ts b/packages/aws-cdk-lib/cloudformation-include/lib/cfn-include.ts index 9a1018e79e026..a2849e5c794a6 100644 --- a/packages/aws-cdk-lib/cloudformation-include/lib/cfn-include.ts +++ b/packages/aws-cdk-lib/cloudformation-include/lib/cfn-include.ts @@ -66,6 +66,16 @@ export interface CfnIncludeProps { * @default - will throw an error on detecting any cyclical references */ readonly allowCyclicalReferences?: boolean; + + /** + * Specifies a list of LogicalIDs for resources that will be included in the CDK Stack, + * but will not be parsed and converted to CDK types. This allows you to use CFN templates + * that rely on Intrinsic placement that `cfn-include` + * would otherwise reject, such as non-primitive values in resource update policies. + * + * @default - All resources are hydrated + */ + readonly dehydratedResources?: string[]; } /** @@ -109,6 +119,7 @@ export class CfnInclude extends core.CfnElement { private readonly template: any; private readonly preserveLogicalIds: boolean; private readonly allowCyclicalReferences: boolean; + private readonly dehydratedResources: string[]; private logicalIdToPlaceholderMap: Map; constructor(scope: Construct, id: string, props: CfnIncludeProps) { @@ -125,6 +136,14 @@ export class CfnInclude extends core.CfnElement { this.preserveLogicalIds = props.preserveLogicalIds ?? true; + this.dehydratedResources = props.dehydratedResources ?? []; + + for (const logicalId of this.dehydratedResources) { + if (!Object.keys(this.template.Resources).includes(logicalId)) { + throw new Error(`Logical ID '${logicalId}' was specified in 'dehydratedResources', but does not belong to a resource in the template.`); + } + } + // check if all user specified parameter values exist in the template for (const logicalId of Object.keys(this.parametersToReplace)) { if (!(logicalId in (this.template.Parameters || {}))) { @@ -663,8 +682,27 @@ export class CfnInclude extends core.CfnElement { const resourceAttributes: any = this.template.Resources[logicalId]; let l1Instance: core.CfnResource; - if (this.nestedStacksToInclude[logicalId]) { + if (this.nestedStacksToInclude[logicalId] && this.dehydratedResources.includes(logicalId)) { + throw new Error(`nested stack '${logicalId}' was marked as dehydrated - nested stacks cannot be dehydrated`); + } else if (this.nestedStacksToInclude[logicalId]) { l1Instance = this.createNestedStack(logicalId, cfnParser); + } else if (this.dehydratedResources.includes(logicalId)) { + + l1Instance = new core.CfnResource(this, logicalId, { + type: resourceAttributes.Type, + properties: resourceAttributes.Properties, + }); + const cfnOptions = l1Instance.cfnOptions; + cfnOptions.creationPolicy = resourceAttributes.CreationPolicy; + cfnOptions.updatePolicy = resourceAttributes.UpdatePolicy; + cfnOptions.deletionPolicy = resourceAttributes.DeletionPolicy; + cfnOptions.updateReplacePolicy = resourceAttributes.UpdateReplacePolicy; + cfnOptions.version = resourceAttributes.Version; + cfnOptions.description = resourceAttributes.Description; + cfnOptions.metadata = resourceAttributes.Metadata; + this.resources[logicalId] = l1Instance; + + return l1Instance; } else { const l1ClassFqn = cfn_type_to_l1_mapping.lookup(resourceAttributes.Type); // The AWS::CloudFormation::CustomResource type corresponds to the CfnCustomResource class. diff --git a/packages/aws-cdk-lib/cloudformation-include/test/invalid-templates.test.ts b/packages/aws-cdk-lib/cloudformation-include/test/invalid-templates.test.ts index 984a394adaa05..3802c00477d37 100644 --- a/packages/aws-cdk-lib/cloudformation-include/test/invalid-templates.test.ts +++ b/packages/aws-cdk-lib/cloudformation-include/test/invalid-templates.test.ts @@ -245,17 +245,201 @@ describe('CDK Include', () => { }, ); }); + + test('throws an exception if Tags contains invalid intrinsics', () => { + expect(() => { + includeTestTemplate(stack, 'tags-with-invalid-intrinsics.json'); + }).toThrow(/expression does not exist in the template/); + }); + + test('non-leaf Intrinsics cannot be used in the top-level creation policy', () => { + stack.node.setContext(cxapi.CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS, true); + expect(() => { + includeTestTemplate(stack, 'intrinsics-create-policy.json'); + }).toThrow(/Cannot convert resource 'CreationPolicyIntrinsic' to CDK objects: it uses an intrinsic in a resource update or deletion policy to represent a non-primitive value. Specify 'CreationPolicyIntrinsic' in the 'dehydratedResources' prop to skip parsing this resource, while still including it in the output./); + }); + + test('Intrinsics cannot be used in the autoscaling creation policy', () => { + stack.node.setContext(cxapi.CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS, true); + expect(() => { + includeTestTemplate(stack, 'intrinsics-create-policy-autoscaling.json'); + }).toThrow(/Cannot convert resource 'AutoScalingCreationPolicyIntrinsic' to CDK objects: it uses an intrinsic in a resource update or deletion policy to represent a non-primitive value. Specify 'AutoScalingCreationPolicyIntrinsic' in the 'dehydratedResources' prop to skip parsing this resource, while still including it in the output./); + }); + + test('Intrinsics cannot be used in the create policy resource signal', () => { + stack.node.setContext(cxapi.CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS, true); + expect(() => { + includeTestTemplate(stack, 'intrinsics-create-policy-resource-signal.json'); + }).toThrow(/Cannot convert resource 'ResourceSignalIntrinsic' to CDK objects: it uses an intrinsic in a resource update or deletion policy to represent a non-primitive value. Specify 'ResourceSignalIntrinsic' in the 'dehydratedResources' prop to skip parsing this resource, while still including it in the output./); + }); + + test('Intrinsics cannot be used in the top-level update policy', () => { + stack.node.setContext(cxapi.CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS, true); + expect(() => { + includeTestTemplate(stack, 'intrinsics-update-policy.json'); + }).toThrow(/Cannot convert resource 'ASG' to CDK objects: it uses an intrinsic in a resource update or deletion policy to represent a non-primitive value. Specify 'ASG' in the 'dehydratedResources' prop to skip parsing this resource, while still including it in the output./); + }); + + test('Intrinsics cannot be used in the auto scaling rolling update update policy', () => { + stack.node.setContext(cxapi.CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS, true); + expect(() => { + includeTestTemplate(stack, 'intrinsics-update-policy-autoscaling-rolling-update.json'); + }).toThrow(/Cannot convert resource 'ASG' to CDK objects: it uses an intrinsic in a resource update or deletion policy to represent a non-primitive value. Specify 'ASG' in the 'dehydratedResources' prop to skip parsing this resource, while still including it in the output./); + }); + + test('Intrinsics cannot be used in the auto scaling replacing update update policy', () => { + stack.node.setContext(cxapi.CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS, true); + expect(() => { + includeTestTemplate(stack, 'intrinsics-update-policy-autoscaling-replacing-update.json'); + }).toThrow(/Cannot convert resource 'ASG' to CDK objects: it uses an intrinsic in a resource update or deletion policy to represent a non-primitive value. Specify 'ASG' in the 'dehydratedResources' prop to skip parsing this resource, while still including it in the output./); + }); + + test('Intrinsics cannot be used in the auto scaling scheduled action update policy', () => { + stack.node.setContext(cxapi.CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS, true); + expect(() => { + includeTestTemplate(stack, 'intrinsics-update-policy-autoscaling-scheduled-action.json'); + }).toThrow(/Cannot convert resource 'ASG' to CDK objects: it uses an intrinsic in a resource update or deletion policy to represent a non-primitive value. Specify 'ASG' in the 'dehydratedResources' prop to skip parsing this resource, while still including it in the output./); + }); + + test('Intrinsics cannot be used in the code deploy lambda alias update policy', () => { + stack.node.setContext(cxapi.CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS, true); + expect(() => { + includeTestTemplate(stack, 'intrinsics-update-policy-code-deploy-lambda-alias-update.json'); + }).toThrow(/Cannot convert resource 'Alias' to CDK objects: it uses an intrinsic in a resource update or deletion policy to represent a non-primitive value. Specify 'Alias' in the 'dehydratedResources' prop to skip parsing this resource, while still including it in the output./); + }); + + test('FF toggles error checking', () => { + stack.node.setContext(cxapi.CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS, false); + expect(() => { + includeTestTemplate(stack, 'intrinsics-update-policy-code-deploy-lambda-alias-update.json'); + }).not.toThrow(); + }); + + test('FF disabled with dehydratedResources does not throw', () => { + stack.node.setContext(cxapi.CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS, false); + expect(() => { + includeTestTemplate(stack, 'intrinsics-update-policy-code-deploy-lambda-alias-update.json', { + dehydratedResources: ['Alias'], + }); + }).not.toThrow(); + }); + + test('dehydrated resources retain attributes with complex Intrinsics', () => { + stack.node.setContext(cxapi.CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS, true); + includeTestTemplate(stack, 'intrinsics-update-policy-code-deploy-lambda-alias-update.json', { + dehydratedResources: ['Alias'], + }); + + expect(Template.fromStack(stack).hasResource('AWS::Lambda::Alias', { + UpdatePolicy: { + CodeDeployLambdaAliasUpdate: { + 'Fn::If': [ + 'SomeCondition', + { + AfterAllowTrafficHook: 'SomeOtherHook', + ApplicationName: 'SomeApp', + BeforeAllowTrafficHook: 'SomeHook', + DeploymentGroupName: 'SomeDeploymentGroup', + }, + { + AfterAllowTrafficHook: 'SomeOtherOtherHook', + ApplicationName: 'SomeOtherApp', + BeforeAllowTrafficHook: 'SomeOtherHook', + DeploymentGroupName: 'SomeOtherDeploymentGroup', + + }, + ], + }, + }, + })); + }); + + test('dehydrated resources retain all attributes', () => { + includeTestTemplate(stack, 'resource-all-attributes.json', { + dehydratedResources: ['Foo'], + }); + + expect(Template.fromStack(stack).hasResource('AWS::Foo::Bar', { + Properties: { Blinky: 'Pinky' }, + Type: 'AWS::Foo::Bar', + CreationPolicy: { Inky: 'Clyde' }, + DeletionPolicy: { DeletionPolicyKey: 'DeletionPolicyValue' }, + Metadata: { SomeKey: 'SomeValue' }, + Version: '1.2.3.4.5.6', + UpdateReplacePolicy: { Oh: 'No' }, + Description: 'This resource does not match the spec, but it does have every possible attribute', + UpdatePolicy: { + Foo: 'Bar', + }, + })); + }); + + test('synth-time validation does not run on dehydrated resources', () => { + // synth-time validation fails if resource is hydrated + expect(() => { + includeTestTemplate(stack, 'intrinsics-tags-resource-validation.json'); + Template.fromStack(stack); + }).toThrow(`Resolution error: Supplied properties not correct for \"CfnLoadBalancerProps\" + tags: element 1: {} should have a 'key' and a 'value' property.`); + + app = new core.App({ context: { [cxapi.NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: false } }); + stack = new core.Stack(app); + + // synth-time validation not run if resource is dehydrated + includeTestTemplate(stack, 'intrinsics-tags-resource-validation.json', { + dehydratedResources: ['MyLoadBalancer'], + }); + + expect(Template.fromStack(stack).hasResource('AWS::ElasticLoadBalancingV2::LoadBalancer', { + Properties: { + Tags: [ + { + Key: 'Name', + Value: 'MyLoadBalancer', + }, + { + data: [ + 'IsExtraTag', + { + Key: 'Name2', + Value: 'MyLoadBalancer2', + }, + { + data: 'AWS::NoValue', + type: 'Ref', + isCfnFunction: true, + }, + ], + type: 'Fn::If', + isCfnFunction: true, + }, + ], + }, + })); + }); + + test('throws on dehydrated resources not present in the template', () => { + expect(() => { + includeTestTemplate(stack, 'intrinsics-tags-resource-validation.json', { + dehydratedResources: ['ResourceNotExistingHere'], + }); + }).toThrow(/Logical ID 'ResourceNotExistingHere' was specified in 'dehydratedResources', but does not belong to a resource in the template./); + }); }); interface IncludeTestTemplateProps { /** @default false */ readonly allowCyclicalReferences?: boolean; + + /** @default none */ + readonly dehydratedResources?: string[]; } function includeTestTemplate(scope: constructs.Construct, testTemplate: string, props: IncludeTestTemplateProps = {}): inc.CfnInclude { return new inc.CfnInclude(scope, 'MyScope', { templateFile: _testTemplateFilePath(testTemplate), allowCyclicalReferences: props.allowCyclicalReferences, + dehydratedResources: props.dehydratedResources, }); } diff --git a/packages/aws-cdk-lib/cloudformation-include/test/nested-stacks.test.ts b/packages/aws-cdk-lib/cloudformation-include/test/nested-stacks.test.ts index 6d43433c3b74b..06fb19716d3cf 100644 --- a/packages/aws-cdk-lib/cloudformation-include/test/nested-stacks.test.ts +++ b/packages/aws-cdk-lib/cloudformation-include/test/nested-stacks.test.ts @@ -743,6 +743,77 @@ describe('CDK Include for nested stacks', () => { }); }); }); + + describe('dehydrated resources', () => { + let parentStack: core.Stack; + let childStack: core.Stack; + + beforeEach(() => { + parentStack = new core.Stack(); + }); + + test('dehydrated resources are included in child templates, even if they are otherwise invalid', () => { + const parentTemplate = new inc.CfnInclude(parentStack, 'ParentStack', { + templateFile: testTemplateFilePath('parent-dehydrated.json'), + dehydratedResources: ['ASG'], + loadNestedStacks: { + 'ChildStack': { + templateFile: testTemplateFilePath('child-dehydrated.json'), + dehydratedResources: ['ChildASG'], + }, + }, + }); + childStack = parentTemplate.getNestedStack('ChildStack').stack; + + Template.fromStack(childStack).templateMatches({ + "Conditions": { + "SomeCondition": { + "Fn::Equals": [ + 2, + 2, + ], + }, + }, + "Resources": { + "ChildStackChildASGF815DFE9": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MaxSize": 10, + "MinSize": 1, + }, + "UpdatePolicy": { + "AutoScalingScheduledAction": { + "Fn::If": [ + "SomeCondition", + { + "IgnoreUnmodifiedGroupSizeProperties": true, + }, + { + "IgnoreUnmodifiedGroupSizeProperties": false, + }, + ], + }, + }, + }, + }, + }); + }); + + test('throws if a nested stack is marked dehydrated', () => { + expect(() => { + new inc.CfnInclude(parentStack, 'ParentStack', { + templateFile: testTemplateFilePath('parent-dehydrated.json'), + dehydratedResources: ['ChildStack'], + loadNestedStacks: { + 'ChildStack': { + templateFile: testTemplateFilePath('child-dehydrated.json'), + dehydratedResources: ['ChildASG'], + }, + }, + }); + }).toThrow(/nested stack 'ChildStack' was marked as dehydrated - nested stacks cannot be dehydrated/); + }); + }); }); function loadTestFileToJsObject(testTemplate: string): any { diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-create-policy-autoscaling.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-create-policy-autoscaling.json new file mode 100644 index 0000000000000..2730a163d5770 --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-create-policy-autoscaling.json @@ -0,0 +1,23 @@ +{ + "Parameters": { + "MinSuccessfulInstancesPercent": { + "Type": "Number" + } + }, + "Resources": { + "AutoScalingCreationPolicyIntrinsic": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MinSize": "1", + "MaxSize": "5" + }, + "CreationPolicy": { + "AutoScalingCreationPolicy": { + "MinSuccessfulInstancesPercent": { + "Ref": "MinSuccessfulInstancesPercent" + } + } + } + } + } +} diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-create-policy-complex.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-create-policy-complex.json new file mode 100644 index 0000000000000..82f46093f68d4 --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-create-policy-complex.json @@ -0,0 +1,42 @@ +{ + "Parameters": { + "CountParameter": { + "Type": "Number", + "Default": 3 + } + }, + "Conditions": { + "SomeCondition": { + "Fn::Equals": [ + 2, + 2 + ] + } + }, + "Resources": { + "ASG": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MinSize": "1", + "MaxSize": "5" + }, + "CreationPolicy": { + "AutoScalingCreationPolicy": { + "MinSuccessfulInstancesPercent": 50 + }, + "ResourceSignal": { + "Count": { + "Fn::If": [ + "SomeCondition", + { + "Ref": "CountParameter" + }, + 4 + ] + }, + "Timeout":"PT5H4M3S" + } + } + } + } +} diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-create-policy-resource-signal.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-create-policy-resource-signal.json new file mode 100644 index 0000000000000..40919f1e39b5b --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-create-policy-resource-signal.json @@ -0,0 +1,24 @@ +{ + "Parameters": { + "CountParameter": { + "Type": "Number", + "Default": 3 + } + }, + "Resources": { + "ResourceSignalIntrinsic": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MinSize": "1", + "MaxSize": "5" + }, + "CreationPolicy": { + "ResourceSignal": { + "Count": { + "Ref": "CountParameter" + } + } + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-autoscaling-replacing-update.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-autoscaling-replacing-update.json new file mode 100644 index 0000000000000..dd80cf6146a6c --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-autoscaling-replacing-update.json @@ -0,0 +1,22 @@ +{ + "Parameters": { + "WillReplace": { + "Type": "Boolean", + "Default": false + } + }, + "Resources": { + "ASG": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MinSize": "1", + "MaxSize": "10" + }, + "UpdatePolicy": { + "AutoScalingReplacingUpdate": { + "WillReplace" : { "Ref": "WillReplace" } + } + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-autoscaling-rolling-update.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-autoscaling-rolling-update.json new file mode 100644 index 0000000000000..bd55715595887 --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-autoscaling-rolling-update.json @@ -0,0 +1,37 @@ +{ + "Parameters": { + "MinInstances": { + "Type": "Number", + "Default": 1 + }, + "MaxBatchSize": { + "Type": "Number", + "Default": 1 + }, + "PauseTime": { + "Type": "String", + "Default": "PT5M" + }, + "WaitOnResourceSignals": { + "Type": "Boolean", + "Default": true + } + }, + "Resources": { + "ASG": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MinSize": "1", + "MaxSize": "10" + }, + "UpdatePolicy": { + "AutoScalingRollingUpdate": { + "MinInstancesInService": { "Ref": "MinInstances" }, + "MaxBatchSize": { "Ref": "MaxBatchSize" }, + "PauseTime": { "Ref": "PauseTime" }, + "WaitOnResourceSignals": { "Ref": "WaitOnResourceSignals" } + } + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-autoscaling-scheduled-action.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-autoscaling-scheduled-action.json new file mode 100644 index 0000000000000..27daa8a4f8972 --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-autoscaling-scheduled-action.json @@ -0,0 +1,24 @@ +{ + "Parameters": { + "IgnoreUnmodifiedGroupSizeProperties": { + "Type": "Boolean", + "Default": false + } + }, + "Resources": { + "ASG": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MinSize": "1", + "MaxSize": "10" + }, + "UpdatePolicy": { + "AutoScalingScheduledAction": { + "IgnoreUnmodifiedGroupSizeProperties": { + "Ref": "IgnoreUnmodifiedGroupSizeProperties" + } + } + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-code-deploy-lambda-alias-update.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-code-deploy-lambda-alias-update.json new file mode 100644 index 0000000000000..382b04a767b89 --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-code-deploy-lambda-alias-update.json @@ -0,0 +1,34 @@ +{ + "Parameters": { + "ApplicationName": { + "Type": "String" + }, + "DeploymentGroupName": { + "Type": "String" + }, + "BeforeAllowTrafficHook": { + "Type": "String" + }, + "AfterAllowTrafficHook": { + "Type": "String" + } + }, + "Resources": { + "Alias": { + "Type": "AWS::Lambda::Alias", + "Properties": { + "FunctionName": "SomeLambda", + "FunctionVersion": "SomeVersion", + "Name": "MyAlias" + }, + "UpdatePolicy": { + "CodeDeployLambdaAliasUpdate": { + "ApplicationName": { "Ref": "ApplicationName" }, + "DeploymentGroupName": { "Ref": "DeploymentGroupName" }, + "BeforeAllowTrafficHook": { "Ref": "BeforeAllowTrafficHook" }, + "AfterAllowTrafficHook": { "Ref": "AfterAllowTrafficHook" } + } + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-complex.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-complex.json new file mode 100644 index 0000000000000..6b0cdb351f00b --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/intrinsics-update-policy-complex.json @@ -0,0 +1,33 @@ +{ + "Conditions": { + "SomeCondition": { + "Fn::Equals": [ + 2, + 2 + ] + } + }, + "Resources": { + "ASG": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MinSize": "1", + "MaxSize": "10" + }, + "UpdatePolicy": { + "AutoScalingRollingUpdate": { + "MinInstancesInService": { + "Fn::If": [ + "SomeCondition", + 1, + 2 + ] + }, + "MaxBatchSize": 2, + "PauseTime": "PT5M", + "WaitOnResourceSignals": true + } + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-create-policy-autoscaling.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-create-policy-autoscaling.json new file mode 100644 index 0000000000000..9d6cfaddf2df2 --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-create-policy-autoscaling.json @@ -0,0 +1,28 @@ +{ + "Conditions": { + "SomeCondition": { + "Fn::Equals": [ + 2, + 2 + ] + } + }, + "Resources": { + "AutoScalingCreationPolicyIntrinsic": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MinSize": 1, + "MaxSize": 5 + }, + "CreationPolicy": { + "AutoScalingCreationPolicy": { + "Fn::If": [ + "SomeCondition", + { "MinSuccessfulInstancesPercent": 50 }, + { "MinSuccessfulInstancesPercent": 25 } + ] + } + } + } + } +} diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-create-policy-resource-signal.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-create-policy-resource-signal.json new file mode 100644 index 0000000000000..5fc823d4731d5 --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-create-policy-resource-signal.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "CountParameter": { + "Type": "Number", + "Default": 3 + } + }, + "Conditions": { + "UseCountParameter": { + "Fn::Equals": [ + 2, + 2 + ] + } + }, + "Resources": { + "ResourceSignalIntrinsic": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MinSize": 1, + "MaxSize": 5 + }, + "CreationPolicy": { + "ResourceSignal": { + "Fn::If": [ + "UseCountParameter", + { + "Count": { "Ref": "CountParameter" } + }, + 5 + ] + } + } + } + } +} diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-create-policy.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-create-policy.json new file mode 100644 index 0000000000000..2afe984191fcc --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-create-policy.json @@ -0,0 +1,42 @@ +{ + "Parameters": { + "CountParameter": { + "Type": "Number", + "Default": 3 + } + }, + "Conditions": { + "SomeCondition": { + "Fn::Equals": [ + 2, + 2 + ] + } + }, + "Resources": { + "CreationPolicyIntrinsic": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MinSize": 1, + "MaxSize": 5 + }, + "CreationPolicy": { + "Fn::If": [ + "SomeCondition", + { + "AutoScalingCreationPolicy": { + "MinSuccessfulInstancesPercent": 50 + }, + "ResourceSignal": { + "Count": 5, + "Timeout": "PT5H4M3S" + } + }, + { + "Ref": "AWS::NoValue" + } + ] + } + } + } +} diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-tags-resource-validation.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-tags-resource-validation.json new file mode 100644 index 0000000000000..b162016bb2577 --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-tags-resource-validation.json @@ -0,0 +1,54 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Parameters": { + "IsExtraTag": { + "Type": "String", + "AllowedValues": [ + "true", + "false" + ], + "Default": "false" + } + }, + "Conditions": { + "AddExtraTag": { + "Fn::Equals": [ + { + "data": "IsExtraTag", + "type": "Ref", + "isCfnFunction": true + }, + "true" + ] + } + }, + "Resources": { + "MyLoadBalancer": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "MyLoadBalancer" + }, + { + "data": [ + "IsExtraTag", + { + "Key": "Name2", + "Value": "MyLoadBalancer2" + }, + { + "data": "AWS::NoValue", + "type": "Ref", + "isCfnFunction": true + } + ], + "type": "Fn::If", + "isCfnFunction": true + } + ] + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy-autoscaling-replacing-update.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy-autoscaling-replacing-update.json new file mode 100644 index 0000000000000..e302385e89139 --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy-autoscaling-replacing-update.json @@ -0,0 +1,32 @@ +{ + "Conditions": { + "SomeCondition": { + "Fn::Equals": [ + 2, + 2 + ] + } + }, + "Resources": { + "ASG": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MaxSize": 10, + "MinSize": 1 + }, + "UpdatePolicy": { + "AutoScalingReplacingUpdate": { + "Fn::If": [ + "SomeCondition", + { + "WillReplace" : true + }, + { + "WillReplace" : false + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy-autoscaling-rolling-update.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy-autoscaling-rolling-update.json new file mode 100644 index 0000000000000..8d793770dda2a --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy-autoscaling-rolling-update.json @@ -0,0 +1,38 @@ +{ + "Conditions": { + "SomeCondition": { + "Fn::Equals": [ + 2, + 2 + ] + } + }, + "Resources": { + "ASG": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MaxSize": 10, + "MinSize": 1 + }, + "UpdatePolicy": { + "AutoScalingRollingUpdate": { + "Fn::If": [ + "SomeCondition", + { + "MinInstancesInService": 1, + "MaxBatchSize": 2, + "PauseTime": "PT5M", + "WaitOnResourceSignals": "true" + }, + { + "MinInstancesInService": 1, + "MaxBatchSize": 2, + "PauseTime": "PT5M", + "WaitOnResourceSignals": "true" + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy-autoscaling-scheduled-action.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy-autoscaling-scheduled-action.json new file mode 100644 index 0000000000000..2a6141f18fffb --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy-autoscaling-scheduled-action.json @@ -0,0 +1,32 @@ +{ + "Conditions": { + "SomeCondition": { + "Fn::Equals": [ + 2, + 2 + ] + } + }, + "Resources": { + "ASG": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MaxSize": 10, + "MinSize": 1 + }, + "UpdatePolicy": { + "AutoScalingScheduledAction": { + "Fn::If": [ + "SomeCondition", + { + "IgnoreUnmodifiedGroupSizeProperties" : true + }, + { + "IgnoreUnmodifiedGroupSizeProperties" : false + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy-code-deploy-lambda-alias-update.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy-code-deploy-lambda-alias-update.json new file mode 100644 index 0000000000000..92911296e5764 --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy-code-deploy-lambda-alias-update.json @@ -0,0 +1,39 @@ +{ + "Conditions": { + "SomeCondition": { + "Fn::Equals": [ + 2, + 2 + ] + } + }, + "Resources": { + "Alias": { + "Type": "AWS::Lambda::Alias", + "Properties": { + "FunctionName": "SomeLambda", + "FunctionVersion": "SomeVersion", + "Name": "MyAlias" + }, + "UpdatePolicy": { + "CodeDeployLambdaAliasUpdate": { + "Fn::If": [ + "SomeCondition", + { + "ApplicationName": "SomeApp", + "DeploymentGroupName": "SomeDeploymentGroup", + "BeforeAllowTrafficHook": "SomeHook", + "AfterAllowTrafficHook": "SomeOtherHook" + }, + { + "ApplicationName": "SomeOtherApp", + "DeploymentGroupName": "SomeOtherDeploymentGroup", + "BeforeAllowTrafficHook": "SomeOtherHook", + "AfterAllowTrafficHook": "SomeOtherOtherHook" + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy.json new file mode 100644 index 0000000000000..fe284e4e05828 --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/intrinsics-update-policy.json @@ -0,0 +1,40 @@ +{ + "Conditions": { + "SomeCondition": { + "Fn::Equals": [ + 2, + 2 + ] + } + }, + "Resources": { + "ASG": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MaxSize": 10, + "MinSize": 1 + }, + "UpdatePolicy": { + "Fn::If": [ + "SomeCondition", + { + "AutoScalingRollingUpdate": { + "MinInstancesInService": 1, + "MaxBatchSize": 2, + "PauseTime": "PT5M", + "WaitOnResourceSignals": "true" + } + }, + { + "AutoScalingRollingUpdate": { + "MinInstancesInService": 3, + "MaxBatchSize": 4, + "PauseTime": "PT5M", + "WaitOnResourceSignals": "false" + } + } + ] + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/resource-all-attributes.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/resource-all-attributes.json new file mode 100644 index 0000000000000..03316390e4e3b --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/resource-all-attributes.json @@ -0,0 +1,27 @@ +{ + "Resources": { + "Foo": { + "Type": "AWS::Foo::Bar", + "Properties": { + "Blinky": "Pinky" + }, + "CreationPolicy": { + "Inky": "Clyde" + }, + "UpdatePolicy": { + "Foo": "Bar" + }, + "DeletionPolicy": { + "DeletionPolicyKey": "DeletionPolicyValue" + }, + "UpdateReplacePolicy": { + "Oh": "No" + }, + "Version": "1.2.3.4.5.6" , + "Description": "This resource does not match the spec, but it does have every possible attribute", + "Metadata": { + "SomeKey": "SomeValue" + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/tags-with-invalid-intrinsics.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/tags-with-invalid-intrinsics.json similarity index 100% rename from packages/aws-cdk-lib/cloudformation-include/test/test-templates/tags-with-invalid-intrinsics.json rename to packages/aws-cdk-lib/cloudformation-include/test/test-templates/invalid/tags-with-invalid-intrinsics.json diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/nested/child-dehydrated.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/nested/child-dehydrated.json new file mode 100644 index 0000000000000..b390fdc70d22b --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/nested/child-dehydrated.json @@ -0,0 +1,32 @@ +{ + "Conditions": { + "SomeCondition": { + "Fn::Equals": [ + 2, + 2 + ] + } + }, + "Resources": { + "ChildASG": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MaxSize": 10, + "MinSize": 1 + }, + "UpdatePolicy": { + "AutoScalingScheduledAction": { + "Fn::If": [ + "SomeCondition", + { + "IgnoreUnmodifiedGroupSizeProperties" : true + }, + { + "IgnoreUnmodifiedGroupSizeProperties" : false + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/nested/parent-dehydrated.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/nested/parent-dehydrated.json new file mode 100644 index 0000000000000..ee0b92688962a --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/nested/parent-dehydrated.json @@ -0,0 +1,41 @@ +{ + "Conditions": { + "SomeCondition": { + "Fn::Equals": [ + 2, + 2 + ] + } + }, + "Resources": { + "ASG": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MaxSize": 10, + "MinSize": 1 + }, + "UpdatePolicy": { + "AutoScalingScheduledAction": { + "Fn::If": [ + "SomeCondition", + { + "IgnoreUnmodifiedGroupSizeProperties" : true + }, + { + "IgnoreUnmodifiedGroupSizeProperties" : false + } + ] + } + } + }, + "ChildStack": { + "Type": "AWS::CloudFormation::Stack", + "Properties": { + "TemplateURL": "https://cfn-templates-set.s3.amazonaws.com/child-dehydrated-stack.json", + "Parameters": { + "SomeParam": "SomeValue" + } + } + } + } +} diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/resource-attribute-update-policy.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/resource-attribute-update-policy.json deleted file mode 100644 index e1440a46193be..0000000000000 --- a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/resource-attribute-update-policy.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "Parameters": { - "WaitOnResourceSignals": { - "Type": "String", - "Default": "true" - } - }, - "Resources": { - "CodeDeployApp": { - "Type": "AWS::CodeDeploy::Application" - }, - "CodeDeployDg": { - "Type": "AWS::CodeDeploy::DeploymentGroup", - "Properties": { - "ApplicationName": { "Ref": "CodeDeployApp" }, - "ServiceRoleArn": "my-role-arn" - } - }, - "Bucket": { - "Type": "AWS::S3::Bucket", - "UpdatePolicy": { - "AutoScalingReplacingUpdate": { - "WillReplace": false - }, - "AutoScalingRollingUpdate": { - "MaxBatchSize" : 1, - "MinInstancesInService" : 2, - "MinSuccessfulInstancesPercent" : 3, - "PauseTime" : "PT4M3S", - "SuspendProcesses" : [ - "Launch", - "Terminate", - "HealthCheck", - "ReplaceUnhealthy", - "AZRebalance", - "AlarmNotification", - "ScheduledActions", - "AddToLoadBalancer" - ], - "WaitOnResourceSignals" : { - "Fn::Equals": [ - "true", - { "Ref": "WaitOnResourceSignals" } - ] - } - }, - "AutoScalingScheduledAction": { - "IgnoreUnmodifiedGroupSizeProperties": true - }, - "CodeDeployLambdaAliasUpdate" : { - "AfterAllowTrafficHook" : "Lambda1", - "ApplicationName" : { "Ref": "CodeDeployApp" }, - "BeforeAllowTrafficHook" : "Lambda2", - "DeploymentGroupName" : { "Ref": "CodeDeployDg" } - }, - "EnableVersionUpgrade": true, - "UseOnlineResharding": false - } - } - } -} diff --git a/packages/aws-cdk-lib/cloudformation-include/test/test-templates/update-policy-with-intrinsics.json b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/update-policy-with-intrinsics.json new file mode 100644 index 0000000000000..607443aa6c129 --- /dev/null +++ b/packages/aws-cdk-lib/cloudformation-include/test/test-templates/update-policy-with-intrinsics.json @@ -0,0 +1,47 @@ +{ + "Conditions": { + "AutoReplaceHosts": { + "Fn::Equals": [ + 2, + 2 + ] + }, + "SetMinInstancesInServiceToZero": { + "Fn::Equals": [ + 2, + 2 + ] + } + }, + "Resources": { + "ASG": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MaxSize": 10, + "MinSize": 1 + }, + "UpdatePolicy": { + "AutoScalingRollingUpdate": { + "Fn::If": [ + "AutoReplaceHosts", + { + "MinInstancesInService": { + "Fn::If": [ + "SetMinInstancesInServiceToZero", + 0, + 1 + ] + }, + "MaxBatchSize": 2, + "PauseTime": "PT5M", + "WaitOnResourceSignals": "true" + }, + { + "Ref": "AWS::NoValue" + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/packages/aws-cdk-lib/cloudformation-include/test/valid-templates.test.ts b/packages/aws-cdk-lib/cloudformation-include/test/valid-templates.test.ts index 8876e5c3fe50a..2f7b132f4aaf8 100644 --- a/packages/aws-cdk-lib/cloudformation-include/test/valid-templates.test.ts +++ b/packages/aws-cdk-lib/cloudformation-include/test/valid-templates.test.ts @@ -611,24 +611,91 @@ describe('CDK Include', () => { }); }); - test('correctly handles the CreationPolicy resource attribute', () => { - const cfnTemplate = includeTestTemplate(stack, 'resource-attribute-creation-policy.json'); - const cfnBucket = cfnTemplate.getResource('Bucket'); + test('Intrinsics can be used in the leaf nodes of autoscaling creation policy', () => { + const cfnTemplate = includeTestTemplate(stack, 'intrinsics-create-policy-autoscaling.json'); + const cfnBucket = cfnTemplate.getResource('AutoScalingCreationPolicyIntrinsic'); expect(cfnBucket.cfnOptions.creationPolicy).toBeDefined(); Template.fromStack(stack).templateMatches( - loadTestFileToJsObject('resource-attribute-creation-policy.json'), + loadTestFileToJsObject('intrinsics-create-policy-autoscaling.json'), ); }); - test('correctly handles the UpdatePolicy resource attribute', () => { - const cfnTemplate = includeTestTemplate(stack, 'resource-attribute-update-policy.json'); - const cfnBucket = cfnTemplate.getResource('Bucket'); + test('Nested intrinsics can be used in the leaf nodes of autoscaling creation policy', () => { + const cfnTemplate = includeTestTemplate(stack, 'intrinsics-create-policy-complex.json'); + const cfnBucket = cfnTemplate.getResource('ASG'); + + expect(cfnBucket.cfnOptions.creationPolicy).toBeDefined(); + + Template.fromStack(stack).templateMatches( + loadTestFileToJsObject('intrinsics-create-policy-complex.json'), + ); + }); + + test('intrinsics can be used in the leaf nodes of autoscaling resource signal creation policy', () => { + const cfnTemplate = includeTestTemplate(stack, 'intrinsics-create-policy-resource-signal.json'); + const cfnBucket = cfnTemplate.getResource('ResourceSignalIntrinsic'); + + expect(cfnBucket.cfnOptions.creationPolicy).toBeDefined(); + + Template.fromStack(stack).templateMatches( + loadTestFileToJsObject('intrinsics-create-policy-resource-signal.json'), + ); + }); + + test('Intrinsics can be used in the leaf nodes of autoscaling rolling update policy', () => { + const cfnTemplate = includeTestTemplate(stack, 'intrinsics-update-policy-autoscaling-rolling-update.json'); + const cfnBucket = cfnTemplate.getResource('ASG'); + + expect(cfnBucket.cfnOptions.updatePolicy).toBeDefined(); + + Template.fromStack(stack).templateMatches( + loadTestFileToJsObject('intrinsics-update-policy-autoscaling-rolling-update.json'), + ); + }); + + test('Intrinsics can be used in the leaf nodes of autoscaling replacing update policy', () => { + const cfnTemplate = includeTestTemplate(stack, 'intrinsics-update-policy-autoscaling-replacing-update.json'); + const cfnBucket = cfnTemplate.getResource('ASG'); + + expect(cfnBucket.cfnOptions.updatePolicy).toBeDefined(); + + Template.fromStack(stack).templateMatches( + loadTestFileToJsObject('intrinsics-update-policy-autoscaling-replacing-update.json'), + ); + }); + + test('Intrinsics can be used in the leaf nodes of autoscaling scheduled-action update policy', () => { + const cfnTemplate = includeTestTemplate(stack, 'intrinsics-update-policy-autoscaling-scheduled-action.json'); + const cfnBucket = cfnTemplate.getResource('ASG'); + + expect(cfnBucket.cfnOptions.updatePolicy).toBeDefined(); + + Template.fromStack(stack).templateMatches( + loadTestFileToJsObject('intrinsics-update-policy-autoscaling-scheduled-action.json'), + ); + }); + + test('Intrinsics can be used in the leaf nodes of code deploy lambda alias update policy', () => { + const cfnTemplate = includeTestTemplate(stack, 'intrinsics-update-policy-code-deploy-lambda-alias-update.json'); + const cfnBucket = cfnTemplate.getResource('Alias'); + + expect(cfnBucket.cfnOptions.updatePolicy).toBeDefined(); + + Template.fromStack(stack).templateMatches( + loadTestFileToJsObject('intrinsics-update-policy-code-deploy-lambda-alias-update.json'), + ); + }); + + test('Nested Intrinsics can be used in the leaf nodes of autoscaling rolling update policy', () => { + const cfnTemplate = includeTestTemplate(stack, 'intrinsics-update-policy-complex.json'); + const cfnBucket = cfnTemplate.getResource('ASG'); expect(cfnBucket.cfnOptions.updatePolicy).toBeDefined(); + Template.fromStack(stack).templateMatches( - loadTestFileToJsObject('resource-attribute-update-policy.json'), + loadTestFileToJsObject('intrinsics-update-policy-complex.json'), ); }); @@ -1129,12 +1196,6 @@ describe('CDK Include', () => { loadTestFileToJsObject('tags-with-intrinsics.json'), ); }); - - test('throws an exception if Tags contains invalid intrinsics', () => { - expect(() => { - includeTestTemplate(stack, 'tags-with-invalid-intrinsics.json'); - }).toThrow(/expression does not exist in the template/); - }); }); interface IncludeTestTemplateProps { diff --git a/packages/aws-cdk-lib/core/lib/helpers-internal/cfn-parse.ts b/packages/aws-cdk-lib/core/lib/helpers-internal/cfn-parse.ts index fbbb26c0c566e..839684b2e791f 100644 --- a/packages/aws-cdk-lib/core/lib/helpers-internal/cfn-parse.ts +++ b/packages/aws-cdk-lib/core/lib/helpers-internal/cfn-parse.ts @@ -1,3 +1,4 @@ +import { CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS } from '../../../cx-api'; import { CfnCondition } from '../cfn-condition'; import { CfnElement } from '../cfn-element'; import { Fn } from '../cfn-fn'; @@ -9,10 +10,12 @@ import { CfnCreationPolicy, CfnDeletionPolicy, CfnResourceAutoScalingCreationPolicy, CfnResourceSignal, CfnUpdatePolicy, } from '../cfn-resource-policy'; import { CfnTag } from '../cfn-tag'; +import { FeatureFlags } from '../feature-flags'; import { Lazy } from '../lazy'; import { CfnReference, ReferenceRendering } from '../private/cfn-reference'; import { IResolvable } from '../resolvable'; import { Validator } from '../runtime'; +import { Stack } from '../stack'; import { isResolvableObject, Token } from '../token'; import { undefinedIfAllValuesAreEmpty } from '../util'; @@ -343,6 +346,7 @@ export interface ParseCfnOptions { */ export class CfnParser { private readonly options: ParseCfnOptions; + private stack?: Stack; constructor(options: ParseCfnOptions) { this.options = options; @@ -350,9 +354,10 @@ export class CfnParser { public handleAttributes(resource: CfnResource, resourceAttributes: any, logicalId: string): void { const cfnOptions = resource.cfnOptions; + this.stack = Stack.of(resource); - cfnOptions.creationPolicy = this.parseCreationPolicy(resourceAttributes.CreationPolicy); - cfnOptions.updatePolicy = this.parseUpdatePolicy(resourceAttributes.UpdatePolicy); + cfnOptions.creationPolicy = this.parseCreationPolicy(resourceAttributes.CreationPolicy, logicalId); + cfnOptions.updatePolicy = this.parseUpdatePolicy(resourceAttributes.UpdatePolicy, logicalId); cfnOptions.deletionPolicy = this.parseDeletionPolicy(resourceAttributes.DeletionPolicy); cfnOptions.updateReplacePolicy = this.parseDeletionPolicy(resourceAttributes.UpdateReplacePolicy); cfnOptions.version = this.parseValue(resourceAttributes.Version); @@ -381,8 +386,10 @@ export class CfnParser { } } - private parseCreationPolicy(policy: any): CfnCreationPolicy | undefined { + private parseCreationPolicy(policy: any, logicalId: string): CfnCreationPolicy | undefined { if (typeof policy !== 'object') { return undefined; } + this.throwIfIsIntrinsic(policy, logicalId); + const self = this; // change simple JS values to their CDK equivalents policy = this.parseValue(policy); @@ -393,6 +400,7 @@ export class CfnParser { }); function parseAutoScalingCreationPolicy(p: any): CfnResourceAutoScalingCreationPolicy | undefined { + self.throwIfIsIntrinsic(p, logicalId); if (typeof p !== 'object') { return undefined; } return undefinedIfAllValuesAreEmpty({ @@ -402,6 +410,7 @@ export class CfnParser { function parseResourceSignal(p: any): CfnResourceSignal | undefined { if (typeof p !== 'object') { return undefined; } + self.throwIfIsIntrinsic(p, logicalId); return undefinedIfAllValuesAreEmpty({ count: FromCloudFormation.getNumber(p.Count).value, @@ -410,8 +419,10 @@ export class CfnParser { } } - private parseUpdatePolicy(policy: any): CfnUpdatePolicy | undefined { + private parseUpdatePolicy(policy: any, logicalId: string): CfnUpdatePolicy | undefined { if (typeof policy !== 'object') { return undefined; } + this.throwIfIsIntrinsic(policy, logicalId); + const self = this; // change simple JS values to their CDK equivalents policy = this.parseValue(policy); @@ -427,6 +438,7 @@ export class CfnParser { function parseAutoScalingReplacingUpdate(p: any): CfnAutoScalingReplacingUpdate | undefined { if (typeof p !== 'object') { return undefined; } + self.throwIfIsIntrinsic(p, logicalId); return undefinedIfAllValuesAreEmpty({ willReplace: p.WillReplace, @@ -435,6 +447,7 @@ export class CfnParser { function parseAutoScalingRollingUpdate(p: any): CfnAutoScalingRollingUpdate | undefined { if (typeof p !== 'object') { return undefined; } + self.throwIfIsIntrinsic(p, logicalId); return undefinedIfAllValuesAreEmpty({ maxBatchSize: FromCloudFormation.getNumber(p.MaxBatchSize).value, @@ -447,6 +460,7 @@ export class CfnParser { } function parseCodeDeployLambdaAliasUpdate(p: any): CfnCodeDeployLambdaAliasUpdate | undefined { + self.throwIfIsIntrinsic(p, logicalId); if (typeof p !== 'object') { return undefined; } return { @@ -458,6 +472,7 @@ export class CfnParser { } function parseAutoScalingScheduledAction(p: any): CfnAutoScalingScheduledAction | undefined { + self.throwIfIsIntrinsic(p, logicalId); if (typeof p !== 'object') { return undefined; } return undefinedIfAllValuesAreEmpty({ @@ -674,6 +689,20 @@ export class CfnParser { } } + private throwIfIsIntrinsic(object: object, logicalId: string): void { + // Top-level parsing functions check before we call `parseValue`, which requires + // calling `looksLikeCfnIntrinsic`. Helper parsing functions check after we call + // `parseValue`, which requires calling `isResolvableObject`. + if (!this.stack) { + throw new Error('cannot call this method before handleAttributes!'); + } + if (FeatureFlags.of(this.stack).isEnabled(CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS)) { + if (isResolvableObject(object ?? {}) || this.looksLikeCfnIntrinsic(object ?? {})) { + throw new Error(`Cannot convert resource '${logicalId}' to CDK objects: it uses an intrinsic in a resource update or deletion policy to represent a non-primitive value. Specify '${logicalId}' in the 'dehydratedResources' prop to skip parsing this resource, while still including it in the output.`); + } + } + } + private looksLikeCfnIntrinsic(object: object): string | undefined { const objectKeys = Object.keys(object); // a CFN intrinsic is always an object with a single key diff --git a/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md b/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md index 2de4a12515cb1..c2813160d9f03 100644 --- a/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +++ b/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md @@ -77,6 +77,7 @@ Flags come in three types: | [@aws-cdk/aws-ec2:ec2SumTImeoutEnabled](#aws-cdkaws-ec2ec2sumtimeoutenabled) | When enabled, initOptions.timeout and resourceSignalTimeout values will be summed together. | 2.160.0 | (fix) | | [@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission](#aws-cdkaws-appsyncappsyncgraphqlapiscopelambdapermission) | When enabled, a Lambda authorizer Permission created when using GraphqlApi will be properly scoped with a SourceArn. | V2NEXT | (fix) | | [@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId](#aws-cdkaws-rdssetcorrectvaluefordatabaseinstancereadreplicainstanceresourceid) | When enabled, the value of property `instanceResourceId` in construct `DatabaseInstanceReadReplica` will be set to the correct value which is `DbiResourceId` instead of currently `DbInstanceArn` | V2NEXT | (fix) | +| [@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics](#aws-cdkcorecfnincluderejectcomplexresourceupdatecreatepolicyintrinsics) | When enabled, CFN templates added with `cfn-include` will error if the template contains Resource Update or Create policies with CFN Intrinsics that include non-primitive values. | V2NEXT | (fix) | @@ -141,8 +142,9 @@ The following json shows the current recommended set of flags, as `cdk init` wou "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false, "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true, "@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true, - "@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true - "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true + "@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true, + "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true, + "@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true } } ``` @@ -1455,4 +1457,19 @@ When this feature flag is enabled, the value of that property will be as expecte **Compatibility with old behavior:** Disable the feature flag to use `DbInstanceArn` as value for property `instanceResourceId` +### @aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics + +*When enabled, CFN templates added with `cfn-include` will error if the template contains Resource Update or Create policies with CFN Intrinsics that include non-primitive values.* (fix) + +Without enabling this feature flag, `cfn-include` will silently drop resource update or create policies that contain CFN Intrinsics if they include non-primitive values. + +Enabling this feature flag will make `cfn-include` throw on these templates, unless you specify the logical ID of the resource in the 'unhydratedResources' property. + + +| Since | Default | Recommended | +| ----- | ----- | ----- | +| (not in v1) | | | +| V2NEXT | `false` | `true` | + + diff --git a/packages/aws-cdk-lib/cx-api/lib/features.ts b/packages/aws-cdk-lib/cx-api/lib/features.ts index b89ad272b63a4..f31d2d3b78687 100644 --- a/packages/aws-cdk-lib/cx-api/lib/features.ts +++ b/packages/aws-cdk-lib/cx-api/lib/features.ts @@ -111,6 +111,7 @@ export const REDUCE_EC2_FARGATE_CLOUDWATCH_PERMISSIONS = '@aws-cdk/aws-ecs:reduc export const EC2_SUM_TIMEOUT_ENABLED = '@aws-cdk/aws-ec2:ec2SumTImeoutEnabled'; export const APPSYNC_GRAPHQLAPI_SCOPE_LAMBDA_FUNCTION_PERMISSION = '@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission'; export const USE_CORRECT_VALUE_FOR_INSTANCE_RESOURCE_ID_PROPERTY = '@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId'; +export const CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS = '@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics'; export const FLAGS: Record = { ////////////////////////////////////////////////////////////////////// @@ -1189,6 +1190,19 @@ export const FLAGS: Record = { recommendedValue: true, compatibilityWithOldBehaviorMd: 'Disable the feature flag to use `DbInstanceArn` as value for property `instanceResourceId`', }, + + ////////////////////////////////////////////////////////////////////// + [CFN_INCLUDE_REJECT_COMPLEX_RESOURCE_UPDATE_CREATE_POLICY_INTRINSICS]: { + type: FlagType.BugFix, + summary: 'When enabled, CFN templates added with `cfn-include` will error if the template contains Resource Update or Create policies with CFN Intrinsics that include non-primitive values.', + detailsMd: ` + Without enabling this feature flag, \`cfn-include\` will silently drop resource update or create policies that contain CFN Intrinsics if they include non-primitive values. + + Enabling this feature flag will make \`cfn-include\` throw on these templates, unless you specify the logical ID of the resource in the 'unhydratedResources' property. + `, + recommendedValue: true, + introducedIn: { v2: 'V2NEXT' }, + }, }; const CURRENT_MV = 'v2'; diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json index 3003b87c37138..9be2acf76bb78 100644 --- a/packages/aws-cdk-lib/package.json +++ b/packages/aws-cdk-lib/package.json @@ -136,7 +136,7 @@ "mime-types": "^2.1.35" }, "devDependencies": { - "@aws-cdk/aws-service-spec": "^0.1.24", + "@aws-cdk/aws-service-spec": "^0.1.25", "@aws-cdk/cdk-build-tools": "0.0.0", "@aws-cdk/custom-resource-handlers": "0.0.0", "@aws-cdk/pkglint": "0.0.0", diff --git a/tools/@aws-cdk/spec2cdk/package.json b/tools/@aws-cdk/spec2cdk/package.json index a344e3a14b49d..35bb89b93c127 100644 --- a/tools/@aws-cdk/spec2cdk/package.json +++ b/tools/@aws-cdk/spec2cdk/package.json @@ -32,9 +32,9 @@ }, "license": "Apache-2.0", "dependencies": { - "@aws-cdk/aws-service-spec": "^0.1.24", - "@aws-cdk/service-spec-importers": "^0.0.48", - "@aws-cdk/service-spec-types": "^0.0.91", + "@aws-cdk/aws-service-spec": "^0.1.25", + "@aws-cdk/service-spec-importers": "^0.0.49", + "@aws-cdk/service-spec-types": "^0.0.92", "@cdklabs/tskb": "^0.0.3", "@cdklabs/typewriter": "^0.0.3", "camelcase": "^6", diff --git a/yarn.lock b/yarn.lock index 86eda7859163b..40a96c0a5843c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -51,12 +51,12 @@ resolved "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.1.0.tgz#6d3c7860354d4856a7e75375f2f0ecab313b4989" integrity sha512-7bY3J8GCVxLupn/kNmpPc5VJz8grx+4RKfnnJiO1LG+uxkZfANZG3RMHhE+qQxxwkyQ9/MfPtTpf748UhR425A== -"@aws-cdk/aws-service-spec@^0.1.24": - version "0.1.24" - resolved "https://registry.npmjs.org/@aws-cdk/aws-service-spec/-/aws-service-spec-0.1.24.tgz#a4f76708430e7fee2f2721ba4686d4fba675fb6a" - integrity sha512-8CTXSMyuNXwp/dnDj7SJi45VG7n+gbtH6zjHBIJNRw8Xt3DdArgyG/C9D+Epl9SRKqRu/xQyM/IZwSi9Fl01Vw== +"@aws-cdk/aws-service-spec@^0.1.25": + version "0.1.25" + resolved "https://registry.npmjs.org/@aws-cdk/aws-service-spec/-/aws-service-spec-0.1.25.tgz#cb6b91a51e5c81d75c20f84fa79d68b381fc9d03" + integrity sha512-5Zzqa1NDm9HrcV2BPOFoavrqXmNm+g6dF59fOkPkjuW9OwiR93fFK9AMc8KYJ7U7jRUejs6pn2bDnqGZ5IXTRg== dependencies: - "@aws-cdk/service-spec-types" "^0.0.91" + "@aws-cdk/service-spec-types" "^0.0.92" "@cdklabs/tskb" "^0.0.3" "@aws-cdk/cloud-assembly-schema@^38.0.0": @@ -89,12 +89,12 @@ resolved "https://registry.npmjs.org/@aws-cdk/lambda-layer-kubectl-v30/-/lambda-layer-kubectl-v30-2.0.1.tgz#2adbb8fc27f926596914f35ab3617622ca088066" integrity sha512-R4N2OTq9jCxARAmrp2TBNRkVreVa01wgAC4GNRRfZ8C4UD5+Cz+vylIyyJsVPD7WWZpdBSWDidnVMpvwTpAsQQ== -"@aws-cdk/service-spec-importers@^0.0.48": - version "0.0.48" - resolved "https://registry.npmjs.org/@aws-cdk/service-spec-importers/-/service-spec-importers-0.0.48.tgz#fe3a8bf2b68e492e2207616eb1cb46f29d4d9ede" - integrity sha512-RNPIl8egwYhmlK9g3DPfIHYcvwV03aSOuLwGN4FtSxRJ8Au/Fv1DCy+p+HQhczwhSVarYvLJmul5c2rNoMqZfw== +"@aws-cdk/service-spec-importers@^0.0.49": + version "0.0.49" + resolved "https://registry.npmjs.org/@aws-cdk/service-spec-importers/-/service-spec-importers-0.0.49.tgz#652b398999a345ea42319a0ab4724aaac934a12d" + integrity sha512-NINippOmojei4ZYUeCwaYz6iXPfTA6tZ83DTgf9slZn3U6JsieCfbHUxaT2mfAl/ExajX2ycdCVGYJcNWlo2ww== dependencies: - "@aws-cdk/service-spec-types" "^0.0.91" + "@aws-cdk/service-spec-types" "^0.0.92" "@cdklabs/tskb" "^0.0.3" ajv "^6" canonicalize "^2.0.0" @@ -105,10 +105,10 @@ glob "^8" sort-json "^2.0.1" -"@aws-cdk/service-spec-types@^0.0.91": - version "0.0.91" - resolved "https://registry.npmjs.org/@aws-cdk/service-spec-types/-/service-spec-types-0.0.91.tgz#e6a0daf0831a77b34dc6e72cd4908916a6909a62" - integrity sha512-J6YyYvH0Ov6bzA2FR68WUDQrp6fQkw8968UjUqMS9Vq0h2iZ/0n4nBcLGWqQuGPVT/Yex7Hfj4dhFsRXCJGEDw== +"@aws-cdk/service-spec-types@^0.0.92": + version "0.0.92" + resolved "https://registry.npmjs.org/@aws-cdk/service-spec-types/-/service-spec-types-0.0.92.tgz#9f102887ef7a9a5b0829869ad6910d58a91e89fa" + integrity sha512-lqZa2/ieUB4ujqEsWl4+f0CFO60aabT1+5/F9z748Jgo7Q+zmv1G0awZuvjUWijkEM4VShg4aSl9s/WkMBbVXA== dependencies: "@cdklabs/tskb" "^0.0.3"