From e93899c87b1ee1effe0e1dbbee0322f5def9b89b Mon Sep 17 00:00:00 2001 From: Rico Hermans Date: Thu, 15 Jun 2023 09:21:45 +0200 Subject: [PATCH 1/5] chore: update cdk-generate-synthetic-examples (#25982) Bump the version of this package to obtain the following fix: https://github.com/cdklabs/cdk-generate-synthetic-examples/pull/272 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- package.json | 2 +- yarn.lock | 91 +++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 3b6d6b1a991da..6b144f859863b 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "@types/node": "18.11.19", "@types/prettier": "2.6.0", "@yarnpkg/lockfile": "^1.1.0", - "cdk-generate-synthetic-examples": "^0.1.260", + "cdk-generate-synthetic-examples": "^0.1.269", "conventional-changelog-cli": "^2.2.2", "fs-extra": "^9.1.0", "graceful-fs": "^4.2.11", diff --git a/yarn.lock b/yarn.lock index b40af912ec932..520112a268c44 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1899,6 +1899,14 @@ chalk "^4.1.2" semver "^7.5.1" +"@jsii/check-node@1.84.0": + version "1.84.0" + resolved "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.84.0.tgz#cbed3a116b141e8dbef198dc161088bca603de0a" + integrity sha512-gLa+N1WKksCjTXaK8VMjTbEXf58QlrDOovoTOEzhGNgTFyAUX8woIRAUmk+X70ssDzBvgh3E98mIsDKoWOp6zA== + dependencies: + chalk "^4.1.2" + semver "^7.5.1" + "@jsii/spec@1.81.0": version "1.81.0" resolved "https://registry.npmjs.org/@jsii/spec/-/spec-1.81.0.tgz#35c461a10dbf8e903df4956eb9d1097c1fcc8129" @@ -1913,6 +1921,13 @@ dependencies: ajv "^8.12.0" +"@jsii/spec@1.84.0", "@jsii/spec@^1.84.0": + version "1.84.0" + resolved "https://registry.npmjs.org/@jsii/spec/-/spec-1.84.0.tgz#75f86e819999a5ee7b1430b274bf88459085bfc2" + integrity sha512-P2PCE4jlmuTh5Oj7Be2jdn5qyzIWHX4rcyYspddc0DLZAuLB/LRQYytrxgfdy4+NroGhrPeKPBoF9MwJ5CzfXA== + dependencies: + ajv "^8.12.0" + "@lerna/child-process@6.6.2": version "6.6.2" resolved "https://registry.npmjs.org/@lerna/child-process/-/child-process-6.6.2.tgz#5d803c8dee81a4e013dc428292e77b365cba876c" @@ -4280,16 +4295,16 @@ case@1.6.3, case@^1.6.3: resolved "https://registry.npmjs.org/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== -cdk-generate-synthetic-examples@^0.1.260: - version "0.1.266" - resolved "https://registry.npmjs.org/cdk-generate-synthetic-examples/-/cdk-generate-synthetic-examples-0.1.266.tgz#60dc1d1862b112c9b1b6741a5fa8170604428fd7" - integrity sha512-gO9QRCD800hMF/m9J0cq1eOnSgkpe8IjccZC2pZtm2XDY/TA3iLE/dwqfKOKAe+qBI4icwEt1Cdn3fx4yqH+jA== +cdk-generate-synthetic-examples@^0.1.269: + version "0.1.269" + resolved "https://registry.npmjs.org/cdk-generate-synthetic-examples/-/cdk-generate-synthetic-examples-0.1.269.tgz#ebbf3f63c00f60ac60ad7a7e6a1526e00daed8a5" + integrity sha512-8EnMZDMwX5Kfs1qkEcXxCvqdz8bZzXz5gEfyDSRkyGHHXJlinLGWIlBBKivst2qI3kRAPWNbgmKPv1KwaQ1M7A== dependencies: - "@jsii/spec" "^1.83.0" + "@jsii/spec" "^1.84.0" fs-extra "^10.1.0" - jsii "^1.83.0" - jsii-reflect "^1.83.0" - jsii-rosetta "^1.83.0" + jsii "^1.84.0" + jsii-reflect "^1.84.0" + jsii-rosetta "^1.84.0" yargs "^17.7.2" cdk8s-plus-24@2.7.31: @@ -8091,7 +8106,7 @@ jsii-reflect@1.82.0: oo-ascii-tree "^1.82.0" yargs "^16.2.0" -jsii-reflect@^1.82.0, jsii-reflect@^1.83.0: +jsii-reflect@^1.82.0: version "1.83.0" resolved "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.83.0.tgz#fb4ef6a93f7acd55cfb3c4b18b46e23316f1b116" integrity sha512-cR3QxpoUp8w9CwCP8dtkff8PZfQMT1gbciUObs0Mr6E2bEyH33QpOmllkIHMspZqtBiz46pWrIkAe5IqJnadtg== @@ -8103,7 +8118,19 @@ jsii-reflect@^1.82.0, jsii-reflect@^1.83.0: oo-ascii-tree "^1.83.0" yargs "^16.2.0" -jsii-rosetta@^1.82.0, jsii-rosetta@^1.83.0: +jsii-reflect@^1.84.0: + version "1.84.0" + resolved "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.84.0.tgz#95b71dabcf3c5fc275e623a29a1d7091fc893e38" + integrity sha512-Iuh0GAxsQscK1re9sWEQHG0wKswnr7ha4EZ8j47Sigo8yBIZNp01P+V0kbZ55bDjiT66Sqqu3jaDJdYzR/5o4w== + dependencies: + "@jsii/check-node" "1.84.0" + "@jsii/spec" "^1.84.0" + chalk "^4" + fs-extra "^10.1.0" + oo-ascii-tree "^1.84.0" + yargs "^16.2.0" + +jsii-rosetta@^1.82.0: version "1.83.0" resolved "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.83.0.tgz#da1a3f51911e609fac0912918edb0db584f0566c" integrity sha512-9yMTijjLoINcrhzA+r96zAPAEvVNXRqKei5SOP+ScmGKhPZ1/fYb7Z3+Unr3VWkWgUtVaiqUZTxAvVUAQHo/Pg== @@ -8121,6 +8148,24 @@ jsii-rosetta@^1.82.0, jsii-rosetta@^1.83.0: workerpool "^6.4.0" yargs "^16.2.0" +jsii-rosetta@^1.84.0: + version "1.84.0" + resolved "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.84.0.tgz#1dca8518f4ae6780beb8d73b54b013a3a1420b8e" + integrity sha512-VrXmc6utiNs3eNTKxVky0LTxoQrsh5GuEGyfj9ihwCkojYBJ3w80PdkMQEeRpWGdaCLEocjpy1X67xgZ4ZbPlg== + dependencies: + "@jsii/check-node" "1.84.0" + "@jsii/spec" "1.84.0" + "@xmldom/xmldom" "^0.8.8" + commonmark "^0.30.0" + fast-glob "^3.2.12" + jsii "1.84.0" + semver "^7.5.1" + semver-intersect "^1.4.0" + stream-json "^1.8.0" + typescript "~3.9.10" + workerpool "^6.4.0" + yargs "^16.2.0" + jsii-rosetta@~5.0.8: version "5.0.10" resolved "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-5.0.10.tgz#e8aea738aabfa20412ead5a81cfbe517142fc820" @@ -8140,7 +8185,7 @@ jsii-rosetta@~5.0.8: workerpool "^6.4.0" yargs "^17.7.2" -jsii@1.83.0, jsii@^1.83.0: +jsii@1.83.0: version "1.83.0" resolved "https://registry.npmjs.org/jsii/-/jsii-1.83.0.tgz#3a1af5f3a68885568220ffbfd1bbd3306e80dd6e" integrity sha512-LxWncwj1lEJN0IIFksrNSh4ksTUbMKLLS6UC01JKxOiyVvxuXTc0skl3XYCVLjJvd1S20oBSalFD2evxMFUaqQ== @@ -8159,6 +8204,25 @@ jsii@1.83.0, jsii@^1.83.0: typescript "~3.9.10" yargs "^16.2.0" +jsii@1.84.0, jsii@^1.84.0: + version "1.84.0" + resolved "https://registry.npmjs.org/jsii/-/jsii-1.84.0.tgz#57e631c85ac2d4ffcc2f59a9c68591fcfaf5667e" + integrity sha512-vtrw3fRrr5Do4LDNxAVXHgtHDyxHvohyzAfBwxcMEYzZ51gJX52wsdlaGE1p0dPe1V9uCAbNQTDKbAMgVJkg0Q== + dependencies: + "@jsii/check-node" "1.84.0" + "@jsii/spec" "^1.84.0" + case "^1.6.3" + chalk "^4" + fast-deep-equal "^3.1.3" + fs-extra "^10.1.0" + log4js "^6.9.1" + semver "^7.5.1" + semver-intersect "^1.4.0" + sort-json "^2.0.1" + spdx-license-list "^6.6.0" + typescript "~3.9.10" + yargs "^16.2.0" + jsii@5.0.x, jsii@~5.0.8: version "5.0.10" resolved "https://registry.npmjs.org/jsii/-/jsii-5.0.10.tgz#0bf853e02e4c21ab88fc6c73ec2dc01a9d1156f9" @@ -10025,6 +10089,11 @@ oo-ascii-tree@^1.81.0, oo-ascii-tree@^1.82.0, oo-ascii-tree@^1.83.0: resolved "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.83.0.tgz#686cd8ccf41d10ba24e8d49e7e58e9b12569f86a" integrity sha512-Fib3Py1moaeRkIRCZyKmqHvuWGf1x3SXE5vjFc5L13EMgycO6edNgkLFa/0zSy+oZHzkNneLY3Ozt7UZFy0k6g== +oo-ascii-tree@^1.84.0: + version "1.84.0" + resolved "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.84.0.tgz#82828d8c962b637bffa0d1b8a555c337907837e9" + integrity sha512-8bvsAKFAQ7HwU3lAEDwsKYDkTqsDTsRTkr3J0gvH1U805d2no9rUNYptWzg3oYku5h5mr9Bko+BIh1pjSD8qrg== + open@^7.4.2: version "7.4.2" resolved "https://registry.npmjs.org/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" From 28df61866096829d2dd87e9174724764649f2524 Mon Sep 17 00:00:00 2001 From: Akira kure <1259315+kuredev@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:23:09 +0900 Subject: [PATCH 2/5] feat(ec2): add addSecurityGroup method to launth template (#25697) [LaunchTemplateProps](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.LaunchTemplateProps.html) is able to process a single securityGroup. Currently we are required to use connections when we wanted to use multiple security groups. https://github.com/aws/aws-cdk/issues/18712#issuecomment-1026975615 I implemented addSecurityGroup method to make this easier. Closes #18712 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...efaultTestDeployAssert1AF2B360.assets.json | 2 +- .../aws-cdk-ec2-lt-metadata-1.assets.json | 19 +- .../aws-cdk-ec2-lt-metadata-1.template.json | 177 ++++++++++++++ .../integ.launch-template.js.snapshot/cdk.out | 2 +- .../integ.json | 2 +- .../manifest.json | 40 ++- .../tree.json | 227 +++++++++++++++--- .../aws-ec2/test/integ.launch-template.ts | 18 +- packages/aws-cdk-lib/aws-ec2/README.md | 20 +- .../aws-ec2/lib/launch-template.ts | 12 + 10 files changed, 479 insertions(+), 40 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.assets.json index 57e75754f5e88..5e84c5907c2b7 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/LambdaTestDefaultTestDeployAssert1AF2B360.assets.json @@ -1,5 +1,5 @@ { - "version": "22.0.0", + "version": "31.0.0", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.assets.json index dac10038e94d8..aab012dc86078 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.assets.json @@ -1,7 +1,20 @@ { - "version": "22.0.0", + "version": "31.0.0", "files": { - "534a1fbecaccb7e2a071086c8085be5c15b2501781767cdeddf754fe3a0ceecb": { + "ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd": { + "source": { + "path": "asset.ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "7151bb47e356bd29580b060ae0e46d6454585c5abca0d036f27da245eccd1fd9": { "source": { "path": "aws-cdk-ec2-lt-metadata-1.template.json", "packaging": "file" @@ -9,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "534a1fbecaccb7e2a071086c8085be5c15b2501781767cdeddf754fe3a0ceecb.json", + "objectKey": "7151bb47e356bd29580b060ae0e46d6454585c5abca0d036f27da245eccd1fd9.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.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.template.json index 83f874269b6db..7e277c0655b5e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/aws-cdk-ec2-lt-metadata-1.template.json @@ -1,5 +1,152 @@ { "Resources": { + "MyVpcF9F0CA6F": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "MyVpc" + } + ] + } + }, + "MyVpcRestrictDefaultSecurityGroupCustomResourceA4FCCD62": { + "Type": "Custom::VpcRestrictDefaultSG", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "CustomVpcRestrictDefaultSGCustomResourceProviderHandlerDC833E5E", + "Arn" + ] + }, + "DefaultSecurityGroupId": { + "Fn::GetAtt": [ + "MyVpcF9F0CA6F", + "DefaultSecurityGroup" + ] + }, + "Account": { + "Ref": "AWS::AccountId" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ], + "Policies": [ + { + "PolicyName": "Inline", + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:AuthorizeSecurityGroupEgress", + "ec2:RevokeSecurityGroupIngress", + "ec2:RevokeSecurityGroupEgress" + ], + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":security-group/", + { + "Fn::GetAtt": [ + "MyVpcF9F0CA6F", + "DefaultSecurityGroup" + ] + } + ] + ] + } + ] + } + ] + } + } + ] + } + }, + "CustomVpcRestrictDefaultSGCustomResourceProviderHandlerDC833E5E": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "ba598c1f1d84f7077ea9c16a6b921e4f8acf18e996100e72a8f17da980e64fdd.zip" + }, + "Timeout": 900, + "MemorySize": 128, + "Handler": "__entrypoint__.handler", + "Role": { + "Fn::GetAtt": [ + "CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0", + "Arn" + ] + }, + "Runtime": "nodejs16.x", + "Description": "Lambda function for removing all inbound/outbound rules from the VPC default security group" + }, + "DependsOn": [ + "CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0" + ] + }, + "sg15CEFF4E3": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-cdk-ec2-lt-metadata-1/sg1", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } + } + }, "LTC4631592": { "Type": "AWS::EC2::LaunchTemplate", "Properties": { @@ -11,6 +158,20 @@ "HttpTokens": "required", "InstanceMetadataTags": "enabled" }, + "SecurityGroupIds": [ + { + "Fn::GetAtt": [ + "sg15CEFF4E3", + "GroupId" + ] + }, + { + "Fn::GetAtt": [ + "sg2860DD91F", + "GroupId" + ] + } + ], "TagSpecifications": [ { "ResourceType": "instance", @@ -45,6 +206,22 @@ ] } }, + "sg2860DD91F": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-cdk-ec2-lt-metadata-1/sg2", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } + } + }, "LTWithMachineImageAAC227A5": { "Type": "AWS::EC2::LaunchTemplate", "Properties": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/cdk.out index 145739f539580..7925065efbcc4 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"22.0.0"} \ No newline at end of file +{"version":"31.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/integ.json index d0325b9f439fc..c0a61b5dc42ea 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "22.0.0", + "version": "31.0.0", "testCases": { "LambdaTest/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/manifest.json index 2a95821bd2fc1..37f50038cfe12 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "22.0.0", + "version": "31.0.0", "artifacts": { "aws-cdk-ec2-lt-metadata-1.assets": { "type": "cdk:asset-manifest", @@ -17,7 +17,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/534a1fbecaccb7e2a071086c8085be5c15b2501781767cdeddf754fe3a0ceecb.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/7151bb47e356bd29580b060ae0e46d6454585c5abca0d036f27da245eccd1fd9.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -33,12 +33,48 @@ "aws-cdk-ec2-lt-metadata-1.assets" ], "metadata": { + "/aws-cdk-ec2-lt-metadata-1/MyVpc/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcF9F0CA6F" + } + ], + "/aws-cdk-ec2-lt-metadata-1/MyVpc/RestrictDefaultSecurityGroupCustomResource/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "MyVpcRestrictDefaultSecurityGroupCustomResourceA4FCCD62" + } + ], + "/aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0" + } + ], + "/aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomVpcRestrictDefaultSGCustomResourceProviderHandlerDC833E5E" + } + ], + "/aws-cdk-ec2-lt-metadata-1/sg1/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "sg15CEFF4E3" + } + ], "/aws-cdk-ec2-lt-metadata-1/LT/Resource": [ { "type": "aws:cdk:logicalId", "data": "LTC4631592" } ], + "/aws-cdk-ec2-lt-metadata-1/sg2/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "sg2860DD91F" + } + ], "/aws-cdk-ec2-lt-metadata-1/LTWithMachineImage/Resource": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/tree.json index 96da980720391..4ce5f02eb8095 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.js.snapshot/tree.json @@ -8,6 +8,125 @@ "id": "aws-cdk-ec2-lt-metadata-1", "path": "aws-cdk-ec2-lt-metadata-1", "children": { + "MyVpc": { + "id": "MyVpc", + "path": "aws-cdk-ec2-lt-metadata-1/MyVpc", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-ec2-lt-metadata-1/MyVpc/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.0.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default", + "tags": [ + { + "key": "Name", + "value": "MyVpc" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.26" + } + }, + "RestrictDefaultSecurityGroupCustomResource": { + "id": "RestrictDefaultSecurityGroupCustomResource", + "path": "aws-cdk-ec2-lt-metadata-1/MyVpc/RestrictDefaultSecurityGroupCustomResource", + "children": { + "Default": { + "id": "Default", + "path": "aws-cdk-ec2-lt-metadata-1/MyVpc/RestrictDefaultSecurityGroupCustomResource/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.26" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.26" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.26" + } + }, + "Custom::VpcRestrictDefaultSGCustomResourceProvider": { + "id": "Custom::VpcRestrictDefaultSGCustomResourceProvider", + "path": "aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider", + "children": { + "Staging": { + "id": "Staging", + "path": "aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider/Staging", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.26" + } + }, + "Role": { + "id": "Role", + "path": "aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider/Role", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.26" + } + }, + "Handler": { + "id": "Handler", + "path": "aws-cdk-ec2-lt-metadata-1/Custom::VpcRestrictDefaultSGCustomResourceProvider/Handler", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.26" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.26" + } + }, + "sg1": { + "id": "sg1", + "path": "aws-cdk-ec2-lt-metadata-1/sg1", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-ec2-lt-metadata-1/sg1/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "aws-cdk-ec2-lt-metadata-1/sg1", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.26" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.26" + } + }, "LT": { "id": "LT", "path": "aws-cdk-ec2-lt-metadata-1/LT", @@ -19,6 +138,20 @@ "aws:cdk:cloudformation:type": "AWS::EC2::LaunchTemplate", "aws:cdk:cloudformation:props": { "launchTemplateData": { + "securityGroupIds": [ + { + "Fn::GetAtt": [ + "sg15CEFF4E3", + "GroupId" + ] + }, + { + "Fn::GetAtt": [ + "sg2860DD91F", + "GroupId" + ] + } + ], "tagSpecifications": [ { "resourceType": "instance", @@ -61,14 +194,48 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnLaunchTemplate", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.26" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.LaunchTemplate", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.26" + } + }, + "sg2": { + "id": "sg2", + "path": "aws-cdk-ec2-lt-metadata-1/sg2", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-ec2-lt-metadata-1/sg2/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "aws-cdk-ec2-lt-metadata-1/sg2", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "MyVpcF9F0CA6F" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.26" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.26" } }, "LTWithMachineImage": { @@ -123,52 +290,52 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.CfnLaunchTemplate", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.26" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-ec2.LaunchTemplate", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.26" } }, "SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter": { "id": "SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter", "path": "aws-cdk-ec2-lt-metadata-1/SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter", "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.26" } }, "SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118": { "id": "SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118", "path": "aws-cdk-ec2-lt-metadata-1/SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118", "constructInfo": { - "fqn": "@aws-cdk/core.Resource", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.26" } }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "aws-cdk-ec2-lt-metadata-1/BootstrapVersion", "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.26" } }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", "path": "aws-cdk-ec2-lt-metadata-1/CheckBootstrapVersion", "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.26" } } }, "constructInfo": { - "fqn": "@aws-cdk/core.Stack", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.26" } }, "LambdaTest": { @@ -184,7 +351,7 @@ "path": "LambdaTest/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.189" + "version": "10.2.26" } }, "DeployAssert": { @@ -195,33 +362,33 @@ "id": "BootstrapVersion", "path": "LambdaTest/DefaultTest/DeployAssert/BootstrapVersion", "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.26" } }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", "path": "LambdaTest/DefaultTest/DeployAssert/CheckBootstrapVersion", "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.26" } } }, "constructInfo": { - "fqn": "@aws-cdk/core.Stack", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.26" } } }, "constructInfo": { - "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/integ-tests.IntegTest", + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", "version": "0.0.0" } }, @@ -230,13 +397,13 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.189" + "version": "10.2.26" } } }, "constructInfo": { - "fqn": "@aws-cdk/core.App", - "version": "0.0.0" + "fqn": "constructs.Construct", + "version": "10.2.26" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.ts index bef5bbb1ef323..51cae5905033a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ec2/test/integ.launch-template.ts @@ -6,14 +6,30 @@ const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-ec2-lt-metadata-1'); -new ec2.LaunchTemplate(stack, 'LT', { +const vpc = new ec2.Vpc(stack, 'MyVpc', { + vpcName: 'MyVpc', + subnetConfiguration: [], +}); + +const sg1 = new ec2.SecurityGroup(stack, 'sg1', { + vpc: vpc, +}); + +const lt = new ec2.LaunchTemplate(stack, 'LT', { httpEndpoint: true, httpProtocolIpv6: true, httpPutResponseHopLimit: 2, httpTokens: ec2.LaunchTemplateHttpTokens.REQUIRED, instanceMetadataTags: true, + securityGroup: sg1, }); +const sg2 = new ec2.SecurityGroup(stack, 'sg2', { + vpc: vpc, +}); + +lt.addSecurityGroup(sg2); + new ec2.LaunchTemplate(stack, 'LTWithMachineImage', { machineImage: ec2.MachineImage.latestAmazonLinux({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2, diff --git a/packages/aws-cdk-lib/aws-ec2/README.md b/packages/aws-cdk-lib/aws-ec2/README.md index 4dde61bfa3fa8..c99503bdfa552 100644 --- a/packages/aws-cdk-lib/aws-ec2/README.md +++ b/packages/aws-cdk-lib/aws-ec2/README.md @@ -1868,6 +1868,24 @@ new ec2.LaunchTemplate(this, 'LaunchTemplate', { }); ``` +And the following demonstrates how to add one or more security groups to launch template. + +```ts +const sg1 = new ec2.SecurityGroup(stack, 'sg1', { + vpc: vpc, +}); +const sg2 = new ec2.SecurityGroup(stack, 'sg2', { + vpc: vpc, +}); + +const launchTemplate = new ec2.LaunchTemplate(stack, 'LaunchTemplate', { + machineImage: ec2.MachineImage.latestAmazonLinux2022(), + securityGroup: sg1, +}); + +launchTemplate.addSecurityGroup(sg2); +``` + ## Detailed Monitoring The following demonstrates how to enable [Detailed Monitoring](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-cloudwatch-new.html) for an EC2 instance. Keep in mind that Detailed Monitoring results in [additional charges](http://aws.amazon.com/cloudwatch/pricing/). @@ -1940,4 +1958,4 @@ new ec2.PrefixList(this, 'PrefixList', { }); ``` -For more information see [Work with customer-managed prefix lists](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-managed-prefix-lists.html) \ No newline at end of file +For more information see [Work with customer-managed prefix lists](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-managed-prefix-lists.html) diff --git a/packages/aws-cdk-lib/aws-ec2/lib/launch-template.ts b/packages/aws-cdk-lib/aws-ec2/lib/launch-template.ts index 24d0be46106e9..43b78e0850bc2 100644 --- a/packages/aws-cdk-lib/aws-ec2/lib/launch-template.ts +++ b/packages/aws-cdk-lib/aws-ec2/lib/launch-template.ts @@ -786,6 +786,18 @@ export class LaunchTemplate extends Resource implements ILaunchTemplate, iam.IGr } } + /** + * Add the security group to the instance. + * + * @param securityGroup: The security group to add + */ + public addSecurityGroup(securityGroup: ISecurityGroup): void { + if (!this._connections) { + throw new Error('LaunchTemplate can only be added a securityGroup if another securityGroup is initialized in the constructor.'); + } + this._connections.addSecurityGroup(securityGroup); + } + /** * Allows specifying security group connections for the instance. * From 9c8f549c1575f3e0db7ec8809a9ef8700a0c3b9e Mon Sep 17 00:00:00 2001 From: Marcel Laverdet Date: Thu, 15 Jun 2023 03:49:41 -0500 Subject: [PATCH 3/5] chore: hide diffs of mangled unicode strings (#25912) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I am reopening this from https://github.com/aws/aws-cdk/pull/25525 and following up on my comments here: https://github.com/aws/aws-cdk/pull/24557#issuecomment-1492965718 https://github.com/aws/aws-cdk/pull/24557#issuecomment-1500747296 https://github.com/aws/aws-cdk/pull/25008#issuecomment-1501441939 https://github.com/aws/aws-cdk/pull/25008#issuecomment-1518734007 https://github.com/aws/aws-cdk/pull/25008#issuecomment-1526860767 https://github.com/aws/aws-cdk/pull/25008#issuecomment-1530705196 https://github.com/aws/aws-cdk/pull/25008#issuecomment-1532033381 https://github.com/aws/aws-cdk/pull/25008#issuecomment-1541047453 https://github.com/aws/aws-cdk/pull/25525#issuecomment-1553618649 https://github.com/aws/aws-cdk/pull/25525#issuecomment-1572524950 🫠 https://github.com/aws/aws-cdk/pull/25525#discussion_r1202548942 🫠 --- Fixes #25309 Fixes #22203 Fixes #20212 Fixes #13634 Fixes #10523 Fixes #10219 See also: aws-cloudformation/cloudformation-coverage-roadmap#1220 See also: aws-cloudformation/cloudformation-coverage-roadmap#814 --- πŸ‘» I have retitled this PR as a `chore` instead of a `fix` because @aws-cdk-automation keeps closing my PRs as abandoned even though they are clearly not abandoned. > This PR has been deemed to be abandoned, and will be automatically closed. Please create a new PR for these changes if you think this decision has been made in error. --- @otaviomacedo @rix0rrr @TheRealAmazonKendra - I'm happy to adjust the approach, add more tests, or do what else needs to be done. I'm not getting any feedback from the team so I'm not sure how to proceed. The diff noise with non-ASCII information in cdk diff makes it difficult to find meaningful changes to our stacks. πŸ—ΏπŸ—žοΈπŸ“¬ **Crucially, this change only affects the CLI output and therefore an integration test isn't possible.** --- CloudFormation's `GetStackTemplate` irrecoverably mangles any character not in the 7-bit ASCII range. This causes noisy output from `cdk diff` when a template contains non-English languages or emoji. We can detect this case and consider these strings equal. *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* Many AWS services accept non-ASCII input, eg many "description" fields. CloudFormation will correctly dispatch these templates but when invoking `GetStackTemplate` the result is mangled. This causes annoying noise in the output of `cdk diff`: ``` Resources [~] AWS::Lambda::Function Lambda/Resource └─ [~] Description β”œβ”€ [-] ????? └─ [+] πŸ€¦πŸ»β€β™‚οΈ ``` This change modifies the diff algorithm to consider the string equal if the lvalue is a mangled version of the rvalue. Of course this runs the risk of hiding changesets which modify only a single non-ASCII character to another non-ASCII character, but these fields already tend to be informative in nature. --- .../cloudformation-diff/lib/diff/util.ts | 12 ++++++++++++ .../@aws-cdk/cloudformation-diff/lib/index.ts | 2 +- .../cloudformation-diff/test/util-test.ts | 10 ++++++++++ packages/aws-cdk/lib/cli.ts | 2 +- packages/aws-cdk/lib/diff.ts | 16 +++++++++++++++- 5 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 packages/@aws-cdk/cloudformation-diff/test/util-test.ts diff --git a/packages/@aws-cdk/cloudformation-diff/lib/diff/util.ts b/packages/@aws-cdk/cloudformation-diff/lib/diff/util.ts index 1cbd4b1a111d7..8b076dd36221e 100644 --- a/packages/@aws-cdk/cloudformation-diff/lib/diff/util.ts +++ b/packages/@aws-cdk/cloudformation-diff/lib/diff/util.ts @@ -134,6 +134,18 @@ export function unionOf(lv: string[] | Set, rv: string[] | Set): return new Array(...result); } +/** + * GetStackTemplate flattens any codepoint greater than "\u7f" to "?". This is + * true even for codepoints in the supplemental planes which are represented + * in JS as surrogate pairs, all the way up to "\u{10ffff}". + * + * This function implements the same mangling in order to provide diagnostic + * information in `cdk diff`. + */ +export function mangleLikeCloudFormation(payload: string) { + return payload.replace(/[\u{80}-\u{10ffff}]/gu, '?'); +} + /** * A parseFloat implementation that does the right thing for * strings like '0.0.0' diff --git a/packages/@aws-cdk/cloudformation-diff/lib/index.ts b/packages/@aws-cdk/cloudformation-diff/lib/index.ts index 34a07c7559fb7..9d42f22b882b9 100644 --- a/packages/@aws-cdk/cloudformation-diff/lib/index.ts +++ b/packages/@aws-cdk/cloudformation-diff/lib/index.ts @@ -1,4 +1,4 @@ export * from './diff-template'; export * from './format'; export * from './format-table'; -export { deepEqual } from './diff/util'; +export { deepEqual, mangleLikeCloudFormation } from './diff/util'; diff --git a/packages/@aws-cdk/cloudformation-diff/test/util-test.ts b/packages/@aws-cdk/cloudformation-diff/test/util-test.ts new file mode 100644 index 0000000000000..b95f44f48c62f --- /dev/null +++ b/packages/@aws-cdk/cloudformation-diff/test/util-test.ts @@ -0,0 +1,10 @@ +import { mangleLikeCloudFormation } from '../lib/diff/util'; + +test('mangled strings', () => { + expect(mangleLikeCloudFormation('foo')).toEqual('foo'); + expect(mangleLikeCloudFormation('ζ–‡ε­—εŒ–γ‘')).toEqual('????'); + expect(mangleLikeCloudFormation('πŸ€¦πŸ»β€β™‚οΈ')).toEqual('?????'); + expect(mangleLikeCloudFormation('\u{10ffff}')).toEqual('?'); + expect(mangleLikeCloudFormation('\u007f')).toEqual('\u007f'); + expect(mangleLikeCloudFormation('\u0080')).toEqual('?'); +}); diff --git a/packages/aws-cdk/lib/cli.ts b/packages/aws-cdk/lib/cli.ts index f24f42231beb5..85ac53137a4b7 100644 --- a/packages/aws-cdk/lib/cli.ts +++ b/packages/aws-cdk/lib/cli.ts @@ -257,7 +257,7 @@ async function parseCommandLineArguments(args: string[]) { .option('exclusively', { type: 'boolean', alias: 'e', desc: 'Only diff requested stacks, don\'t include dependencies' }) .option('context-lines', { type: 'number', desc: 'Number of context lines to include in arbitrary JSON diff rendering', default: 3, requiresArg: true }) .option('template', { type: 'string', desc: 'The path to the CloudFormation template to compare with', requiresArg: true }) - .option('strict', { type: 'boolean', desc: 'Do not filter out AWS::CDK::Metadata resources', default: false }) + .option('strict', { type: 'boolean', desc: 'Do not filter out AWS::CDK::Metadata resources or mangled non-ASCII characters', default: false }) .option('security-only', { type: 'boolean', desc: 'Only diff for broadened security changes', default: false }) .option('fail', { type: 'boolean', desc: 'Fail with exit code 1 in case of diff' }) .option('processed', { type: 'boolean', desc: 'Whether to compare against the template with Transforms already processed', default: false })) diff --git a/packages/aws-cdk/lib/diff.ts b/packages/aws-cdk/lib/diff.ts index 8566083efa48a..08a67e7567c8c 100644 --- a/packages/aws-cdk/lib/diff.ts +++ b/packages/aws-cdk/lib/diff.ts @@ -21,7 +21,18 @@ export function printStackDiff( context: number, stream?: cfnDiff.FormatStream): number { - const diff = cfnDiff.diffTemplate(oldTemplate, newTemplate.template); + let diff = cfnDiff.diffTemplate(oldTemplate, newTemplate.template); + + // detect and filter out mangled characters from the diff + let filteredChangesCount = 0; + if (diff.differenceCount && !strict) { + const mangledNewTemplate = JSON.parse(cfnDiff.mangleLikeCloudFormation(JSON.stringify(newTemplate.template))); + const mangledDiff = cfnDiff.diffTemplate(oldTemplate, mangledNewTemplate); + filteredChangesCount = Math.max(0, diff.differenceCount - mangledDiff.differenceCount); + if (filteredChangesCount > 0) { + diff = mangledDiff; + } + } // filter out 'AWS::CDK::Metadata' resources from the template if (diff.resources && !strict) { @@ -41,6 +52,9 @@ export function printStackDiff( } else { print(chalk.green('There were no differences')); } + if (filteredChangesCount > 0) { + print(chalk.yellow(`Omitted ${filteredChangesCount} changes because they are likely mangled non-ASCII characters. Use --strict to print them.`)); + } return diff.differenceCount; } From c1211805b918f1b37168f88280d37190c4eb0f1d Mon Sep 17 00:00:00 2001 From: Kaizen Conroy <36202692+kaizencc@users.noreply.github.com> Date: Thu, 15 Jun 2023 05:35:03 -0400 Subject: [PATCH 4/5] fix(ecr): autoDeleteImages fails on multiple repositories (#25964) When setting `autoDeleteImages: true` for multiple repositories in the same stack, permissions to do the actual deleting only get added to the first one. This is because the policy statement is added inside of the `getOrCreateProvider` method, and that method ensures that the provider is only created once. Instead, this adds the policy statement on the provider itself, regardless of whether it was created or referenced. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-cdk-lib/aws-ecr/lib/repository.ts | 37 +++++++----- .../aws-ecr/test/repository.test.ts | 60 +++++++++++++++++++ 2 files changed, 83 insertions(+), 14 deletions(-) diff --git a/packages/aws-cdk-lib/aws-ecr/lib/repository.ts b/packages/aws-cdk-lib/aws-ecr/lib/repository.ts index 9338a9c73e781..1cd39b8fe84bd 100644 --- a/packages/aws-cdk-lib/aws-ecr/lib/repository.ts +++ b/packages/aws-cdk-lib/aws-ecr/lib/repository.ts @@ -24,6 +24,7 @@ import { const AUTO_DELETE_IMAGES_RESOURCE_TYPE = 'Custom::ECRAutoDeleteImages'; const AUTO_DELETE_IMAGES_TAG = 'aws-cdk:auto-delete-images'; +const REPO_ARN_SYMBOL = Symbol.for('@aws-cdk/aws-ecr.RepoArns'); /** * Represents an ECR repository. @@ -857,26 +858,34 @@ export class Repository extends RepositoryBase { } private enableAutoDeleteImages() { - // Use a iam policy to allow the custom resource to list & delete - // images in the repository and the ability to get all repositories to find the arn needed on delete. + const firstTime = Stack.of(this).node.tryFindChild(`${AUTO_DELETE_IMAGES_RESOURCE_TYPE}CustomResourceProvider`) === undefined; const provider = CustomResourceProvider.getOrCreateProvider(this, AUTO_DELETE_IMAGES_RESOURCE_TYPE, { codeDirectory: path.join(__dirname, 'auto-delete-images-handler'), runtime: builtInCustomResourceProviderNodeRuntime(this), description: `Lambda function for auto-deleting images in ${this.repositoryName} repository.`, - policyStatements: [ - { - Effect: 'Allow', - Action: [ - 'ecr:BatchDeleteImage', - 'ecr:DescribeRepositories', - 'ecr:ListImages', - 'ecr:ListTagsForResource', - ], - Resource: [this._resource.attrArn], - }, - ], }); + if (firstTime) { + const repoArns = [this._resource.attrArn]; + (provider as any)[REPO_ARN_SYMBOL] = repoArns; + + // Use a iam policy to allow the custom resource to list & delete + // images in the repository and the ability to get all repositories to find the arn needed on delete. + // We lazily produce a list of repositories associated with this custom resource provider. + provider.addToRolePolicy({ + Effect: 'Allow', + Action: [ + 'ecr:BatchDeleteImage', + 'ecr:DescribeRepositories', + 'ecr:ListImages', + 'ecr:ListTagsForResource', + ], + Resource: Lazy.list({ produce: () => repoArns }), + }); + } else { + (provider as any)[REPO_ARN_SYMBOL].push(this._resource.attrArn); + } + const customResource = new CustomResource(this, 'AutoDeleteImagesCustomResource', { resourceType: AUTO_DELETE_IMAGES_RESOURCE_TYPE, serviceToken: provider.serviceToken, diff --git a/packages/aws-cdk-lib/aws-ecr/test/repository.test.ts b/packages/aws-cdk-lib/aws-ecr/test/repository.test.ts index f192a76c06ef1..6b58bbb3e2d88 100644 --- a/packages/aws-cdk-lib/aws-ecr/test/repository.test.ts +++ b/packages/aws-cdk-lib/aws-ecr/test/repository.test.ts @@ -976,4 +976,64 @@ describe('repository', () => { }); }); }); + + describe('when auto delete images is set to true', () => { + test('permissions are correctly for multiple ecr repos', () => { + const stack = new cdk.Stack(); + new ecr.Repository(stack, 'Repo1', { + autoDeleteImages: true, + removalPolicy: cdk.RemovalPolicy.DESTROY, + }); + new ecr.Repository(stack, 'Repo2', { + autoDeleteImages: true, + removalPolicy: cdk.RemovalPolicy.DESTROY, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { + Policies: [ + { + PolicyName: 'Inline', + PolicyDocument: { + Version: '2012-10-17', + Statement: [ + { + Effect: 'Allow', + Action: [ + 'ecr:BatchDeleteImage', + 'ecr:DescribeRepositories', + 'ecr:ListImages', + 'ecr:ListTagsForResource', + ], + Resource: [ + { + 'Fn::GetAtt': [ + 'Repo1DBD717D9', + 'Arn', + ], + }, + { + 'Fn::GetAtt': [ + 'Repo2730A8200', + 'Arn', + ], + }, + ], + }, + ], + }, + }, + ], + }); + }); + + test('synth fails when removal policy is not DESTROY', () => { + const stack = new cdk.Stack(); + expect(() => { + new ecr.Repository(stack, 'Repo', { + autoDeleteImages: true, + removalPolicy: cdk.RemovalPolicy.RETAIN, + }); + }).toThrowError('Cannot use \'autoDeleteImages\' property on a repository without setting removal policy to \'DESTROY\'.'); + }); + }); }); From 97d2fab5dc902bc0e66e081fb90c8f115ca1b1a9 Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Thu, 15 Jun 2023 06:01:32 -0400 Subject: [PATCH 5/5] docs(cfnspec): update CloudFormation documentation (#25986) --- packages/@aws-cdk/cfnspec/spec-source/cfn-docs/cfn-docs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/cfnspec/spec-source/cfn-docs/cfn-docs.json b/packages/@aws-cdk/cfnspec/spec-source/cfn-docs/cfn-docs.json index fa8dbb6071c7f..74d1cf90305de 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/cfn-docs/cfn-docs.json +++ b/packages/@aws-cdk/cfnspec/spec-source/cfn-docs/cfn-docs.json @@ -15236,7 +15236,7 @@ "IamInstanceProfile": "The name of an IAM instance profile. To create a new IAM instance profile, use the [AWS::IAM::InstanceProfile](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-instanceprofile.html) resource.", "ImageId": "The ID of the AMI. An AMI ID is required to launch an instance and must be specified here or in a launch template.", "InstanceInitiatedShutdownBehavior": "Indicates whether an instance stops or terminates when you initiate shutdown from the instance (using the operating system command for system shutdown).\n\nDefault: `stop`", - "InstanceType": "The instance type. For more information, see [Instance types](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html) in the *Amazon EC2 User Guide* .\n\nDefault: `m1.small`", + "InstanceType": "The instance type. For more information, see [Instance types](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html) in the *Amazon EC2 User Guide* .\n\nWhen you change your EBS-backed instance type, instance restart or replacement behavior depends on the instance type compatibility between the old and new types. An instance that's backed by an instance store volume is always replaced. For more information, see [Change the instance type](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-resize.html) in the *Amazon EC2 User Guide* .\n\nDefault: `m1.small`", "Ipv6AddressCount": "The number of IPv6 addresses to associate with the primary network interface. Amazon EC2 chooses the IPv6 addresses from the range of your subnet. You cannot specify this option and the option to assign specific IPv6 addresses in the same request. You can specify this option if you've specified a minimum number of instances to launch.\n\nYou cannot specify this option and the network interfaces option in the same request.", "Ipv6Addresses": "The IPv6 addresses from the range of the subnet to associate with the primary network interface. You cannot specify this option and the option to assign a number of IPv6 addresses in the same request. You cannot specify this option if you've specified a minimum number of instances to launch.\n\nYou cannot specify this option and the network interfaces option in the same request.", "KernelId": "The ID of the kernel.\n\n> We recommend that you use PV-GRUB instead of kernels and RAM disks. For more information, see [PV-GRUB](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedkernels.html) in the *Amazon EC2 User Guide* .",