From b8f02eca3445553df591721dcd0733fc0deb028b Mon Sep 17 00:00:00 2001 From: Christopher Rybicki Date: Wed, 22 Sep 2021 14:35:46 -0700 Subject: [PATCH 001/148] chore: add Chriscbr to mergify --- .mergify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mergify.yml b/.mergify.yml index 97f3ce42a91be..993a25aee5269 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -6,7 +6,7 @@ pull_request_rules: label: add: [ contribution/core ] conditions: - - author~=^(eladb|RomainMuller|garnaat|nija-at|skinny85|rix0rrr|NGL321|Jerry-AWS|MrArnoldPalmer|NetaNir|iliapolo|njlynch|ericzbeard|ccfife|fulghum|pkandasamy91|SoManyHs|uttarasridhar|otaviomacedo|BenChaimberg|madeline-k|BryanPan342|kaizen3031593|comcalvi)$ + - author~=^(eladb|RomainMuller|garnaat|nija-at|skinny85|rix0rrr|NGL321|Jerry-AWS|MrArnoldPalmer|NetaNir|iliapolo|njlynch|ericzbeard|ccfife|fulghum|pkandasamy91|SoManyHs|uttarasridhar|otaviomacedo|BenChaimberg|madeline-k|BryanPan342|kaizen3031593|comcalvi|Chriscbr)$ - -label~="contribution/core" - name: automatic merge actions: From 7a63b92a37ae2f142af51e6e73ca5896d59a4591 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 20 Oct 2021 13:48:58 +0200 Subject: [PATCH 002/148] chore(assertions): remove `rosetta:extract` from build command (#17072) This form of executing Rosetta is not mocked by the jsii integ tests (which try executing a CDK build using a new version of the jsii tools). The jsii integ tests rely on passing environment variables `$CDK_BUILD_JSII`, `$PACMAK` and `$ROSETTA` (instead of replacing symlinks in the Node module farm). This leads to the generation of `.jsii.tabl.json` during build using the NPM-installed version of `jsii-rosetta`, which subsequently interferes with the run of `$PACMAK` which *is* the new version (since Rosetta tablets are supposed to be short-lived, there is no backwards compatibility guarantee between different versions). There will be a supported mechanism to achieve what this single post-build command is trying to achieve, so remove it. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* (cherry picked from commit ac54842ba15991b2359181a27d2530158622d9f9) --- packages/@aws-cdk/assertions/package.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/@aws-cdk/assertions/package.json b/packages/@aws-cdk/assertions/package.json index e87d1c9526302..ac9a08ae297d6 100644 --- a/packages/@aws-cdk/assertions/package.json +++ b/packages/@aws-cdk/assertions/package.json @@ -55,11 +55,6 @@ } } }, - "cdk-build": { - "post": [ - "yarn rosetta:extract" - ] - }, "author": { "name": "Amazon Web Services", "url": "https://aws.amazon.com", From 74066ca5c19509b60d95fc35ac7f732f44c6d8ae Mon Sep 17 00:00:00 2001 From: Otavio Macedo Date: Thu, 21 Oct 2021 10:15:39 +0100 Subject: [PATCH 003/148] chore: bumped jsii dependencies to 1.40.0 (#17087) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- package.json | 8 +- packages/aws-cdk/package.json | 2 +- packages/awslint/package.json | 4 +- packages/decdk/package.json | 4 +- tools/@aws-cdk/cdk-build-tools/package.json | 6 +- yarn.lock | 103 +++++++++++--------- 6 files changed, 68 insertions(+), 59 deletions(-) diff --git a/package.json b/package.json index 97612d72cea6f..7db1f7c20c0ad 100644 --- a/package.json +++ b/package.json @@ -20,10 +20,10 @@ "fs-extra": "^9.1.0", "graceful-fs": "^4.2.8", "jest-junit": "^12.3.0", - "jsii-diff": "^1.39.0", - "jsii-pacmak": "^1.39.0", - "jsii-reflect": "^1.39.0", - "jsii-rosetta": "^1.39.0", + "jsii-diff": "^1.40.0", + "jsii-pacmak": "^1.40.0", + "jsii-reflect": "^1.40.0", + "jsii-rosetta": "^1.40.0", "lerna": "^4.0.0", "patch-package": "^6.4.7", "standard-version": "^9.3.1", diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 1e6f3b7bef7fe..4492f92549b45 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -71,7 +71,7 @@ "@aws-cdk/cloudformation-diff": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/region-info": "0.0.0", - "@jsii/check-node": "1.39.0", + "@jsii/check-node": "1.40.0", "archiver": "^5.3.0", "aws-sdk": "^2.979.0", "camelcase": "^6.2.0", diff --git a/packages/awslint/package.json b/packages/awslint/package.json index f035267fc9292..1bae6a09ba6cb 100644 --- a/packages/awslint/package.json +++ b/packages/awslint/package.json @@ -18,11 +18,11 @@ "awslint": "bin/awslint" }, "dependencies": { - "@jsii/spec": "^1.39.0", + "@jsii/spec": "^1.40.0", "camelcase": "^6.2.0", "colors": "^1.4.0", "fs-extra": "^9.1.0", - "jsii-reflect": "^1.39.0", + "jsii-reflect": "^1.40.0", "yargs": "^16.2.0" }, "devDependencies": { diff --git a/packages/decdk/package.json b/packages/decdk/package.json index 6ee38d4e401a4..8a87b4a7001f8 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -243,7 +243,7 @@ "@aws-cdk/region-info": "0.0.0", "constructs": "^3.3.69", "fs-extra": "^9.1.0", - "jsii-reflect": "^1.39.0", + "jsii-reflect": "^1.40.0", "jsonschema": "^1.4.0", "yaml": "1.10.2", "yargs": "^16.2.0" @@ -254,7 +254,7 @@ "@types/yaml": "1.9.7", "@types/yargs": "^15.0.14", "jest": "^26.6.3", - "jsii": "^1.39.0" + "jsii": "^1.40.0" }, "keywords": [ "aws", diff --git a/tools/@aws-cdk/cdk-build-tools/package.json b/tools/@aws-cdk/cdk-build-tools/package.json index d2b03befabebb..84005357a2458 100644 --- a/tools/@aws-cdk/cdk-build-tools/package.json +++ b/tools/@aws-cdk/cdk-build-tools/package.json @@ -55,9 +55,9 @@ "fs-extra": "^9.1.0", "jest": "^26.6.3", "jest-junit": "^11.1.0", - "jsii": "^1.39.0", - "jsii-pacmak": "^1.39.0", - "jsii-reflect": "^1.39.0", + "jsii": "^1.40.0", + "jsii-pacmak": "^1.40.0", + "jsii-reflect": "^1.40.0", "markdownlint-cli": "^0.29.0", "nyc": "^15.1.0", "semver": "^7.3.5", diff --git a/yarn.lock b/yarn.lock index 3fc7477ad872b..442e61841ae13 100644 --- a/yarn.lock +++ b/yarn.lock @@ -576,18 +576,18 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@jsii/check-node@1.39.0": - version "1.39.0" - resolved "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.39.0.tgz#31a22f6270c790b5f2bb0f7d2950511e6d7c0c9e" - integrity sha512-tqx5o0Zw6WrVKmB9S1X0E8AajfXjWu9yoOUtUdYVCR6NAdi8mY/NQ3uYJ8II0AF1MtC0PdASOjb/6i3h02komw== +"@jsii/check-node@1.40.0": + version "1.40.0" + resolved "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.40.0.tgz#49882a61ad1b3a37cd35c35fa1a2301955f1c058" + integrity sha512-rk0hFXxFQR8rDGUfsZT9ua6OufOpnLQWsNFyFU86AvpoKQ0ciw2KlGdWs7OYFnzPq8sQGhSS+iuBrUboaHW3jg== dependencies: chalk "^4.1.2" semver "^7.3.5" -"@jsii/spec@^1.39.0": - version "1.39.0" - resolved "https://registry.npmjs.org/@jsii/spec/-/spec-1.39.0.tgz#17b2d55f8261da3ed4a670e9a4c5dfa18a7e050a" - integrity sha512-NbCmAYOB938uyWHwXj6fhdeIzznhHbxLmvl4Jtwe08Nrz5Gs4n79snV29XWIQulDMa4HYkNh1yqhBXOHkd+GAg== +"@jsii/spec@^1.40.0": + version "1.40.0" + resolved "https://registry.npmjs.org/@jsii/spec/-/spec-1.40.0.tgz#027dd2a9c2c0b49e5974ad6445728dde91569fe3" + integrity sha512-SJ9Kwz0C53bomYWb5PlESt6v8JmfgqqFjc1annNK+foHxcaUzs3trhKbBXgxhcoApE2pMnUIBj3DG9gLNmKdWw== dependencies: jsonschema "^1.4.0" @@ -2845,6 +2845,15 @@ codemaker@^1.39.0: decamelize "^5.0.1" fs-extra "^9.1.0" +codemaker@^1.40.0: + version "1.40.0" + resolved "https://registry.npmjs.org/codemaker/-/codemaker-1.40.0.tgz#80ed75a433fb08976c602b9080dc7fffbb13dbb9" + integrity sha512-X0dMlXILO5r9/YhNAbiLl9kNIfhATfGS8nAT7xC09zREipANnCEbjZuF8jtFGzrD942/k5QNROmqRtqRaZJ1QQ== + dependencies: + camelcase "^6.2.0" + decamelize "^5.0.1" + fs-extra "^9.1.0" + collect-v8-coverage@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" @@ -6011,70 +6020,70 @@ jsesc@^2.5.1: resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== -jsii-diff@^1.39.0: - version "1.39.0" - resolved "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.39.0.tgz#e6dc9ffc5689bfcfa2bcd9532829054003547470" - integrity sha512-O49YB3IElNIyP7zbBXLTYmLPwxxJY4Zs4rcZ4zpO73Yv373edT+TmoKkZV05DhKNcU79nFPB+axr6sKP6ElzFw== +jsii-diff@^1.40.0: + version "1.40.0" + resolved "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.40.0.tgz#97668273bc6c7f8ea6c6c27ebd8d70d433e1208d" + integrity sha512-Q0ctTmPE3wZ03CP++MxjPMBV3ynonDHq1gsd5mFUk9DW+cTyKb78KUkyjhgQnuiehXLRDQtoTlWJkH9C5xhEnQ== dependencies: - "@jsii/check-node" "1.39.0" - "@jsii/spec" "^1.39.0" + "@jsii/check-node" "1.40.0" + "@jsii/spec" "^1.40.0" fs-extra "^9.1.0" - jsii-reflect "^1.39.0" + jsii-reflect "^1.40.0" log4js "^6.3.0" typescript "~3.9.10" yargs "^16.2.0" -jsii-pacmak@^1.39.0: - version "1.39.0" - resolved "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.39.0.tgz#b5c66eb32a62390e02c0273f6edca3871600cc74" - integrity sha512-+B2Z62v/MQ8fQcvd1nhKUWv+ZoNEArwa6OiTSvAuMsRoZpZ7Uvabscu71Uu3zq1XzJ6WQStw90ENHkw40l/o7w== +jsii-pacmak@^1.40.0: + version "1.40.0" + resolved "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.40.0.tgz#5c0ecd5ff9c0917931bbe66773402dfe5517fbec" + integrity sha512-8IyvvWiD2eUpVhw0WXrYJILz+NSeNEwcWfQB+fUmn2gL8q27hlPZhHE7BVlr8+rb+EJVVLeHmpAMgA/SF9g/vQ== dependencies: - "@jsii/check-node" "1.39.0" - "@jsii/spec" "^1.39.0" + "@jsii/check-node" "1.40.0" + "@jsii/spec" "^1.40.0" clone "^2.1.2" - codemaker "^1.39.0" + codemaker "^1.40.0" commonmark "^0.30.0" escape-string-regexp "^4.0.0" fs-extra "^9.1.0" - jsii-reflect "^1.39.0" - jsii-rosetta "^1.39.0" + jsii-reflect "^1.40.0" + jsii-rosetta "^1.40.0" semver "^7.3.5" spdx-license-list "^6.4.0" xmlbuilder "^15.1.1" yargs "^16.2.0" -jsii-reflect@^1.39.0: - version "1.39.0" - resolved "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.39.0.tgz#c35a395b7ec14c4e94aef8bf195a0ff329311534" - integrity sha512-HEMpGHJBDtUbhdnfYUH0M/NTrYxaXrb0B2DXglzN/EYzKJsdp4FAmDPzpKEwnGVK3ReJLZ68YRogTq3msyuQDQ== +jsii-reflect@^1.40.0: + version "1.40.0" + resolved "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.40.0.tgz#f8715f1506059d49294b32fe2c710753dd9545ba" + integrity sha512-/ccIjkRSfbHCl1MCfwWFaz2RjoAAiNH5teE95Qi11a4gbTu52WcOFIg3Y+8llzHmmLykr9jTDqBtgyzi9WI6dw== dependencies: - "@jsii/check-node" "1.39.0" - "@jsii/spec" "^1.39.0" + "@jsii/check-node" "1.40.0" + "@jsii/spec" "^1.40.0" colors "^1.4.0" fs-extra "^9.1.0" - oo-ascii-tree "^1.39.0" + oo-ascii-tree "^1.40.0" yargs "^16.2.0" -jsii-rosetta@^1.39.0: - version "1.39.0" - resolved "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.39.0.tgz#b4251bb9b0295d2a8c2c7a7d8b1d8d744f432305" - integrity sha512-Fx+kQ+IDEMILQvTESW9TMXLxzQa7h/nm4EKXuDKAeglr5RNhzvTvhsgJy+WshJoMsNcT9ImCV8gmvqAqdSBrWA== +jsii-rosetta@^1.40.0: + version "1.40.0" + resolved "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.40.0.tgz#eff34919ed9d4193ddb4a684f6108c82db3feb7c" + integrity sha512-Gb257CdUbHV8ZRFYflZy7F7alH5X49T+pX2133F7eaoMpRqc0V6jQsphaL4V+S/jK29XOfXtANmq55AvmwsWLQ== dependencies: - "@jsii/check-node" "1.39.0" - "@jsii/spec" "^1.39.0" + "@jsii/check-node" "1.40.0" + "@jsii/spec" "^1.40.0" "@xmldom/xmldom" "^0.7.5" commonmark "^0.30.0" fs-extra "^9.1.0" typescript "~3.9.10" yargs "^16.2.0" -jsii@^1.39.0: - version "1.39.0" - resolved "https://registry.npmjs.org/jsii/-/jsii-1.39.0.tgz#68554dd5c20ac4b7da118f748d5297e5f9e58384" - integrity sha512-2ReD7t6rGhT+c41xovFoAMc4XU5/O2VqGRh3Ud/wN+Nn1ISjZFQa4doQ1xtZLFb1065Vxyv5VCqWp80t6Xw2iA== +jsii@^1.40.0: + version "1.40.0" + resolved "https://registry.npmjs.org/jsii/-/jsii-1.40.0.tgz#cc04f2bad5ae9495513af921cfcaca99dc8753d3" + integrity sha512-QUPmQzq7c/FREvtfw9+eIU16LB45hxRPtdLO2Ci2ZX1df4E4+vegtfvvjUJ21diVo2hwVp4UCftKqrXZ/cXEFg== dependencies: - "@jsii/check-node" "1.39.0" - "@jsii/spec" "^1.39.0" + "@jsii/check-node" "1.40.0" + "@jsii/spec" "^1.40.0" case "^1.6.3" colors "^1.4.0" deep-equal "^2.0.5" @@ -7413,10 +7422,10 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -oo-ascii-tree@^1.39.0: - version "1.39.0" - resolved "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.39.0.tgz#7dfc1fc11e0c7c7bf34d0b91591db9bfe0406cbb" - integrity sha512-a0g33GTdCizt5jnQzY9j6cRNyx5xITmZb+b3C21+KNweaERltcR1BQO/tLUuuVEFRVWvZcUqrFDVa8f8nqOafA== +oo-ascii-tree@^1.40.0: + version "1.40.0" + resolved "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.40.0.tgz#69005b8f5f140ed23a81e90b3659750dc3a62522" + integrity sha512-nkiEc8TJZwGxPdEB1jRxHWyc/qBTPQSf70KhO+WjuiWzVfLVEWF/dksWRjm8e510YmPrBjfYCJOn+BVlOUojSQ== open@^7.4.2: version "7.4.2" From 76b9efadbf85cedd88838616f556f99c0dda4979 Mon Sep 17 00:00:00 2001 From: AWS CDK Team Date: Thu, 21 Oct 2021 12:40:24 +0000 Subject: [PATCH 004/148] chore(release): 1.129.0 --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ version.v1.json | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f254623e858c1..8c9fd17ee41a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.129.0](https://github.com/aws/aws-cdk/compare/v1.128.0...v1.129.0) (2021-10-21) + + +### Features + +* **aws-autoscaling:** add flag and aspect to require imdsv2 ([#16052](https://github.com/aws/aws-cdk/issues/16052)) ([ef7e20d](https://github.com/aws/aws-cdk/commit/ef7e20df08b4321f210bfc050afa42d7b4901931)) +* **codebuild:** add support for small ARM machine type ([#16635](https://github.com/aws/aws-cdk/issues/16635)) ([55fbc86](https://github.com/aws/aws-cdk/commit/55fbc866ef0195fdfc722206e4d69a1f4469cd40)), closes [#16633](https://github.com/aws/aws-cdk/issues/16633) +* **dynamodb:** add option to skip waiting for global replication to finish ([#16983](https://github.com/aws/aws-cdk/issues/16983)) ([254601f](https://github.com/aws/aws-cdk/commit/254601f477a4da309e81f5384140427f1b958bfd)), closes [#16611](https://github.com/aws/aws-cdk/issues/16611) +* **ec2:** add aspect to require imdsv2 ([#16051](https://github.com/aws/aws-cdk/issues/16051)) ([0947b21](https://github.com/aws/aws-cdk/commit/0947b21c1e3186042324820ec5ab433237246f58)) +* **eks:** configure serviceIpv4Cidr on the cluster ([#16957](https://github.com/aws/aws-cdk/issues/16957)) ([72102c7](https://github.com/aws/aws-cdk/commit/72102c750bfd6564cd51c1a5d8abc79b1ba1d3ce)), closes [/docs.aws.amazon.com/eks/latest/APIReference/API_KubernetesNetworkConfigRequest.html#AmazonEKS-Type-KubernetesNetworkConfigRequest-serviceIpv4](https://github.com/aws//docs.aws.amazon.com/eks/latest/APIReference/API_KubernetesNetworkConfigRequest.html/issues/AmazonEKS-Type-KubernetesNetworkConfigRequest-serviceIpv4) [#16541](https://github.com/aws/aws-cdk/issues/16541) +* **events:** Add DLQ support for SQS target ([#16916](https://github.com/aws/aws-cdk/issues/16916)) ([7fda903](https://github.com/aws/aws-cdk/commit/7fda90318e18b3a5d126b040e35a0146634d5f2d)), closes [#16417](https://github.com/aws/aws-cdk/issues/16417) +* **msk:** add Kafka version 2.8.1 ([#16881](https://github.com/aws/aws-cdk/issues/16881)) ([7db5c8c](https://github.com/aws/aws-cdk/commit/7db5c8cdafe7b9b22b6b40cb25ed8bd1946301f4)) +* **stepfunctions-tasks:** add `enableNetworkIsolation` property to `SageMakerCreateTrainingJobProps` ([#16792](https://github.com/aws/aws-cdk/issues/16792)) ([69ac520](https://github.com/aws/aws-cdk/commit/69ac520452b219bf242f2fbb4740f6b1b8b8790f)), closes [#16779](https://github.com/aws/aws-cdk/issues/16779) + + +### Bug Fixes + +* **apigatewayv2:** unable to retrieve domain url for default stage ([#16854](https://github.com/aws/aws-cdk/issues/16854)) ([c6db91e](https://github.com/aws/aws-cdk/commit/c6db91eee2cb658ce347c7ac6d6e3c95bc5977dc)), closes [#16638](https://github.com/aws/aws-cdk/issues/16638) +* **cfn-diff:** correctly handle Date strings in diff ([#16591](https://github.com/aws/aws-cdk/issues/16591)) ([86f2714](https://github.com/aws/aws-cdk/commit/86f2714613f06aaf2bcee27da2f66066c8e863d0)), closes [#16444](https://github.com/aws/aws-cdk/issues/16444) +* **ecs:** imported services don't have account & region set correctly ([#16997](https://github.com/aws/aws-cdk/issues/16997)) ([dc6f743](https://github.com/aws/aws-cdk/commit/dc6f7433f01b9bc2c8206fb03d72ab8404fe4f6a)), closes [#11199](https://github.com/aws/aws-cdk/issues/11199) [#11199](https://github.com/aws/aws-cdk/issues/11199) [#15944](https://github.com/aws/aws-cdk/issues/15944) +* **events:** PhysicalName.GENERATE_IF_NEEDED does not work for EventBus ([#17008](https://github.com/aws/aws-cdk/issues/17008)) ([707fa00](https://github.com/aws/aws-cdk/commit/707fa003a458039878a1ae5173b6665a84c1170b)), closes [#14337](https://github.com/aws/aws-cdk/issues/14337) +* **lambda:** docker image function fails when insightsVersion is specified ([#16781](https://github.com/aws/aws-cdk/issues/16781)) ([d0e15cc](https://github.com/aws/aws-cdk/commit/d0e15ccaca22c5e05b9186aa1a241e744d67c96a)), closes [#16642](https://github.com/aws/aws-cdk/issues/16642) +* **lambda-layer-node-proxy-agent:** Replace use of package.json with Dockerfile command `npm install [package]@[version]` ([#17078](https://github.com/aws/aws-cdk/issues/17078)) ([a129046](https://github.com/aws/aws-cdk/commit/a129046495a926561f94f5ce1f41c34b1df3afde)) +* **opensearch:** add validation to domainName property ([#17017](https://github.com/aws/aws-cdk/issues/17017)) ([3ec6832](https://github.com/aws/aws-cdk/commit/3ec683283e96159d588797bd46d33c82ff3076f1)), closes [#17016](https://github.com/aws/aws-cdk/issues/17016) +* **pipelines:** `additionalInputs` fails for deep directory ([#17074](https://github.com/aws/aws-cdk/issues/17074)) ([403d3ce](https://github.com/aws/aws-cdk/commit/403d3ce3bc0f4e30e9694e5c20743f0032009464)), closes [#16936](https://github.com/aws/aws-cdk/issues/16936) + ## [1.128.0](https://github.com/aws/aws-cdk/compare/v1.127.0...v1.128.0) (2021-10-14) diff --git a/version.v1.json b/version.v1.json index c24ba0065c588..cdb974a76d7f9 100644 --- a/version.v1.json +++ b/version.v1.json @@ -1,3 +1,3 @@ { - "version": "1.128.0" + "version": "1.129.0" } \ No newline at end of file From 3987808d16dbb37b6d5c16ad7a23d07bc6c2e9ec Mon Sep 17 00:00:00 2001 From: Otavio Macedo Date: Thu, 21 Oct 2021 13:45:13 +0100 Subject: [PATCH 005/148] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c9fd17ee41a3..511ed1a25dabd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ All notable changes to this project will be documented in this file. See [standa * **codebuild:** add support for small ARM machine type ([#16635](https://github.com/aws/aws-cdk/issues/16635)) ([55fbc86](https://github.com/aws/aws-cdk/commit/55fbc866ef0195fdfc722206e4d69a1f4469cd40)), closes [#16633](https://github.com/aws/aws-cdk/issues/16633) * **dynamodb:** add option to skip waiting for global replication to finish ([#16983](https://github.com/aws/aws-cdk/issues/16983)) ([254601f](https://github.com/aws/aws-cdk/commit/254601f477a4da309e81f5384140427f1b958bfd)), closes [#16611](https://github.com/aws/aws-cdk/issues/16611) * **ec2:** add aspect to require imdsv2 ([#16051](https://github.com/aws/aws-cdk/issues/16051)) ([0947b21](https://github.com/aws/aws-cdk/commit/0947b21c1e3186042324820ec5ab433237246f58)) -* **eks:** configure serviceIpv4Cidr on the cluster ([#16957](https://github.com/aws/aws-cdk/issues/16957)) ([72102c7](https://github.com/aws/aws-cdk/commit/72102c750bfd6564cd51c1a5d8abc79b1ba1d3ce)), closes [/docs.aws.amazon.com/eks/latest/APIReference/API_KubernetesNetworkConfigRequest.html#AmazonEKS-Type-KubernetesNetworkConfigRequest-serviceIpv4](https://github.com/aws//docs.aws.amazon.com/eks/latest/APIReference/API_KubernetesNetworkConfigRequest.html/issues/AmazonEKS-Type-KubernetesNetworkConfigRequest-serviceIpv4) [#16541](https://github.com/aws/aws-cdk/issues/16541) +* **eks:** configure serviceIpv4Cidr on the cluster ([#16957](https://github.com/aws/aws-cdk/issues/16957)) ([72102c7](https://github.com/aws/aws-cdk/commit/72102c750bfd6564cd51c1a5d8abc79b1ba1d3ce)), closes [#16541](https://github.com/aws/aws-cdk/issues/16541) * **events:** Add DLQ support for SQS target ([#16916](https://github.com/aws/aws-cdk/issues/16916)) ([7fda903](https://github.com/aws/aws-cdk/commit/7fda90318e18b3a5d126b040e35a0146634d5f2d)), closes [#16417](https://github.com/aws/aws-cdk/issues/16417) * **msk:** add Kafka version 2.8.1 ([#16881](https://github.com/aws/aws-cdk/issues/16881)) ([7db5c8c](https://github.com/aws/aws-cdk/commit/7db5c8cdafe7b9b22b6b40cb25ed8bd1946301f4)) * **stepfunctions-tasks:** add `enableNetworkIsolation` property to `SageMakerCreateTrainingJobProps` ([#16792](https://github.com/aws/aws-cdk/issues/16792)) ([69ac520](https://github.com/aws/aws-cdk/commit/69ac520452b219bf242f2fbb4740f6b1b8b8790f)), closes [#16779](https://github.com/aws/aws-cdk/issues/16779) From ee24046466f42efca4bf2b14ce9f344f174afa78 Mon Sep 17 00:00:00 2001 From: Nick Lynch Date: Thu, 21 Oct 2021 16:15:43 +0100 Subject: [PATCH 006/148] chore(individual-pkg-gen): strip redundant 'aws' from go package names (#17097) Currently, the published go alpha modules look like this: `github.com/aws/aws-cdk-go/awscdkawsfoobaralpha/v2` The redundant 'aws' in front of each service package name leads to a longer package name than necessary, on an already long name. This change explicitly sets the 'go' package name for each of the alpha modules, so they turn out like this: `github.com/aws/aws-cdk-go/awscdkfoobaralpha/v2` ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- tools/@aws-cdk/individual-pkg-gen/transform-packages.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/@aws-cdk/individual-pkg-gen/transform-packages.ts b/tools/@aws-cdk/individual-pkg-gen/transform-packages.ts index a5cbcb556ea1b..b56e39c788f2b 100644 --- a/tools/@aws-cdk/individual-pkg-gen/transform-packages.ts +++ b/tools/@aws-cdk/individual-pkg-gen/transform-packages.ts @@ -175,9 +175,11 @@ function transformPackageJson(pkg: any, source: string, destination: string, alp jsiiTargets.python.distName += '-alpha'; jsiiTargets.python.module += '_alpha'; // Typically, only our top-level packages have a Go target. - // moduleName is needed; packageName will be automatically derived by from the package name. + // packageName has unusable chars and redundant 'aws' stripped. + // This generates names like 'awscdkfoobaralpha' (rather than 'awscdkawsfoobaralpha'). jsiiTargets.go = { moduleName: 'github.com/aws/aws-cdk-go', + packageName: packageJson.name.replace('/aws-', '').replace(/[^a-z0-9.]/gi, '').toLowerCase(), }; const finalPackageJson = transformPackageJsonDependencies(packageJson, pkg, alphaPackages); From 86f85ce10f78b86133f9dab9851e56d03fb28cc0 Mon Sep 17 00:00:00 2001 From: Tatsuya Yamamoto Date: Fri, 22 Oct 2021 03:46:55 +0900 Subject: [PATCH 007/148] feat(iot): add the TopicRule L2 construct (#16681) I tried to implement aws-iot L2 Constructs. I did following: 1. add L2 construct 1. add unit tests 1. add integration test 1. test with deploying to my AWS account and sending MQTT. 1. update package.json resolves: #16602 I should do following for undrafting: - [x] write comments - [x] implement other actions Following is not implemented yet, but I will implements other PR. - Elasticsearch - Kinesis Firehose - Kinesis Stream - http - IoT Analytics - IoT Events - IoT SiteWise - kafka - Step Functions - [x] write README ---- ## Design ### TopicRule and IAction ![image](https://user-images.githubusercontent.com/11013683/136200920-9aa1aa58-2e9f-4a0d-a161-bbe251d02f7d.png) ### Implements of IAction ![image](https://user-images.githubusercontent.com/11013683/136201053-4f693683-3318-4fbf-9a7e-cd3f8ac1a93e.png) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-iot/README.md | 41 +++++- packages/@aws-cdk/aws-iot/lib/index.ts | 3 + packages/@aws-cdk/aws-iot/lib/iot-sql.ts | 75 +++++++++++ packages/@aws-cdk/aws-iot/lib/topic-rule.ts | 106 +++++++++++++++ packages/@aws-cdk/aws-iot/package.json | 6 +- .../test/integ.topic-rule.expected.json | 14 ++ .../@aws-cdk/aws-iot/test/integ.topic-rule.ts | 18 +++ packages/@aws-cdk/aws-iot/test/iot.test.ts | 6 - .../@aws-cdk/aws-iot/test/topic-rule.test.ts | 124 ++++++++++++++++++ 9 files changed, 384 insertions(+), 9 deletions(-) create mode 100644 packages/@aws-cdk/aws-iot/lib/iot-sql.ts create mode 100644 packages/@aws-cdk/aws-iot/lib/topic-rule.ts create mode 100644 packages/@aws-cdk/aws-iot/test/integ.topic-rule.expected.json create mode 100644 packages/@aws-cdk/aws-iot/test/integ.topic-rule.ts delete mode 100644 packages/@aws-cdk/aws-iot/test/iot.test.ts create mode 100644 packages/@aws-cdk/aws-iot/test/topic-rule.test.ts diff --git a/packages/@aws-cdk/aws-iot/README.md b/packages/@aws-cdk/aws-iot/README.md index 7334c9d4e108e..bbde9aae8a21d 100644 --- a/packages/@aws-cdk/aws-iot/README.md +++ b/packages/@aws-cdk/aws-iot/README.md @@ -9,8 +9,47 @@ > > [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib +![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge) + +> The APIs of higher level constructs in this module are experimental and under active development. +> They are subject to non-backward compatible changes or removal in any future version. These are +> not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be +> announced in the release notes. This means that while you may use them, you may need to update +> your source code when upgrading to a newer version of this package. + --- -This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project. +AWS IoT Core lets you connect billions of IoT devices and route trillions of +messages to AWS services without managing infrastructure. + +## Installation + +Install the module: + +```console +$ npm i @aws-cdk/aws-iot +``` + +Import it into your code: + +```ts +import * as iot from '@aws-cdk/aws-iot'; +``` + +## `TopicRule` + +The `TopicRule` construct defined Rules that give your devices the ability to +interact with AWS services. + +For example, to define a rule: + +```ts +new iot.TopicRule(stack, 'MyTopicRule', { + topicRuleName: 'MyRuleName', // optional property + sql: iot.IotSql.fromStringAsVer20160323( + "SELECT topic(2) as device_id, temperature FROM 'device/+/data'", + ), +}); +``` diff --git a/packages/@aws-cdk/aws-iot/lib/index.ts b/packages/@aws-cdk/aws-iot/lib/index.ts index 4f78a6cf531e3..18b6f2e03aaeb 100644 --- a/packages/@aws-cdk/aws-iot/lib/index.ts +++ b/packages/@aws-cdk/aws-iot/lib/index.ts @@ -1,2 +1,5 @@ +export * from './iot-sql'; +export * from './topic-rule'; + // AWS::IoT CloudFormation Resources: export * from './iot.generated'; diff --git a/packages/@aws-cdk/aws-iot/lib/iot-sql.ts b/packages/@aws-cdk/aws-iot/lib/iot-sql.ts new file mode 100644 index 0000000000000..c673552743364 --- /dev/null +++ b/packages/@aws-cdk/aws-iot/lib/iot-sql.ts @@ -0,0 +1,75 @@ +import { Construct } from 'constructs'; + +/** + * The type returned from the `bind()` method in {@link IotSql}. + */ +export interface IotSqlConfig { + /** + * The version of the SQL rules engine to use when evaluating the rule. + */ + readonly awsIotSqlVersion: string; + + /** + * The SQL statement used to query the topic. + */ + readonly sql: string; +} + +/** + * Defines AWS IoT SQL. + */ +export abstract class IotSql { + /** + * Uses the original SQL version built on 2015-10-08. + * + * @param sql The actual SQL-like syntax query + * @returns Instance of IotSql + */ + public static fromStringAsVer20151008(sql: string): IotSql { + return new IotSqlImpl('2015-10-08', sql); + } + + /** + * Uses the SQL version built on 2016-03-23. + * + * @param sql The actual SQL-like syntax query + * @returns Instance of IotSql + */ + public static fromStringAsVer20160323(sql: string): IotSql { + return new IotSqlImpl('2016-03-23', sql); + } + + /** + * Uses the most recent beta SQL version. If you use this version, it might + * introduce breaking changes to your rules. + * + * @param sql The actual SQL-like syntax query + * @returns Instance of IotSql + */ + public static fromStringAsVerNewestUnstable(sql: string): IotSql { + return new IotSqlImpl('beta', sql); + } + + /** + * Returns the IoT SQL configuration. + */ + public abstract bind(scope: Construct): IotSqlConfig; +} + + +class IotSqlImpl extends IotSql { + constructor(private readonly version: string, private readonly sql: string) { + super(); + + if (sql === '') { + throw new Error('IoT SQL string cannot be empty'); + } + } + + bind(_scope: Construct): IotSqlConfig { + return { + awsIotSqlVersion: this.version, + sql: this.sql, + }; + } +} diff --git a/packages/@aws-cdk/aws-iot/lib/topic-rule.ts b/packages/@aws-cdk/aws-iot/lib/topic-rule.ts new file mode 100644 index 0000000000000..17f121eb29ab3 --- /dev/null +++ b/packages/@aws-cdk/aws-iot/lib/topic-rule.ts @@ -0,0 +1,106 @@ +import { ArnFormat, Resource, Stack, IResource } from '@aws-cdk/core'; +import { Construct } from 'constructs'; +import { IotSql } from './iot-sql'; +import { CfnTopicRule } from './iot.generated'; + +/** + * Represents an AWS IoT Rule + */ +export interface ITopicRule extends IResource { + /** + * The value of the topic rule Amazon Resource Name (ARN), such as + * arn:aws:iot:us-east-2:123456789012:rule/rule_name + * + * @attribute + */ + readonly topicRuleArn: string; + + /** + * The name topic rule + * + * @attribute + */ + readonly topicRuleName: string; +} + +/** + * Properties for defining an AWS IoT Rule + */ +export interface TopicRuleProps { + /** + * The name of the rule. + * @default None + */ + readonly topicRuleName?: string; + + /** + * A simplified SQL syntax to filter messages received on an MQTT topic and push the data elsewhere. + * + * @see https://docs.aws.amazon.com/iot/latest/developerguide/iot-sql-reference.html + */ + readonly sql: IotSql; +} + +/** + * Defines an AWS IoT Rule in this stack. + */ +export class TopicRule extends Resource implements ITopicRule { + /** + * Import an existing AWS IoT Rule provided an ARN + * + * @param scope The parent creating construct (usually `this`). + * @param id The construct's name. + * @param topicRuleArn AWS IoT Rule ARN (i.e. arn:aws:iot:::rule/MyRule). + */ + public static fromTopicRuleArn(scope: Construct, id: string, topicRuleArn: string): ITopicRule { + const parts = Stack.of(scope).splitArn(topicRuleArn, ArnFormat.SLASH_RESOURCE_NAME); + if (!parts.resourceName) { + throw new Error(`Missing topic rule name in ARN: '${topicRuleArn}'`); + } + const resourceName = parts.resourceName; + + class Import extends Resource implements ITopicRule { + public readonly topicRuleArn = topicRuleArn; + public readonly topicRuleName = resourceName; + } + return new Import(scope, id, { + environmentFromArn: topicRuleArn, + }); + } + + /** + * Arn of this rule + * @attribute + */ + public readonly topicRuleArn: string; + + /** + * Name of this rule + * @attribute + */ + public readonly topicRuleName: string; + + constructor(scope: Construct, id: string, props: TopicRuleProps) { + super(scope, id, { + physicalName: props.topicRuleName, + }); + + const sqlConfig = props.sql.bind(this); + + const resource = new CfnTopicRule(this, 'Resource', { + ruleName: this.physicalName, + topicRulePayload: { + actions: [], + awsIotSqlVersion: sqlConfig.awsIotSqlVersion, + sql: sqlConfig.sql, + }, + }); + + this.topicRuleArn = this.getResourceArnAttribute(resource.attrArn, { + service: 'iot', + resource: 'rule', + resourceName: this.physicalName, + }); + this.topicRuleName = this.getResourceNameAttribute(resource.ref); + } +} diff --git a/packages/@aws-cdk/aws-iot/package.json b/packages/@aws-cdk/aws-iot/package.json index 9960168c78ec1..074ebd9c79435 100644 --- a/packages/@aws-cdk/aws-iot/package.json +++ b/packages/@aws-cdk/aws-iot/package.json @@ -74,9 +74,11 @@ "devDependencies": { "@aws-cdk/assertions": "0.0.0", "@aws-cdk/cdk-build-tools": "0.0.0", + "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/jest": "^26.0.24" + "@types/jest": "^26.0.24", + "jest": "^26.6.3" }, "dependencies": { "@aws-cdk/core": "0.0.0", @@ -91,7 +93,7 @@ "node": ">= 10.13.0 <13 || >=13.7.0" }, "stability": "experimental", - "maturity": "cfn-only", + "maturity": "experimental", "awscdkio": { "announce": false }, diff --git a/packages/@aws-cdk/aws-iot/test/integ.topic-rule.expected.json b/packages/@aws-cdk/aws-iot/test/integ.topic-rule.expected.json new file mode 100644 index 0000000000000..cf4be2735229e --- /dev/null +++ b/packages/@aws-cdk/aws-iot/test/integ.topic-rule.expected.json @@ -0,0 +1,14 @@ +{ + "Resources": { + "TopicRule40A4EA44": { + "Type": "AWS::IoT::TopicRule", + "Properties": { + "TopicRulePayload": { + "Actions": [], + "AwsIotSqlVersion": "2015-10-08", + "Sql": "SELECT topic(2) as device_id FROM 'device/+/data'" + } + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iot/test/integ.topic-rule.ts b/packages/@aws-cdk/aws-iot/test/integ.topic-rule.ts new file mode 100644 index 0000000000000..a06edc3c3f5e1 --- /dev/null +++ b/packages/@aws-cdk/aws-iot/test/integ.topic-rule.ts @@ -0,0 +1,18 @@ +/// !cdk-integ pragma:ignore-assets +import * as cdk from '@aws-cdk/core'; +import * as iot from '../lib'; + +const app = new cdk.App(); + +class TestStack extends cdk.Stack { + constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { + super(scope, id, props); + + new iot.TopicRule(this, 'TopicRule', { + sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id FROM 'device/+/data'"), + }); + } +} + +new TestStack(app, 'test-stack'); +app.synth(); diff --git a/packages/@aws-cdk/aws-iot/test/iot.test.ts b/packages/@aws-cdk/aws-iot/test/iot.test.ts deleted file mode 100644 index 465c7bdea0693..0000000000000 --- a/packages/@aws-cdk/aws-iot/test/iot.test.ts +++ /dev/null @@ -1,6 +0,0 @@ -import '@aws-cdk/assertions'; -import {} from '../lib'; - -test('No tests are specified for this package', () => { - expect(true).toBe(true); -}); diff --git a/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts b/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts new file mode 100644 index 0000000000000..1dec8c3065a86 --- /dev/null +++ b/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts @@ -0,0 +1,124 @@ +import { Template } from '@aws-cdk/assertions'; +import * as cdk from '@aws-cdk/core'; +import * as iot from '../lib'; + +test('Default property', () => { + const stack = new cdk.Stack(); + + new iot.TopicRule(stack, 'MyTopicRule', { + sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"), + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', { + TopicRulePayload: { + Actions: [], + Sql: "SELECT topic(2) as device_id, temperature FROM 'device/+/data'", + }, + }); +}); + +test('can get topic rule name', () => { + const stack = new cdk.Stack(); + const rule = new iot.TopicRule(stack, 'MyTopicRule', { + sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"), + }); + + new cdk.CfnResource(stack, 'Res', { + type: 'Test::Resource', + properties: { + TopicRuleName: rule.topicRuleName, + }, + }); + + Template.fromStack(stack).hasResourceProperties('Test::Resource', { + TopicRuleName: { Ref: 'MyTopicRule4EC2091C' }, + }); +}); + +test('can get topic rule arn', () => { + const stack = new cdk.Stack(); + const rule = new iot.TopicRule(stack, 'MyTopicRule', { + sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"), + }); + + new cdk.CfnResource(stack, 'Res', { + type: 'Test::Resource', + properties: { + TopicRuleArn: rule.topicRuleArn, + }, + }); + + Template.fromStack(stack).hasResourceProperties('Test::Resource', { + TopicRuleArn: { + 'Fn::GetAtt': ['MyTopicRule4EC2091C', 'Arn'], + }, + }); +}); + +test('can set physical name', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new iot.TopicRule(stack, 'MyTopicRule', { + topicRuleName: 'PhysicalName', + sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"), + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', { + RuleName: 'PhysicalName', + }); +}); + +test.each([ + ['fromStringAsVer20151008', iot.IotSql.fromStringAsVer20151008, '2015-10-08'], + ['fromStringAsVer20160323', iot.IotSql.fromStringAsVer20160323, '2016-03-23'], + ['fromStringAsVerNewestUnstable', iot.IotSql.fromStringAsVerNewestUnstable, 'beta'], +])('can set sql with using %s', (_, factoryMethod, version) => { + const stack = new cdk.Stack(); + + new iot.TopicRule(stack, 'MyTopicRule', { + sql: factoryMethod("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"), + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', { + TopicRulePayload: { + AwsIotSqlVersion: version, + Sql: "SELECT topic(2) as device_id, temperature FROM 'device/+/data'", + }, + }); +}); + +test.each([ + ['fromStringAsVer20151008', iot.IotSql.fromStringAsVer20151008], + ['fromStringAsVer20160323', iot.IotSql.fromStringAsVer20160323], + ['fromStringAsVerNewestUnstable', iot.IotSql.fromStringAsVerNewestUnstable], +])('Using %s fails when setting empty sql', (_, factoryMethod) => { + expect(() => { + factoryMethod(''); + }).toThrow('IoT SQL string cannot be empty'); +}); + +test('can import a TopicRule by ARN', () => { + const stack = new cdk.Stack(); + + const topicRuleArn = 'arn:aws:iot:ap-northeast-1:123456789012:rule/my-rule-name'; + + const topicRule = iot.TopicRule.fromTopicRuleArn(stack, 'TopicRuleFromArn', topicRuleArn); + + expect(topicRule).toMatchObject({ + topicRuleArn, + topicRuleName: 'my-rule-name', + }); +}); + +test('fails importing a TopicRule by ARN if the ARN is missing the name of the TopicRule', () => { + const stack = new cdk.Stack(); + + const topicRuleArn = 'arn:aws:iot:ap-northeast-1:123456789012:rule/'; + + expect(() => { + iot.TopicRule.fromTopicRuleArn(stack, 'TopicRuleFromArn', topicRuleArn); + }).toThrow("Missing topic rule name in ARN: 'arn:aws:iot:ap-northeast-1:123456789012:rule/'"); +}); From b0d5a573d1d545623713f86cbb185c0ed61d0330 Mon Sep 17 00:00:00 2001 From: Andreas Skyman Date: Thu, 21 Oct 2021 22:57:17 +0200 Subject: [PATCH 008/148] chore: Missing ; makes initialised test fail linting (#16637) The missing ; in the template makes the newly generated test file fail linting. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../v1/app/typescript/test/%name%.test.template.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk/lib/init-templates/v1/app/typescript/test/%name%.test.template.ts b/packages/aws-cdk/lib/init-templates/v1/app/typescript/test/%name%.test.template.ts index b98e4f0abee50..a574690020687 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/typescript/test/%name%.test.template.ts +++ b/packages/aws-cdk/lib/init-templates/v1/app/typescript/test/%name%.test.template.ts @@ -9,5 +9,5 @@ test('Empty Stack', () => { // THEN expectCDK(stack).to(matchTemplate({ "Resources": {} - }, MatchStyle.EXACT)) + }, MatchStyle.EXACT)); }); From 3617b70527516237955b8415fcfc8b58d3e23b3c Mon Sep 17 00:00:00 2001 From: Matt Berry Date: Thu, 21 Oct 2021 14:50:27 -0700 Subject: [PATCH 009/148] fix(custom-resources): Role Session Name can exceed maximum size (#16680) The provider used the physical resource id and the epoch time as the name of the assumed role session. Unfortunately, the maximum length of these two fields combined can exceed the 64 character limit on a role session name. The role session name is not extremely important, it's purely for human consumption. Nothing ensures that every assumed role session has a unique role session name. For a unique identifier, the session's access key identifier should be used instead. This change caps the generate role session name at 64 characters and moves the timestamp to the front, so that it is not the portion of the name that is truncated. https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html ``` 2021-09-28T01:36:45.780Z fc8f6e02-d746-441b-b07c-5e2b836087a0 INFO Error [CredentialsError]: Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1 at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/query.js:50:29) at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10) at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14) at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10) at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12) at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10 at Request. (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9) at Request. (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12) at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18) { code: 'CredentialsError', time: 2021-09-28T01:36:45.659Z, requestId: '8aedc751-a552-449c-af2b-4566e3160d98', statusCode: 400, retryable: false, retryDelay: 38.712174099272744, originalError: { message: 'Could not load credentials from ChainableTemporaryCredentials', code: 'CredentialsError', time: 2021-09-28T01:36:45.659Z, requestId: '8aedc751-a552-449c-af2b-4566e3160d98', statusCode: 400, retryable: false, retryDelay: 38.712174099272744, originalError: { message: "1 validation error detected: Value 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-1632793004697' at 'roleSessionName' failed to satisfy constraint: Member must have length less than or equal to 64", code: 'ValidationError', time: 2021-09-28T01:36:45.657Z, requestId: '8aedc751-a552-449c-af2b-4566e3160d98', statusCode: 400, retryable: false, retryDelay: 38.712174099272744 } } } ``` ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../custom-resources/lib/aws-custom-resource/runtime/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts b/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts index 68156b6412958..a805fc8c2bf4d 100644 --- a/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts +++ b/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts @@ -167,7 +167,7 @@ export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent const params = { RoleArn: call.assumedRoleArn, - RoleSessionName: `${physicalResourceId}-${timestamp}`, + RoleSessionName: `${timestamp}-${physicalResourceId}`.substring(0, 64), }; AWS.config.credentials = new AWS.ChainableTemporaryCredentials({ From 5ba7f6ad13acad51c3c4280b9f2954acdd4a381c Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Thu, 21 Oct 2021 16:43:09 -0600 Subject: [PATCH 010/148] docs(iam): improve fromAwsManagedPolicyName documentation (#16737) This documentation was confusing to me. I kept reading it as "Do not include", even though it said "Do include". For clarity, this PR changes "Do include" to just "Include". ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-iam/lib/managed-policy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-iam/lib/managed-policy.ts b/packages/@aws-cdk/aws-iam/lib/managed-policy.ts index cc8bddc0e8a17..3fd1a936d4ab7 100644 --- a/packages/@aws-cdk/aws-iam/lib/managed-policy.ts +++ b/packages/@aws-cdk/aws-iam/lib/managed-policy.ts @@ -151,7 +151,7 @@ export class ManagedPolicy extends Resource implements IManagedPolicy { * For this managed policy, you only need to know the name to be able to use it. * * Some managed policy names start with "service-role/", some start with - * "job-function/", and some don't start with anything. Do include the + * "job-function/", and some don't start with anything. Include the * prefix when constructing this object. */ public static fromAwsManagedPolicyName(managedPolicyName: string): IManagedPolicy { From 131b4720362658ed237b9fd78c33ac8a98b92471 Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Thu, 21 Oct 2021 16:37:21 -0700 Subject: [PATCH 011/148] docs: corrected grammatical issues (#16809) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/pipelines/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/pipelines/README.md b/packages/@aws-cdk/pipelines/README.md index bd6525542920b..ac345c75f3776 100644 --- a/packages/@aws-cdk/pipelines/README.md +++ b/packages/@aws-cdk/pipelines/README.md @@ -38,7 +38,7 @@ with the same amount of code. The *CDK Pipelines* library takes care of the details. CDK Pipelines supports multiple *deployment engines* (see below), and comes with -a deployment engine that deployes CDK apps using AWS CodePipeline. To use the +a deployment engine that deploys CDK apps using AWS CodePipeline. To use the CodePipeline engine, define a `CodePipeline` construct. The following example creates a CodePipeline that deploys an application from GitHub: @@ -155,8 +155,8 @@ by adding the following to `cdk.json`: ## Provisioning the pipeline -To provision the pipeline you have defined, making sure the target environment -has been bootstrapped (see below), and then executing deploying the +To provision the pipeline you have defined, make sure the target environment +has been bootstrapped (see below), and then execute deploying the `PipelineStack` *once*. Afterwards, the pipeline will keep itself up-to-date. > **Important**: be sure to `git commit` and `git push` before deploying the @@ -175,7 +175,7 @@ $ cdk deploy PipelineStack ``` Administrative permissions to the account are only necessary up until -this point. We recommend you shed access to these credentials after doing this. +this point. We recommend you remove access to these credentials after doing this. ### Working on the pipeline From 985f7b9ce364097e9f91fa669e4158793e067afd Mon Sep 17 00:00:00 2001 From: Dan Cavallaro Date: Thu, 21 Oct 2021 20:31:20 -0400 Subject: [PATCH 012/148] docs(custom-resource): correcting links to S3File example code (#16822) Was reading the custom-resource documentation this morning (https://docs.aws.amazon.com/cdk/api/latest/docs/custom-resources-readme.html#s3file) and realized that both the S3File and S3Assert sections linked to the S3Assert sample code. Fixed the S3File links to point to the right files, and verified that they looked correct in the rendered Markdown. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/custom-resources/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/custom-resources/README.md b/packages/@aws-cdk/custom-resources/README.md index 8583e04bc087f..90892fb7906c7 100644 --- a/packages/@aws-cdk/custom-resources/README.md +++ b/packages/@aws-cdk/custom-resources/README.md @@ -301,8 +301,8 @@ This module includes a few examples for custom resource implementations: Provisions an object in an S3 bucket with textual contents. See the source code for the -[construct](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/custom-resources/test/provider-framework/integration-test-fixtures/s3-assert.ts) and -[handler](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/custom-resources/test/provider-framework/integration-test-fixtures/s3-assert-handler/index.py). +[construct](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/custom-resources/test/provider-framework/integration-test-fixtures/s3-file.ts) and +[handler](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/custom-resources/test/provider-framework/integration-test-fixtures/s3-file-handler/index.ts). The following example will create the file `folder/file1.txt` inside `myBucket` with the contents `hello!`. From f4dc54aef09d3b3e63fbd2efd35b084d8b8fa5d8 Mon Sep 17 00:00:00 2001 From: Jerry Kindall <52084730+Jerry-AWS@users.noreply.github.com> Date: Thu, 21 Oct 2021 18:24:15 -0700 Subject: [PATCH 013/148] docs: fix typo (#16833) otional -> optional ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-events-targets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-events-targets/README.md b/packages/@aws-cdk/aws-events-targets/README.md index a5c8fde1d9d98..76d25eab83dd3 100644 --- a/packages/@aws-cdk/aws-events-targets/README.md +++ b/packages/@aws-cdk/aws-events-targets/README.md @@ -65,7 +65,7 @@ const queue = new sqs.Queue(this, 'Queue'); rule.addTarget(new targets.LambdaFunction(fn, { deadLetterQueue: queue, // Optional: add a dead letter queue - maxEventAge: cdk.Duration.hours(2), // Otional: set the maxEventAge retry policy + maxEventAge: cdk.Duration.hours(2), // Optional: set the maxEventAge retry policy retryAttempts: 2, // Optional: set the max number of retry attempts })); ``` From 672acba9e532776832565d0fb91a59f261d6a466 Mon Sep 17 00:00:00 2001 From: tmokmss Date: Fri, 22 Oct 2021 11:16:17 +0900 Subject: [PATCH 014/148] docs(applicationautoscaling): fix wrong description for EnableScalingProps (#16863) `EnableScalingProps` has no relation to DynamoDB. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-applicationautoscaling/lib/base-scalable-attribute.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-applicationautoscaling/lib/base-scalable-attribute.ts b/packages/@aws-cdk/aws-applicationautoscaling/lib/base-scalable-attribute.ts index 95d2a19c8a17d..6bb821240c6ff 100644 --- a/packages/@aws-cdk/aws-applicationautoscaling/lib/base-scalable-attribute.ts +++ b/packages/@aws-cdk/aws-applicationautoscaling/lib/base-scalable-attribute.ts @@ -86,7 +86,7 @@ export abstract class BaseScalableAttribute extends CoreConstruct { } /** - * Properties for enabling DynamoDB capacity scaling + * Properties for enabling Application Auto Scaling */ export interface EnableScalingProps { /** From 54ca9105194767c6d8401c7f439ff7919c225b4a Mon Sep 17 00:00:00 2001 From: Julian Michel Date: Fri, 22 Oct 2021 06:01:34 +0200 Subject: [PATCH 015/148] docs(core): fix CfnMapping example (#16882) The CloudFormation intrinsic function `Fn::FindInMap` only supports alphanumeric characters as name. However, the `CfnMapping` examples in the README file contain hyphens in the name field. This causes an error when the code is deployed. I changed the structure of the examples to create examples that can be deployed in AWS. Fixes #16866. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/core/README.md | 35 ++++++++++++++++++-------------- packages/aws-cdk-lib/README.md | 35 ++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/packages/@aws-cdk/core/README.md b/packages/@aws-cdk/core/README.md index a6d4d2efc5a9b..1090d893c508d 100644 --- a/packages/@aws-cdk/core/README.md +++ b/packages/@aws-cdk/core/README.md @@ -753,16 +753,19 @@ CloudFormation [mappings][cfn-mappings] are created and queried using the ```ts const regionTable = new CfnMapping(this, 'RegionTable', { mapping: { - regionName: { - 'us-east-1': 'US East (N. Virginia)', - 'us-east-2': 'US East (Ohio)', + 'us-east-1': { + regionName: 'US East (N. Virginia)', + // ... + }, + 'us-east-2': { + regionName: 'US East (Ohio)', // ... }, // ... } }); -regionTable.findInMap('regionName', Aws.REGION); +regionTable.findInMap(Aws.REGION, 'regionName') ``` This will yield the following template: @@ -770,9 +773,10 @@ This will yield the following template: ```yaml Mappings: RegionTable: - regionName: - us-east-1: US East (N. Virginia) - us-east-2: US East (Ohio) + us-east-1: + regionName: US East (N. Virginia) + us-east-2: + regionName: US East (Ohio) ``` Mappings can also be synthesized "lazily"; lazy mappings will only render a "Mappings" @@ -787,24 +791,25 @@ call to `findInMap` will be able to resolve the value during synthesis and simpl ```ts const regionTable = new CfnMapping(this, 'RegionTable', { mapping: { - regionName: { - 'us-east-1': 'US East (N. Virginia)', - 'us-east-2': 'US East (Ohio)', + 'us-east-1': { + regionName: 'US East (N. Virginia)', + }, + 'us-east-2': { + regionName: 'US East (Ohio)', }, }, lazy: true, }); -regionTable.findInMap('regionName', 'us-east-2'); +regionTable.findInMap('us-east-2', 'regionName'); ``` On the other hand, the following code will produce the "Mappings" section shown above, -since the second-level key is an unresolved token. The call to `findInMap` will return a -token that resolves to `{ Fn::FindInMap: [ 'RegionTable', 'regionName', { Ref: AWS::Region -} ] }`. +since the top-level key is an unresolved token. The call to `findInMap` will return a token that resolves to +`{ "Fn::FindInMap": [ "RegionTable", { "Ref": "AWS::Region" }, "regionName" ] }`. ```ts -regionTable.findInMap('regionName', Aws.REGION); +regionTable.findInMap(Aws.REGION, 'regionName'); ``` [cfn-mappings]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html diff --git a/packages/aws-cdk-lib/README.md b/packages/aws-cdk-lib/README.md index 48d4cd65f93a5..5d225ce542aa5 100644 --- a/packages/aws-cdk-lib/README.md +++ b/packages/aws-cdk-lib/README.md @@ -786,16 +786,19 @@ CloudFormation [mappings][cfn-mappings] are created and queried using the ```ts const regionTable = new CfnMapping(this, 'RegionTable', { mapping: { - regionName: { - 'us-east-1': 'US East (N. Virginia)', - 'us-east-2': 'US East (Ohio)', + 'us-east-1': { + regionName: 'US East (N. Virginia)', + // ... + }, + 'us-east-2': { + regionName: 'US East (Ohio)', // ... }, // ... } }); -regionTable.findInMap('regionName', Aws.REGION); +regionTable.findInMap(Aws.REGION, 'regionName') ``` This will yield the following template: @@ -803,9 +806,10 @@ This will yield the following template: ```yaml Mappings: RegionTable: - regionName: - us-east-1: US East (N. Virginia) - us-east-2: US East (Ohio) + us-east-1: + regionName: US East (N. Virginia) + us-east-2: + regionName: US East (Ohio) ``` Mappings can also be synthesized "lazily"; lazy mappings will only render a "Mappings" @@ -820,24 +824,25 @@ call to `findInMap` will be able to resolve the value during synthesis and simpl ```ts const regionTable = new CfnMapping(this, 'RegionTable', { mapping: { - regionName: { - 'us-east-1': 'US East (N. Virginia)', - 'us-east-2': 'US East (Ohio)', + 'us-east-1': { + regionName: 'US East (N. Virginia)', + }, + 'us-east-2': { + regionName: 'US East (Ohio)', }, }, lazy: true, }); -regionTable.findInMap('regionName', 'us-east-2'); +regionTable.findInMap('us-east-2', 'regionName'); ``` On the other hand, the following code will produce the "Mappings" section shown above, -since the second-level key is an unresolved token. The call to `findInMap` will return a -token that resolves to `{ Fn::FindInMap: [ 'RegionTable', 'regionName', { Ref: AWS::Region -} ] }`. +since the top-level key is an unresolved token. The call to `findInMap` will return a token that resolves to +`{ "Fn::FindInMap": [ "RegionTable", { "Ref": "AWS::Region" }, "regionName" ] }`. ```ts -regionTable.findInMap('regionName', Aws.REGION); +regionTable.findInMap(Aws.REGION, 'regionName'); ``` [cfn-mappings]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html From 5f7c58bc9b4acc36a197e6ebebceda9923a50ec3 Mon Sep 17 00:00:00 2001 From: Kyle Wiest Date: Thu, 21 Oct 2021 21:56:08 -0700 Subject: [PATCH 016/148] docs: fix README - change Construct to Stage (#17079) A Stage is meant to hold collections of Stacks as a unit of deployment. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/core/README.md | 2 +- packages/aws-cdk-lib/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/core/README.md b/packages/@aws-cdk/core/README.md index 1090d893c508d..79ac6e6bb3e4d 100644 --- a/packages/@aws-cdk/core/README.md +++ b/packages/@aws-cdk/core/README.md @@ -48,7 +48,7 @@ logical application. You can then treat that new unit the same way you used to be able to treat a single stack: by instantiating it multiple times for different instances of your application. -You can define a custom subclass of `Construct`, holding one or more +You can define a custom subclass of `Stage`, holding one or more `Stack`s, to represent a single logical instance of your application. As a final note: `Stack`s are not a unit of reuse. They describe physical diff --git a/packages/aws-cdk-lib/README.md b/packages/aws-cdk-lib/README.md index 5d225ce542aa5..40fc7c0d880af 100644 --- a/packages/aws-cdk-lib/README.md +++ b/packages/aws-cdk-lib/README.md @@ -81,7 +81,7 @@ logical application. You can then treat that new unit the same way you used to be able to treat a single stack: by instantiating it multiple times for different instances of your application. -You can define a custom subclass of `Construct`, holding one or more +You can define a custom subclass of `Stage`, holding one or more `Stack`s, to represent a single logical instance of your application. As a final note: `Stack`s are not a unit of reuse. They describe physical From d7aceec9fe2cad0f13f012000a60c06c06e0705c Mon Sep 17 00:00:00 2001 From: Mattia <5013654+mattiamatrix@users.noreply.github.com> Date: Fri, 22 Oct 2021 06:49:50 +0100 Subject: [PATCH 017/148] chore(aws-kinesisanalytics-flink): add support to Flink 1.13 (#17019) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support to Flink 1.13 in construct `@aws-cdk/aws-kinesisanalytics-flink ยป Application` This fixes #16985 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-kinesisanalytics-flink/README.md | 2 +- packages/@aws-cdk/aws-kinesisanalytics-flink/lib/types.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-kinesisanalytics-flink/README.md b/packages/@aws-cdk/aws-kinesisanalytics-flink/README.md index 5322ff28027f7..830b59a2c7053 100644 --- a/packages/@aws-cdk/aws-kinesisanalytics-flink/README.md +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/README.md @@ -59,7 +59,7 @@ import * as logs from '@aws-cdk/aws-logs'; const flinkApp = new flink.Application(this, 'Application', { code: flink.ApplicationCode.fromBucket(bucket, 'my-app.jar'), - runtime: file.Runtime.FLINK_1_11, + runtime: file.Runtime.FLINK_1_13, checkpointingEnabled: true, // default is true checkpointInterval: cdk.Duration.seconds(30), // default is 1 minute minPauseBetweenCheckpoints: cdk.Duration.seconds(10), // default is 5 seconds diff --git a/packages/@aws-cdk/aws-kinesisanalytics-flink/lib/types.ts b/packages/@aws-cdk/aws-kinesisanalytics-flink/lib/types.ts index b92d55cb48518..02e56eee10966 100644 --- a/packages/@aws-cdk/aws-kinesisanalytics-flink/lib/types.ts +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/lib/types.ts @@ -37,7 +37,7 @@ export enum MetricsLevel { * configuration. */ export interface PropertyGroups { - readonly [propertyId: string]: {[mapKey: string]: string}; + readonly [propertyId: string]: { [mapKey: string]: string }; } /** @@ -53,6 +53,9 @@ export class Runtime { /** Flink Version 1.11 */ public static readonly FLINK_1_11 = Runtime.of('FLINK-1_11'); + /** Flink Version 1.13 */ + public static readonly FLINK_1_13 = Runtime.of('FLINK-1_13'); + /** Create a new Runtime with with an arbitrary Flink version string */ public static of(value: string) { return new Runtime(value); From 0520ca2a7ac695115df7cb43e1c0aececd6802ed Mon Sep 17 00:00:00 2001 From: Almas Sapargali Date: Fri, 22 Oct 2021 12:41:57 +0600 Subject: [PATCH 018/148] docs(amplify): fix files example in BuildSpec.fromObjectToYaml (#16701) passing `files: '**/*'` to artifacts doesn't work. It needs to be an array. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-amplify/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-amplify/README.md b/packages/@aws-cdk/aws-amplify/README.md index a706cb73bb39b..472846ea276b6 100644 --- a/packages/@aws-cdk/aws-amplify/README.md +++ b/packages/@aws-cdk/aws-amplify/README.md @@ -55,7 +55,8 @@ const amplifyApp = new amplify.App(this, 'MyApp', { }, artifacts: { baseDirectory: 'public', - files: '**/*' + files: + - '**/*' } } }) From a0d4ee75ff6cdd0f1e4dba1273b9ff754da777db Mon Sep 17 00:00:00 2001 From: Calvin Combs <66279577+comcalvi@users.noreply.github.com> Date: Fri, 22 Oct 2021 00:39:25 -0700 Subject: [PATCH 019/148] chore(cli): stop hard-coding partition to 'aws' in hotswapping (#17085) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/lib/api/hotswap-deployments.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/aws-cdk/lib/api/hotswap-deployments.ts b/packages/aws-cdk/lib/api/hotswap-deployments.ts index 138adf904c992..19b8405a7de19 100644 --- a/packages/aws-cdk/lib/api/hotswap-deployments.ts +++ b/packages/aws-cdk/lib/api/hotswap-deployments.ts @@ -35,8 +35,7 @@ export async function tryHotswapDeployment( parameters: assetParams, account: resolvedEnv.account, region: resolvedEnv.region, - // ToDo make this better: - partition: 'aws', + partition: (await sdk.currentAccount()).partition, // ToDo make this better: urlSuffix: 'amazonaws.com', listStackResources, From c74b0127af95f8e86b95a0be2f2c6cb30fab1103 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 22 Oct 2021 11:56:08 +0200 Subject: [PATCH 020/148] fix(core): `DefaultSynthesizer` deployments are never skipped (#17099) The `DefaultSynthesizer` always adds an SSM parameter with the bootstrap stack version, so that it can check that the bootstrap stack has a recent enough version. Unfortunately, the CDK CLI will refuse to short-circuit any deployment that uses SSM parameters, because it can't tell if the parameter has changed, and so it has to pessimize. Adding a magic marker to the description of the parameter will now exempt it from the check. Fixes #16959. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../stack-synthesizers/default-synthesizer.ts | 2 +- .../new-style-synthesis.test.ts | 1 + packages/@aws-cdk/cx-api/lib/cxapi.ts | 11 +++++++- .../test/blueprint/stack-deployment.test.ts | 4 +-- .../integ.newpipeline-with-vpc.expected.json | 2 +- .../test/integ.newpipeline.expected.json | 2 +- .../integ.pipeline-security.expected.json | 2 +- ...ne-with-assets-single-upload.expected.json | 2 +- .../integ.pipeline-with-assets.expected.json | 2 +- .../test/integ.pipeline.expected.json | 2 +- packages/aws-cdk/lib/api/deploy-stack.ts | 10 ++++--- .../aws-cdk/lib/api/util/cloudformation.ts | 13 ++++++--- .../aws-cdk/test/util/cloudformation.test.ts | 27 +++++++++++++++++-- 13 files changed, 61 insertions(+), 19 deletions(-) diff --git a/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts b/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts index 5c4072c3efc5c..aae69e36ef24e 100644 --- a/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts +++ b/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts @@ -600,7 +600,7 @@ function addBootstrapVersionRule(stack: Stack, requiredVersion: number, bootstra const param = new CfnParameter(stack, 'BootstrapVersion', { type: 'AWS::SSM::Parameter::Value', - description: 'Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store.', + description: `Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. ${cxapi.SSMPARAM_NO_INVALIDATE}`, default: bootstrapStackVersionSsmParameter, }); diff --git a/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts b/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts index 1528e91205f80..3a8d8c1e60b31 100644 --- a/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts +++ b/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts @@ -70,6 +70,7 @@ describe('new style synthesis', () => { const template = app.synth().getStackByName('Stack').template; expect(template?.Parameters?.BootstrapVersion?.Type).toEqual('AWS::SSM::Parameter::Value'); expect(template?.Parameters?.BootstrapVersion?.Default).toEqual('/cdk-bootstrap/hnb659fds/version'); + expect(template?.Parameters?.BootstrapVersion?.Description).toContain(cxapi.SSMPARAM_NO_INVALIDATE); const assertions = template?.Rules?.CheckBootstrapVersion?.Assertions ?? []; expect(assertions.length).toEqual(1); diff --git a/packages/@aws-cdk/cx-api/lib/cxapi.ts b/packages/@aws-cdk/cx-api/lib/cxapi.ts index 33d83e74ea45c..9b179e9a71b5f 100644 --- a/packages/@aws-cdk/cx-api/lib/cxapi.ts +++ b/packages/@aws-cdk/cx-api/lib/cxapi.ts @@ -31,4 +31,13 @@ export const CLI_VERSION_ENV = 'CDK_CLI_VERSION'; /** * If a context value is an object with this key, it indicates an error */ -export const PROVIDER_ERROR_KEY = '$providerError'; \ No newline at end of file +export const PROVIDER_ERROR_KEY = '$providerError'; + + +/** + * This SSM parameter does not invalidate the template + * + * If this string occurs in the description of an SSM parameter, the CLI + * will not assume that the stack must always be redeployed. + */ +export const SSMPARAM_NO_INVALIDATE = '[cdk:skip]'; \ No newline at end of file diff --git a/packages/@aws-cdk/pipelines/test/blueprint/stack-deployment.test.ts b/packages/@aws-cdk/pipelines/test/blueprint/stack-deployment.test.ts index ee9d5b29240ce..68ca1f20a20b6 100644 --- a/packages/@aws-cdk/pipelines/test/blueprint/stack-deployment.test.ts +++ b/packages/@aws-cdk/pipelines/test/blueprint/stack-deployment.test.ts @@ -31,7 +31,7 @@ describe('templateUrl', () => { const sd = StageDeployment.fromStage(stage); // THEN - expect(sd.stacks[0].templateUrl).toBe('https://cdk-hnb659fds-assets-111-us-east-1.s3.us-east-1.amazonaws.com/4ef627170a212f66f5d1d9240d967ef306f4820ff9cb05b3a7ec703df6af6c3e.json'); + expect(sd.stacks[0].templateUrl).toBe('https://cdk-hnb659fds-assets-111-us-east-1.s3.us-east-1.amazonaws.com/93ae4de94f81d0905c37db64b7304f5d65233ca4d9581d3a32215743c9bb92dd.json'); }); test('without region', () => { @@ -43,7 +43,7 @@ describe('templateUrl', () => { const sd = StageDeployment.fromStage(stage); // THEN - expect(sd.stacks[0].templateUrl).toBe('https://cdk-hnb659fds-assets-111-.s3.amazonaws.com/$%7BAWS::Region%7D/4ef627170a212f66f5d1d9240d967ef306f4820ff9cb05b3a7ec703df6af6c3e.json'); + expect(sd.stacks[0].templateUrl).toBe('https://cdk-hnb659fds-assets-111-.s3.amazonaws.com/$%7BAWS::Region%7D/93ae4de94f81d0905c37db64b7304f5d65233ca4d9581d3a32215743c9bb92dd.json'); }); }); diff --git a/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json b/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json index e0075942e6069..80a17d7243cb1 100644 --- a/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json @@ -2368,7 +2368,7 @@ "BootstrapVersion": { "Type": "AWS::SSM::Parameter::Value", "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store." + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" } }, "Rules": { diff --git a/packages/@aws-cdk/pipelines/test/integ.newpipeline.expected.json b/packages/@aws-cdk/pipelines/test/integ.newpipeline.expected.json index 07e65b9bd643f..935ad4ce5136a 100644 --- a/packages/@aws-cdk/pipelines/test/integ.newpipeline.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.newpipeline.expected.json @@ -2303,7 +2303,7 @@ "BootstrapVersion": { "Type": "AWS::SSM::Parameter::Value", "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store." + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" } }, "Rules": { diff --git a/packages/@aws-cdk/pipelines/test/integ.pipeline-security.expected.json b/packages/@aws-cdk/pipelines/test/integ.pipeline-security.expected.json index b72a78754a1d2..3d808a0f31767 100644 --- a/packages/@aws-cdk/pipelines/test/integ.pipeline-security.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.pipeline-security.expected.json @@ -2366,7 +2366,7 @@ "BootstrapVersion": { "Type": "AWS::SSM::Parameter::Value", "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store." + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" } }, "Rules": { diff --git a/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets-single-upload.expected.json b/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets-single-upload.expected.json index 8250f113b53e3..85f20ecf8995f 100644 --- a/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets-single-upload.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets-single-upload.expected.json @@ -1519,7 +1519,7 @@ "BootstrapVersion": { "Type": "AWS::SSM::Parameter::Value", "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store." + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" } }, "Rules": { diff --git a/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets.expected.json b/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets.expected.json index c2e4cddc58aef..e236dbdb569ac 100644 --- a/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets.expected.json @@ -1576,7 +1576,7 @@ "BootstrapVersion": { "Type": "AWS::SSM::Parameter::Value", "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store." + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" } }, "Rules": { diff --git a/packages/@aws-cdk/pipelines/test/integ.pipeline.expected.json b/packages/@aws-cdk/pipelines/test/integ.pipeline.expected.json index 32a0a50bd90d5..0f158a1dffdf5 100644 --- a/packages/@aws-cdk/pipelines/test/integ.pipeline.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.pipeline.expected.json @@ -1299,7 +1299,7 @@ "BootstrapVersion": { "Type": "AWS::SSM::Parameter::Value", "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store." + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" } }, "Rules": { diff --git a/packages/aws-cdk/lib/api/deploy-stack.ts b/packages/aws-cdk/lib/api/deploy-stack.ts index f58f441560e3e..6b5afe9673ead 100644 --- a/packages/aws-cdk/lib/api/deploy-stack.ts +++ b/packages/aws-cdk/lib/api/deploy-stack.ts @@ -14,7 +14,7 @@ import { CfnEvaluationException } from './hotswap/evaluate-cloudformation-templa import { ToolkitInfo } from './toolkit-info'; import { changeSetHasNoChanges, CloudFormationStack, TemplateParameters, waitForChangeSet, - waitForStackDeploy, waitForStackDelete, ParameterValues, + waitForStackDeploy, waitForStackDelete, ParameterValues, ParameterChanges, } from './util/cloudformation'; import { StackActivityMonitor, StackActivityProgress } from './util/cloudformation/stack-activity-monitor'; @@ -466,7 +466,7 @@ export async function destroyStack(options: DestroyStackOptions) { async function canSkipDeploy( deployStackOptions: DeployStackOptions, cloudFormationStack: CloudFormationStack, - parameterChanges: boolean): Promise { + parameterChanges: ParameterChanges): Promise { const deployName = deployStackOptions.deployName || deployStackOptions.stack.stackName; debug(`${deployName}: checking if we can skip deploy`); @@ -509,7 +509,11 @@ async function canSkipDeploy( // Parameters have changed if (parameterChanges) { - debug(`${deployName}: parameters have changed`); + if (parameterChanges === 'ssm') { + debug(`${deployName}: some parameters come from SSM so we have to assume they may have changed`); + } else { + debug(`${deployName}: parameters have changed`); + } return false; } diff --git a/packages/aws-cdk/lib/api/util/cloudformation.ts b/packages/aws-cdk/lib/api/util/cloudformation.ts index 19db988fdc15e..b3b5660d727c4 100644 --- a/packages/aws-cdk/lib/api/util/cloudformation.ts +++ b/packages/aws-cdk/lib/api/util/cloudformation.ts @@ -1,3 +1,4 @@ +import { SSMPARAM_NO_INVALIDATE } from '@aws-cdk/cx-api'; import { CloudFormation } from 'aws-sdk'; import { debug } from '../../logging'; import { deserializeStructure } from '../../serialize'; @@ -11,6 +12,7 @@ export type Template = { interface TemplateParameter { Type: string; Default?: any; + Description?: string; [key: string]: any; } @@ -424,11 +426,12 @@ export class ParameterValues { /** * Whether this set of parameter updates will change the actual stack values */ - public hasChanges(currentValues: Record): boolean { + public hasChanges(currentValues: Record): ParameterChanges { // If any of the parameters are SSM parameters, deploying must always happen - // because we can't predict what the values will be. - if (Object.values(this.formalParams).some(p => p.Type.startsWith('AWS::SSM::Parameter::'))) { - return true; + // because we can't predict what the values will be. We will allow some + // parameters to opt out of this check by having a magic string in their description. + if (Object.values(this.formalParams).some(p => p.Type.startsWith('AWS::SSM::Parameter::') && !p.Description?.includes(SSMPARAM_NO_INVALIDATE))) { + return 'ssm'; } // Otherwise we're dirty if: @@ -445,3 +448,5 @@ export class ParameterValues { return false; } } + +export type ParameterChanges = boolean | 'ssm'; \ No newline at end of file diff --git a/packages/aws-cdk/test/util/cloudformation.test.ts b/packages/aws-cdk/test/util/cloudformation.test.ts index c8c034ba23f67..40a748d50ea37 100644 --- a/packages/aws-cdk/test/util/cloudformation.test.ts +++ b/packages/aws-cdk/test/util/cloudformation.test.ts @@ -1,3 +1,4 @@ +import { SSMPARAM_NO_INVALIDATE } from '@aws-cdk/cx-api'; import { CloudFormationStack, TemplateParameters } from '../../lib/api/util/cloudformation'; import { MockedObject, MockSdkProvider, SyncHandlerSubsetOf } from './mock-sdk'; @@ -81,10 +82,32 @@ test('if a parameter is retrieved from SSM, the parameters always count as chang const oldValues = { Foo: '/Some/Key' }; // If we don't pass a new value - expect(params.updateExisting({}, oldValues).hasChanges(oldValues)).toEqual(true); + expect(params.updateExisting({}, oldValues).hasChanges(oldValues)).toEqual('ssm'); // If we do pass a new value but it's the same as the old one - expect(params.updateExisting({ Foo: '/Some/Key' }, oldValues).hasChanges(oldValues)).toEqual(true); + expect(params.updateExisting({ Foo: '/Some/Key' }, oldValues).hasChanges(oldValues)).toEqual('ssm'); +}); + +test('if a parameter is retrieved from SSM, the parameters doesnt count as changed if it has the magic marker', () => { + const params = TemplateParameters.fromTemplate({ + Parameters: { + Foo: { + Type: 'AWS::SSM::Parameter::Name', + Default: '/Some/Key', + Description: `blabla ${SSMPARAM_NO_INVALIDATE}`, + }, + }, + }); + const oldValues = { Foo: '/Some/Key' }; + + // If we don't pass a new value + expect(params.updateExisting({}, oldValues).hasChanges(oldValues)).toEqual(false); + + // If we do pass a new value but it's the same as the old one + expect(params.updateExisting({ Foo: '/Some/Key' }, oldValues).hasChanges(oldValues)).toEqual(false); + + // If we do pass a new value and it's different + expect(params.updateExisting({ Foo: '/OTHER/Key' }, oldValues).hasChanges(oldValues)).toEqual(true); }); test('empty string is a valid update value', () => { From 260df31c1117f60a7a92f7845e4e15386225b5c6 Mon Sep 17 00:00:00 2001 From: Nick Lynch Date: Fri, 22 Oct 2021 15:58:15 +0100 Subject: [PATCH 021/148] chore: include RELEASE_NOTES in packed distribution (#17118) We now create and generate a `RELEASE_NOTES.md` file as part of our build, with the intent to use it for our GitHub release publishing. See (#16942) and https://github.com/cdklabs/aws-delivlib/pull/1044. What I missed is that after the build, we pack, and then only include what ends up in `./dist` in the final build artifact that goes to publishing. This fix includes the release notes in the dist folder so it will be picked up and used by the release process. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- pack.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pack.sh b/pack.sh index d270fb28271c5..86c29bacbd48c 100755 --- a/pack.sh +++ b/pack.sh @@ -92,8 +92,9 @@ cat > ${distdir}/build.json < Date: Fri, 22 Oct 2021 19:18:45 +0200 Subject: [PATCH 022/148] chore(codebuild): make examples compile (#17123) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-codebuild/README.md | 81 ++++++++++++------- .../lib/untrusted-code-boundary-policy.ts | 3 +- 2 files changed, 52 insertions(+), 32 deletions(-) diff --git a/packages/@aws-cdk/aws-codebuild/README.md b/packages/@aws-cdk/aws-codebuild/README.md index d4b31c1bf91db..ff73599bca8e4 100644 --- a/packages/@aws-cdk/aws-codebuild/README.md +++ b/packages/@aws-cdk/aws-codebuild/README.md @@ -30,7 +30,7 @@ $ npm i @aws-cdk/aws-codebuild Import it into your code: -```ts +```ts nofixture import * as codebuild from '@aws-cdk/aws-codebuild'; ``` @@ -56,7 +56,6 @@ CodeBuild!`: Use an AWS CodeCommit repository as the source of this build: ```ts -import * as codebuild from '@aws-cdk/aws-codebuild'; import * as codecommit from '@aws-cdk/aws-codecommit'; const repository = new codecommit.Repository(this, 'MyRepo', { repositoryName: 'foo' }); @@ -70,10 +69,8 @@ new codebuild.Project(this, 'MyFirstCodeCommitProject', { Create a CodeBuild project with an S3 bucket as the source: ```ts -import * as codebuild from '@aws-cdk/aws-codebuild'; -import * as s3 from '@aws-cdk/aws-s3'; - const bucket = new s3.Bucket(this, 'MyBucket'); + new codebuild.Project(this, 'MyProject', { source: codebuild.Source.s3({ bucket: bucket, @@ -140,7 +137,9 @@ const gitHubSource = codebuild.Source.gitHub({ CodeBuild Projects can produce Artifacts and upload them to S3. For example: ```ts -const project = codebuild.Project(stack, 'MyProject', { +declare const bucket: s3.Bucket; + +const project = new codebuild.Project(this, 'MyProject', { buildSpec: codebuild.BuildSpec.fromObject({ version: '0.2', }), @@ -193,7 +192,7 @@ new codebuild.Project(this, 'Project', { owner: 'awslabs', repo: 'aws-cdk', }), - cache: codebuild.Cache.bucket(new Bucket(this, 'Bucket')) + cache: codebuild.Cache.bucket(new s3.Bucket(this, 'Bucket')) }); ``` @@ -214,7 +213,7 @@ new codebuild.Project(this, 'Project', { }), // Enable Docker AND custom caching - cache: codebuild.Cache.local(LocalCacheMode.DOCKER_LAYER, LocalCacheMode.CUSTOM) + cache: codebuild.Cache.local(codebuild.LocalCacheMode.DOCKER_LAYER, codebuild.LocalCacheMode.CUSTOM) }); ``` @@ -260,6 +259,8 @@ Note that the `WindowsBuildImage` version of the static methods accepts an optio which can be either `WindowsImageType.STANDARD`, the default, or `WindowsImageType.SERVER_2019`: ```ts +declare const ecrRepository: ecr.Repository; + new codebuild.Project(this, 'Project', { environment: { buildImage: codebuild.WindowsBuildImage.fromEcrRepository(ecrRepository, 'v1.0', codebuild.WindowsImageType.SERVER_2019), @@ -269,7 +270,7 @@ new codebuild.Project(this, 'Project', { objectKey: 'path/to/cert.pem', }, }, - ... + // ... }) ``` @@ -296,7 +297,7 @@ new codebuild.Project(this, 'Project', { environment: { buildImage: codebuild.LinuxGpuBuildImage.DLC_TENSORFLOW_2_1_0_INFERENCE, }, - ... + // ... }) ``` @@ -315,7 +316,7 @@ new codebuild.Project(this, 'Project', { buildImage: codebuild.LinuxGpuBuildImage.awsDeepLearningContainersImage( 'tensorflow-inference', '2.1.0-gpu-py36-cu101-ubuntu18.04', '123456789012'), }, - ... + // ... }) ``` @@ -331,10 +332,9 @@ By default, logs will go to cloudwatch. new codebuild.Project(this, 'Project', { logging: { cloudWatch: { - logGroup: new cloudwatch.LogGroup(this, `MyLogGroup`), + logGroup: new logs.LogGroup(this, `MyLogGroup`), } }, - ... }) ``` @@ -347,7 +347,6 @@ new codebuild.Project(this, 'Project', { bucket: new s3.Bucket(this, `LogBucket`) } }, - ... }) ``` @@ -358,7 +357,7 @@ like GitHub: ```ts new codebuild.GitHubSourceCredentials(this, 'CodeBuildGitHubCreds', { - accessToken: cdk.SecretValue.secretsManager('my-token'), + accessToken: SecretValue.secretsManager('my-token'), }); // GitHub Enterprise is almost the same, // except the class is called GitHubEnterpriseSourceCredentials @@ -368,8 +367,8 @@ and BitBucket: ```ts new codebuild.BitBucketSourceCredentials(this, 'CodeBuildBitBucketCreds', { - username: cdk.SecretValue.secretsManager('my-bitbucket-creds', { jsonField: 'username' }), - password: cdk.SecretValue.secretsManager('my-bitbucket-creds', { jsonField: 'password' }), + username: SecretValue.secretsManager('my-bitbucket-creds', { jsonField: 'username' }), + password: SecretValue.secretsManager('my-bitbucket-creds', { jsonField: 'password' }), }); ``` @@ -409,8 +408,10 @@ if you'd rather not have those permissions added, you can opt out of it when creating the project: ```ts +declare const source: codebuild.Source; + const project = new codebuild.Project(this, 'Project', { - // ... + source, grantReportGroupPermissions: false, }); ``` @@ -419,10 +420,13 @@ Alternatively, you can specify an ARN of an existing resource group, instead of a simple name, in your buildspec: ```ts +declare const source: codebuild.Source; + // create a new ReportGroup const reportGroup = new codebuild.ReportGroup(this, 'ReportGroup'); const project = new codebuild.Project(this, 'Project', { + source, buildSpec: codebuild.BuildSpec.fromObject({ // ... reports: { @@ -438,6 +442,9 @@ const project = new codebuild.Project(this, 'Project', { If you do that, you need to grant the project's role permissions to write reports to that report group: ```ts +declare const project: codebuild.Project; +declare const reportGroup: codebuild.ReportGroup; + reportGroup.grantWrite(project); ``` @@ -456,8 +463,12 @@ project as a AWS CloudWatch event rule target: ```ts // start build when a commit is pushed +import * as codecommit from '@aws-cdk/aws-codecommit'; import * as targets from '@aws-cdk/aws-events-targets'; +declare const codeCommitRepository: codecommit.Repository; +declare const project: codebuild.Project; + codeCommitRepository.onCommit('OnCommit', { target: new targets.CodeBuildProject(project), }); @@ -469,6 +480,10 @@ To define Amazon CloudWatch event rules for build projects, use one of the `onXx methods: ```ts +import * as targets from '@aws-cdk/aws-events-targets'; +declare const fn: lambda.Function; +declare const project: codebuild.Project; + const rule = project.onStateChange('BuildStateChange', { target: new targets.LambdaFunction(fn) }); @@ -480,7 +495,11 @@ To define CodeStar Notification rules for Projects, use one of the `notifyOnXxx( They are very similar to `onXxx()` methods for CloudWatch events: ```ts -const target = new chatbot.SlackChannelConfiguration(stack, 'MySlackChannel', { +import * as chatbot from '@aws-cdk/aws-chatbot'; + +declare const project: codebuild.Project; + +const target = new chatbot.SlackChannelConfiguration(this, 'MySlackChannel', { slackChannelConfigurationName: 'YOUR_CHANNEL_NAME', slackWorkspaceId: 'YOUR_SLACK_WORKSPACE_ID', slackChannelId: 'YOUR_SLACK_CHANNEL_ID', @@ -495,6 +514,10 @@ CodeBuild Projects can get their sources from multiple places, and produce multiple outputs. For example: ```ts +import * as codecommit from '@aws-cdk/aws-codecommit'; +declare const repo: codecommit.Repository; +declare const bucket: s3.Bucket; + const project = new codebuild.Project(this, 'MyProject', { secondarySources: [ codebuild.Source.codeCommit({ @@ -586,6 +609,8 @@ to access the resources that it needs by using the For example: ```ts +declare const loadBalancer: elbv2.ApplicationLoadBalancer; + const vpc = new ec2.Vpc(this, 'MyVPC'); const project = new codebuild.Project(this, 'MyProject', { vpc: vpc, @@ -608,7 +633,7 @@ The only supported file system type is `EFS`. For example: ```ts -new codebuild.Project(stack, 'MyProject', { +new codebuild.Project(this, 'MyProject', { buildSpec: codebuild.BuildSpec.fromObject({ version: '0.2', }), @@ -635,9 +660,9 @@ It returns an object containing the batch service role that was created, or `undefined` if batch builds could not be enabled, for example if the project was imported. ```ts -import * as codebuild from '@aws-cdk/aws-codebuild'; +declare const source: codebuild.Source; -const project = new codebuild.Project(this, 'MyProject', { ... }); +const project = new codebuild.Project(this, 'MyProject', { source, }); if (project.enableBatchBuilds()) { console.log('Batch builds were enabled'); @@ -652,9 +677,7 @@ The default is 60 minutes. An example of overriding the default follows. ```ts -import * as codebuild from '@aws-cdk/aws-codebuild'; - -new codebuild.Project(stack, 'MyProject', { +new codebuild.Project(this, 'MyProject', { timeout: Duration.minutes(90) }); ``` @@ -665,9 +688,7 @@ As an example, to allow your Project to queue for up to thirty (30) minutes befo use the following code. ```ts -import * as codebuild from '@aws-cdk/aws-codebuild'; - -new codebuild.Project(stack, 'MyProject', { +new codebuild.Project(this, 'MyProject', { queuedTimeout: Duration.minutes(30) }); ``` @@ -679,9 +700,7 @@ It is possible to limit the maximum concurrent builds to value between 1 and the By default there is no explicit limit. ```ts -import * as codebuild from '@aws-cdk/aws-codebuild'; - -new codebuild.Project(stack, 'MyProject', { +new codebuild.Project(this, 'MyProject', { concurrentBuildLimit: 1 }); ``` diff --git a/packages/@aws-cdk/aws-codebuild/lib/untrusted-code-boundary-policy.ts b/packages/@aws-cdk/aws-codebuild/lib/untrusted-code-boundary-policy.ts index 229cb547e7c1f..1a94c521fc08a 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/untrusted-code-boundary-policy.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/untrusted-code-boundary-policy.ts @@ -39,7 +39,8 @@ export interface UntrustedCodeBoundaryPolicyProps { * * @example * - * iam.PermissionsBoundary.of(project).apply(new UntrustedCodeBoundaryPolicy(this, 'Boundary')); + * declare const project: codebuild.Project; + * iam.PermissionsBoundary.of(project).apply(new codebuild.UntrustedCodeBoundaryPolicy(this, 'Boundary')); */ export class UntrustedCodeBoundaryPolicy extends iam.ManagedPolicy { constructor(scope: Construct, id: string, props: UntrustedCodeBoundaryPolicyProps = {}) { From 06838e66db0c9a48e2aa7da1e7707fda335bb62c Mon Sep 17 00:00:00 2001 From: Tatsuya Yamamoto Date: Sat, 23 Oct 2021 03:41:59 +0900 Subject: [PATCH 023/148] feat(iot): create new aws-iot-actions module (#17112) I'm trying to implement aws-iot L2 Constructs. This PR is the next step of #16681 refar: - https://github.com/aws/aws-cdk/pull/16681#discussion_r733912215 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-iot-actions/.eslintrc.js | 3 + packages/@aws-cdk/aws-iot-actions/.gitignore | 19 ++ packages/@aws-cdk/aws-iot-actions/.npmignore | 28 +++ packages/@aws-cdk/aws-iot-actions/LICENSE | 201 ++++++++++++++++++ packages/@aws-cdk/aws-iot-actions/NOTICE | 2 + packages/@aws-cdk/aws-iot-actions/README.md | 20 ++ .../@aws-cdk/aws-iot-actions/jest.config.js | 2 + .../@aws-cdk/aws-iot-actions/lib/index.ts | 2 + .../@aws-cdk/aws-iot-actions/package.json | 97 +++++++++ packages/aws-cdk-lib/package.json | 1 + packages/decdk/package.json | 1 + packages/monocdk/package.json | 1 + 12 files changed, 377 insertions(+) create mode 100644 packages/@aws-cdk/aws-iot-actions/.eslintrc.js create mode 100644 packages/@aws-cdk/aws-iot-actions/.gitignore create mode 100644 packages/@aws-cdk/aws-iot-actions/.npmignore create mode 100644 packages/@aws-cdk/aws-iot-actions/LICENSE create mode 100644 packages/@aws-cdk/aws-iot-actions/NOTICE create mode 100644 packages/@aws-cdk/aws-iot-actions/README.md create mode 100644 packages/@aws-cdk/aws-iot-actions/jest.config.js create mode 100644 packages/@aws-cdk/aws-iot-actions/lib/index.ts create mode 100644 packages/@aws-cdk/aws-iot-actions/package.json diff --git a/packages/@aws-cdk/aws-iot-actions/.eslintrc.js b/packages/@aws-cdk/aws-iot-actions/.eslintrc.js new file mode 100644 index 0000000000000..2658ee8727166 --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/.eslintrc.js @@ -0,0 +1,3 @@ +const baseConfig = require('@aws-cdk/cdk-build-tools/config/eslintrc'); +baseConfig.parserOptions.project = __dirname + '/tsconfig.json'; +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-iot-actions/.gitignore b/packages/@aws-cdk/aws-iot-actions/.gitignore new file mode 100644 index 0000000000000..d8a8561d50885 --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/.gitignore @@ -0,0 +1,19 @@ +*.js +*.js.map +*.d.ts +tsconfig.json +node_modules +*.generated.ts +dist +.jsii + +.LAST_BUILD +.nyc_output +coverage +nyc.config.js +.LAST_PACKAGE +*.snk +!.eslintrc.js +!jest.config.js + +junit.xml \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iot-actions/.npmignore b/packages/@aws-cdk/aws-iot-actions/.npmignore new file mode 100644 index 0000000000000..aaabf1df59065 --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/.npmignore @@ -0,0 +1,28 @@ +# Don't include original .ts files when doing `npm pack` +*.ts +!*.d.ts +coverage +.nyc_output +*.tgz + +dist +.LAST_PACKAGE +.LAST_BUILD +!*.js + +# Include .jsii +!.jsii + +*.snk + +*.tsbuildinfo + +tsconfig.json +.eslintrc.js +jest.config.js + +# exclude cdk artifacts +**/cdk.out +junit.xml +test/ +!*.lit.ts \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iot-actions/LICENSE b/packages/@aws-cdk/aws-iot-actions/LICENSE new file mode 100644 index 0000000000000..28e4bdcec77ec --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/@aws-cdk/aws-iot-actions/NOTICE b/packages/@aws-cdk/aws-iot-actions/NOTICE new file mode 100644 index 0000000000000..5fc3826926b5b --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/NOTICE @@ -0,0 +1,2 @@ +AWS Cloud Development Kit (AWS CDK) +Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/packages/@aws-cdk/aws-iot-actions/README.md b/packages/@aws-cdk/aws-iot-actions/README.md new file mode 100644 index 0000000000000..1c098d25eb3de --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/README.md @@ -0,0 +1,20 @@ +# Actions for AWS IoT Rule + + +--- + +![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge) + +> The APIs of higher level constructs in this module are experimental and under active development. +> They are subject to non-backward compatible changes or removal in any future version. These are +> not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be +> announced in the release notes. This means that while you may use them, you may need to update +> your source code when upgrading to a newer version of this package. + +--- + + + +This library contains integration classes to send data to any number of +supported AWS Services. Instances of these classes should be passed to +`TopicRule` defined in `@aws-cdk/aws-iot`. diff --git a/packages/@aws-cdk/aws-iot-actions/jest.config.js b/packages/@aws-cdk/aws-iot-actions/jest.config.js new file mode 100644 index 0000000000000..3a2fd93a1228a --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/jest.config.js @@ -0,0 +1,2 @@ +const baseConfig = require('@aws-cdk/cdk-build-tools/config/jest.config'); +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-iot-actions/lib/index.ts b/packages/@aws-cdk/aws-iot-actions/lib/index.ts new file mode 100644 index 0000000000000..3e4b0ef0a73d4 --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/lib/index.ts @@ -0,0 +1,2 @@ +// this is placeholder for monocdk +export const dummy = true; diff --git a/packages/@aws-cdk/aws-iot-actions/package.json b/packages/@aws-cdk/aws-iot-actions/package.json new file mode 100644 index 0000000000000..76878637e0430 --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/package.json @@ -0,0 +1,97 @@ +{ + "name": "@aws-cdk/aws-iot-actions", + "version": "0.0.0", + "description": "Receipt rule actions for AWS IoT", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "jsii": { + "outdir": "dist", + "targets": { + "java": { + "package": "software.amazon.awscdk.services.iot.actions", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "iot-actions" + } + }, + "dotnet": { + "namespace": "Amazon.CDK.AWS.IoT.Actions", + "packageId": "Amazon.CDK.AWS.IoT.Actions", + "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png" + }, + "python": { + "distName": "aws-cdk.aws-iot-actions", + "module": "aws_cdk.aws_iot_actions", + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ] + } + }, + "projectReferences": true + }, + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-cdk.git", + "directory": "packages/@aws-cdk/aws-iot-actions" + }, + "scripts": { + "build": "cdk-build", + "watch": "cdk-watch", + "lint": "cdk-lint", + "test": "cdk-test", + "integ": "cdk-integ", + "pkglint": "pkglint -f", + "package": "cdk-package", + "awslint": "cdk-awslint", + "build+test+package": "yarn build+test && yarn package", + "build+test": "yarn build && yarn test", + "compat": "cdk-compat", + "rosetta:extract": "yarn --silent jsii-rosetta extract", + "build+extract": "yarn build && yarn rosetta:extract", + "build+test+extract": "yarn build+test && yarn rosetta:extract" + }, + "cdk-build": { + "env": { + "AWSLINT_BASE_CONSTRUCT": true + } + }, + "keywords": [ + "aws", + "cdk", + "constructs", + "iot", + "actions" + ], + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@aws-cdk/assertions": "0.0.0", + "@aws-cdk/cdk-build-tools": "0.0.0", + "@aws-cdk/cdk-integ-tools": "0.0.0", + "@aws-cdk/pkglint": "0.0.0", + "@types/jest": "^26.0.24", + "constructs": "^3.3.69", + "jest": "^26.6.3" + }, + "dependencies": { + }, + "homepage": "https://github.com/aws/aws-cdk", + "peerDependencies": { + }, + "engines": { + "node": ">= 10.13.0 <13 || >=13.7.0" + }, + "stability": "experimental", + "maturity": "experimental", + "awscdkio": { + "announce": false + }, + "publishConfig": { + "tag": "latest" + } +} diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json index ad2aeeace6cd1..de4d8379cac35 100644 --- a/packages/aws-cdk-lib/package.json +++ b/packages/aws-cdk-lib/package.json @@ -231,6 +231,7 @@ "@aws-cdk/aws-imagebuilder": "0.0.0", "@aws-cdk/aws-inspector": "0.0.0", "@aws-cdk/aws-iot": "0.0.0", + "@aws-cdk/aws-iot-actions": "0.0.0", "@aws-cdk/aws-iot1click": "0.0.0", "@aws-cdk/aws-iotanalytics": "0.0.0", "@aws-cdk/aws-iotcoredeviceadvisor": "0.0.0", diff --git a/packages/decdk/package.json b/packages/decdk/package.json index 8a87b4a7001f8..6a0a0eb5c0baa 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -134,6 +134,7 @@ "@aws-cdk/aws-imagebuilder": "0.0.0", "@aws-cdk/aws-inspector": "0.0.0", "@aws-cdk/aws-iot": "0.0.0", + "@aws-cdk/aws-iot-actions": "0.0.0", "@aws-cdk/aws-iot1click": "0.0.0", "@aws-cdk/aws-iotanalytics": "0.0.0", "@aws-cdk/aws-iotcoredeviceadvisor": "0.0.0", diff --git a/packages/monocdk/package.json b/packages/monocdk/package.json index 526eb3ce967b3..7e0b967fe70ab 100644 --- a/packages/monocdk/package.json +++ b/packages/monocdk/package.json @@ -228,6 +228,7 @@ "@aws-cdk/aws-imagebuilder": "0.0.0", "@aws-cdk/aws-inspector": "0.0.0", "@aws-cdk/aws-iot": "0.0.0", + "@aws-cdk/aws-iot-actions": "0.0.0", "@aws-cdk/aws-iot1click": "0.0.0", "@aws-cdk/aws-iotanalytics": "0.0.0", "@aws-cdk/aws-iotcoredeviceadvisor": "0.0.0", From 924045daad403b7814bedc536675c37e00e2bf53 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Sat, 23 Oct 2021 16:16:26 +0200 Subject: [PATCH 024/148] chore(codebuild): add forgotten rosetta fixture (#17129) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-codebuild/rosetta/default.ts-fixture | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 packages/@aws-cdk/aws-codebuild/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-codebuild/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-codebuild/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..12926b4e95060 --- /dev/null +++ b/packages/@aws-cdk/aws-codebuild/rosetta/default.ts-fixture @@ -0,0 +1,19 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { Stack, Duration, SecretValue } from '@aws-cdk/core'; +import codebuild = require('@aws-cdk/aws-codebuild'); +import iam = require('@aws-cdk/aws-iam'); +import ec2 = require('@aws-cdk/aws-ec2'); +import lambda = require('@aws-cdk/aws-lambda'); +import * as s3 from '@aws-cdk/aws-s3'; +import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2'; +import * as ecr from '@aws-cdk/aws-ecr'; +import * as logs from '@aws-cdk/aws-logs'; + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} From ab627c69e9edac82b1fd07d2c9ee1b05f7dc3166 Mon Sep 17 00:00:00 2001 From: Adam Ruka Date: Mon, 25 Oct 2021 02:44:42 -0700 Subject: [PATCH 025/148] fix(rds): using both Instance imports & exports for Postgres fails deployment (#17060) Our CDK code was assuming that all instance engines that support S3 imports & exports must use the same Role if both functions are enabled at the same time. However, it turns out that's true only for Oracle and SQL Server, but not for Postgres - in fact, Postgres has the exact opposite requirement, and will fail deployment if the same Role is used for both. Change our code to only use a single Role if the engine is Oracle or SQL Server. Fixes #16757 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-rds/lib/cluster.ts | 2 +- packages/@aws-cdk/aws-rds/lib/instance.ts | 13 +- packages/@aws-cdk/aws-rds/lib/private/util.ts | 4 +- .../integ.instance-s3-postgres.expected.json | 601 ++++++++++++++++++ .../test/integ.instance-s3-postgres.ts | 20 + 5 files changed, 631 insertions(+), 9 deletions(-) create mode 100644 packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.expected.json create mode 100644 packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.ts diff --git a/packages/@aws-cdk/aws-rds/lib/cluster.ts b/packages/@aws-cdk/aws-rds/lib/cluster.ts index ad5a2201c759c..15f9e60215ebc 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster.ts @@ -327,7 +327,7 @@ abstract class DatabaseClusterNew extends DatabaseClusterBase { }), ]; - let { s3ImportRole, s3ExportRole } = setupS3ImportExport(this, props); + let { s3ImportRole, s3ExportRole } = setupS3ImportExport(this, props, /* combineRoles */ false); // bind the engine to the Cluster const clusterEngineBindConfig = props.engine.bindToCluster(this, { s3ImportRole, diff --git a/packages/@aws-cdk/aws-rds/lib/instance.ts b/packages/@aws-cdk/aws-rds/lib/instance.ts index 8d285b7375006..3349d15fb5c97 100644 --- a/packages/@aws-cdk/aws-rds/lib/instance.ts +++ b/packages/@aws-cdk/aws-rds/lib/instance.ts @@ -576,7 +576,6 @@ export interface DatabaseInstanceNewProps { /** * Role that will be associated with this DB instance to enable S3 export. - * This feature is only supported by the Microsoft SQL Server and Oracle engines. * * This property must not be used if `s3ExportBuckets` is used. * @@ -591,7 +590,6 @@ export interface DatabaseInstanceNewProps { /** * S3 buckets that you want to load data into. - * This feature is only supported by the Microsoft SQL Server and Oracle engines. * * This property must not be used if `s3ExportRole` is used. * @@ -847,7 +845,10 @@ abstract class DatabaseInstanceSource extends DatabaseInstanceNew implements IDa this.multiUserRotationApplication = props.engine.multiUserRotationApplication; this.engine = props.engine; - let { s3ImportRole, s3ExportRole } = setupS3ImportExport(this, props, true); + const engineType = props.engine.engineType; + // only Oracle and SQL Server require the import and export Roles to be the same + const combineRoles = engineType.startsWith('oracle-') || engineType.startsWith('sqlserver-'); + let { s3ImportRole, s3ExportRole } = setupS3ImportExport(this, props, combineRoles); const engineConfig = props.engine.bindToInstance(this, { ...props, s3ImportRole, @@ -866,8 +867,8 @@ abstract class DatabaseInstanceSource extends DatabaseInstanceNew implements IDa if (!engineFeatures?.s3Export) { throw new Error(`Engine '${engineDescription(props.engine)}' does not support S3 export`); } - // Only add the export role and feature if they are different from the import role & feature. - if (s3ImportRole !== s3ExportRole || engineFeatures.s3Import !== engineFeatures?.s3Export) { + // only add the export feature if it's different from the import feature + if (engineFeatures.s3Import !== engineFeatures?.s3Export) { instanceAssociatedRoles.push({ roleArn: s3ExportRole.roleArn, featureName: engineFeatures?.s3Export }); } } @@ -883,7 +884,7 @@ abstract class DatabaseInstanceSource extends DatabaseInstanceNew implements IDa allowMajorVersionUpgrade: props.allowMajorVersionUpgrade, dbName: props.databaseName, dbParameterGroupName: instanceParameterGroupConfig?.parameterGroupName, - engine: props.engine.engineType, + engine: engineType, engineVersion: props.engine.engineVersion?.fullVersion, licenseModel: props.licenseModel, timezone: props.timezone, diff --git a/packages/@aws-cdk/aws-rds/lib/private/util.ts b/packages/@aws-cdk/aws-rds/lib/private/util.ts index c142a903bad7a..1664647c92bd8 100644 --- a/packages/@aws-cdk/aws-rds/lib/private/util.ts +++ b/packages/@aws-cdk/aws-rds/lib/private/util.ts @@ -31,14 +31,14 @@ export interface DatabaseS3ImportExportProps { * Validates the S3 import/export props and returns the import/export roles, if any. * If `combineRoles` is true, will reuse the import role for export (or vice versa) if possible. * - * Notably, `combineRoles` is (by default) set to true for instances, but false for clusters. + * Notably, `combineRoles` is set to true for instances, but false for clusters. * This is because the `combineRoles` functionality is most applicable to instances and didn't exist * for the initial clusters implementation. To maintain backwards compatibility, it is set to false for clusters. */ export function setupS3ImportExport( scope: Construct, props: DatabaseS3ImportExportProps, - combineRoles?: boolean): { s3ImportRole?: iam.IRole, s3ExportRole?: iam.IRole } { + combineRoles: boolean): { s3ImportRole?: iam.IRole, s3ExportRole?: iam.IRole } { let s3ImportRole = props.s3ImportRole; let s3ExportRole = props.s3ExportRole; diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.expected.json b/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.expected.json new file mode 100644 index 0000000000000..2a55df00bab2c --- /dev/null +++ b/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.expected.json @@ -0,0 +1,601 @@ +{ + "Resources": { + "VPCB9E5F0B4": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-rds-instance-s3-postgres-integ/VPC" + } + ] + } + }, + "VPCPublicSubnet1SubnetB4246D30": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.0.0/18", + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "aws-cdk-rds-instance-s3-postgres-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1RouteTableFEE4B781": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-rds-instance-s3-postgres-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1RouteTableAssociation0B0896DC": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "VPCPublicSubnet1DefaultRoute91CEF279": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet1EIP6AD938E8": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-rds-instance-s3-postgres-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1NATGatewayE0556630": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-rds-instance-s3-postgres-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet2Subnet74179F39": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.64.0/18", + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1b", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "aws-cdk-rds-instance-s3-postgres-integ/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2RouteTable6F1A15F1": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-rds-instance-s3-postgres-integ/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2RouteTableAssociation5A808732": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "VPCPublicSubnet2DefaultRouteB7481BBA": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPrivateSubnet1Subnet8BCA10E0": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.128.0/18", + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "aws-cdk-rds-instance-s3-postgres-integ/VPC/PrivateSubnet1" + } + ] + } + }, + "VPCPrivateSubnet1RouteTableBE8A6027": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-rds-instance-s3-postgres-integ/VPC/PrivateSubnet1" + } + ] + } + }, + "VPCPrivateSubnet1RouteTableAssociation347902D1": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "VPCPrivateSubnet1DefaultRouteAE1D6490": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + } + } + }, + "VPCPrivateSubnet2SubnetCFCDAA7A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.192.0/18", + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "AvailabilityZone": "test-region-1b", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "aws-cdk-rds-instance-s3-postgres-integ/VPC/PrivateSubnet2" + } + ] + } + }, + "VPCPrivateSubnet2RouteTable0A19E10E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-rds-instance-s3-postgres-integ/VPC/PrivateSubnet2" + } + ] + } + }, + "VPCPrivateSubnet2RouteTableAssociation0C73D413": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "VPCPrivateSubnet2DefaultRouteF4F5CFD2": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + } + } + }, + "VPCIGWB7E252D3": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-rds-instance-s3-postgres-integ/VPC" + } + ] + } + }, + "VPCVPCGW99B986DC": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "VPCB9E5F0B4" + }, + "InternetGatewayId": { + "Ref": "VPCIGWB7E252D3" + } + } + }, + "ImportBucketBAF3A8E9": { + "Type": "AWS::S3::Bucket", + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ExportBucket4E99310E": { + "Type": "AWS::S3::Bucket", + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "InstanceSubnetGroupF2CBA54F": { + "Type": "AWS::RDS::DBSubnetGroup", + "Properties": { + "DBSubnetGroupDescription": "Subnet group for Instance database", + "SubnetIds": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ] + } + }, + "InstanceSecurityGroupB4E5FA83": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Security group for Instance database", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "InstanceS3ImportRole30959D06": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "rds.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "InstanceS3ImportRoleDefaultPolicy297F292A": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "ImportBucketBAF3A8E9", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "ImportBucketBAF3A8E9", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "InstanceS3ImportRoleDefaultPolicy297F292A", + "Roles": [ + { + "Ref": "InstanceS3ImportRole30959D06" + } + ] + } + }, + "InstanceS3ExportRole9891C2F7": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "rds.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "InstanceS3ExportRoleDefaultPolicy62C930BC": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*", + "s3:DeleteObject*", + "s3:PutObject", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "ExportBucket4E99310E", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "ExportBucket4E99310E", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "InstanceS3ExportRoleDefaultPolicy62C930BC", + "Roles": [ + { + "Ref": "InstanceS3ExportRole9891C2F7" + } + ] + } + }, + "InstanceSecret478E0A47": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "Description": { + "Fn::Join": [ + "", + [ + "Generated by the CDK for stack: ", + { + "Ref": "AWS::StackName" + } + ] + ] + }, + "GenerateSecretString": { + "ExcludeCharacters": " %+~`#$&*()|[]{}:;<>?!'/@\"\\", + "GenerateStringKey": "password", + "PasswordLength": 30, + "SecretStringTemplate": "{\"username\":\"postgres\"}" + } + } + }, + "InstanceSecretAttachment83BEE581": { + "Type": "AWS::SecretsManager::SecretTargetAttachment", + "Properties": { + "SecretId": { + "Ref": "InstanceSecret478E0A47" + }, + "TargetId": { + "Ref": "InstanceC1063A87" + }, + "TargetType": "AWS::RDS::DBInstance" + } + }, + "InstanceC1063A87": { + "Type": "AWS::RDS::DBInstance", + "Properties": { + "DBInstanceClass": "db.m5.large", + "AllocatedStorage": "100", + "AssociatedRoles": [ + { + "FeatureName": "s3Import", + "RoleArn": { + "Fn::GetAtt": [ + "InstanceS3ImportRole30959D06", + "Arn" + ] + } + }, + { + "FeatureName": "s3Export", + "RoleArn": { + "Fn::GetAtt": [ + "InstanceS3ExportRole9891C2F7", + "Arn" + ] + } + } + ], + "CopyTagsToSnapshot": true, + "DBSubnetGroupName": { + "Ref": "InstanceSubnetGroupF2CBA54F" + }, + "EnableIAMDatabaseAuthentication": true, + "Engine": "postgres", + "EngineVersion": "11.12", + "MasterUsername": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "InstanceSecret478E0A47" + }, + ":SecretString:username::}}" + ] + ] + }, + "MasterUserPassword": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "InstanceSecret478E0A47" + }, + ":SecretString:password::}}" + ] + ] + }, + "MultiAZ": false, + "PubliclyAccessible": true, + "StorageType": "gp2", + "VPCSecurityGroups": [ + { + "Fn::GetAtt": [ + "InstanceSecurityGroupB4E5FA83", + "GroupId" + ] + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.ts b/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.ts new file mode 100644 index 0000000000000..e07501039549b --- /dev/null +++ b/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.ts @@ -0,0 +1,20 @@ +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as s3 from '@aws-cdk/aws-s3'; +import * as cdk from '@aws-cdk/core'; +import * as rds from '../lib'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-cdk-rds-instance-s3-postgres-integ'); + +new rds.DatabaseInstance(stack, 'Instance', { + engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_11_12 }), + vpc: new ec2.Vpc(stack, 'VPC', { maxAzs: 2, natGateways: 1 }), + multiAz: false, + publiclyAccessible: true, + iamAuthentication: true, + s3ImportBuckets: [new s3.Bucket(stack, 'ImportBucket', { removalPolicy: cdk.RemovalPolicy.DESTROY })], + s3ExportBuckets: [new s3.Bucket(stack, 'ExportBucket', { removalPolicy: cdk.RemovalPolicy.DESTROY })], + removalPolicy: cdk.RemovalPolicy.DESTROY, +}); + +app.synth(); From e063fbd3a31bdce046b2598e4a429c45d016f055 Mon Sep 17 00:00:00 2001 From: flemjame-at-amazon <57235867+flemjame-at-amazon@users.noreply.github.com> Date: Mon, 25 Oct 2021 09:47:16 -0400 Subject: [PATCH 026/148] feat(route53): Expose VpcEndpointServiceDomainName domain name as a property (#16458) I want to be able to read the domain name associated with the object. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/vpc-endpoint-service-domain-name.ts | 11 ++++++++--- .../vpc-endpoint-service-domain-name.test.ts | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-route53/lib/vpc-endpoint-service-domain-name.ts b/packages/@aws-cdk/aws-route53/lib/vpc-endpoint-service-domain-name.ts index 9098503b625f4..862a63e26e6d1 100644 --- a/packages/@aws-cdk/aws-route53/lib/vpc-endpoint-service-domain-name.ts +++ b/packages/@aws-cdk/aws-route53/lib/vpc-endpoint-service-domain-name.ts @@ -46,6 +46,11 @@ export class VpcEndpointServiceDomainName extends CoreConstruct { // Track all domain names created, so someone doesn't accidentally associate two domains with a single service private static readonly endpointServicesMap: { [endpointService: string]: string} = {}; + /** + * The domain name associated with the private DNS configuration + */ + public domainName: string; + // The way this class works is by using three custom resources and a TxtRecord in conjunction // The first custom resource tells the VPC endpoint service to use the given DNS name // The VPC endpoint service will then say: @@ -58,16 +63,16 @@ export class VpcEndpointServiceDomainName extends CoreConstruct { const serviceUniqueId = Names.nodeUniqueId(props.endpointService.node); const serviceId = props.endpointService.vpcEndpointServiceId; - const privateDnsName = props.domainName; + this.domainName = props.domainName; // Make sure a user doesn't accidentally add multiple domains this.validateProps(props); - VpcEndpointServiceDomainName.endpointServicesMap[serviceUniqueId] = privateDnsName; + VpcEndpointServiceDomainName.endpointServicesMap[serviceUniqueId] = this.domainName; VpcEndpointServiceDomainName.endpointServices.push(props.endpointService); // Enable Private DNS on the endpoint service and retrieve the AWS-generated configuration - const privateDnsConfiguration = this.getPrivateDnsConfiguration(serviceUniqueId, serviceId, privateDnsName); + const privateDnsConfiguration = this.getPrivateDnsConfiguration(serviceUniqueId, serviceId, this.domainName); // Tell AWS to verify that this account owns the domain attached to the service this.verifyPrivateDnsConfiguration(privateDnsConfiguration, props.publicHostedZone); diff --git a/packages/@aws-cdk/aws-route53/test/vpc-endpoint-service-domain-name.test.ts b/packages/@aws-cdk/aws-route53/test/vpc-endpoint-service-domain-name.test.ts index 35b7ac9c67596..506a25e2a26df 100644 --- a/packages/@aws-cdk/aws-route53/test/vpc-endpoint-service-domain-name.test.ts +++ b/packages/@aws-cdk/aws-route53/test/vpc-endpoint-service-domain-name.test.ts @@ -264,4 +264,20 @@ test('throws if creating multiple domains for a single service', () => { publicHostedZone: zone, }); }).toThrow(/Cannot create a VpcEndpointServiceDomainName for service/); +}); + + +test('endpoint domain name property equals input domain name', () => { + // GIVEN + vpces = new VpcEndpointService(stack, 'NameTest', { + vpcEndpointServiceLoadBalancers: [nlb], + }); + + const dn = new VpcEndpointServiceDomainName(stack, 'EndpointDomain', { + endpointService: vpces, + domainName: 'name-test.aws-cdk.dev', + publicHostedZone: zone, + }); + expect(dn.domainName).toEqual('name-test.aws-cdk.dev'); + }); \ No newline at end of file From f1e244b331f95253030bae0525775683b5a350c4 Mon Sep 17 00:00:00 2001 From: Mina Asham Date: Mon, 25 Oct 2021 16:43:16 +0200 Subject: [PATCH 027/148] feat(ec2): look up VPC from different regions (#16728) - Currently Vpc.fromLookup will default to the Stack's region, when needing to lookup Stack's from other regions (e.g. for VPC peering) this doesn't work and the only other work around is a custom resource - The lookup provider already supports passing a region and works fine if you pass one that's not the Stack's inferred region, so just propagate that option to the top level - Fixes #10208 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-ec2/lib/vpc-lookup.ts | 7 +++++++ packages/@aws-cdk/aws-ec2/lib/vpc.ts | 6 ++++++ .../aws-ec2/test/vpc.from-lookup.test.ts | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-lookup.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-lookup.ts index 3f9f49dba2540..8db845763dd0e 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-lookup.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-lookup.ts @@ -48,4 +48,11 @@ export interface VpcLookupOptions { * @default aws-cdk:subnet-name */ readonly subnetGroupNameTag?: string; + + /** + * Optional to override inferred region + * + * @default Current stack's environment region + */ + readonly region?: string; } diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index b8194eb161c1d..64f3bb46f14c8 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -1118,9 +1118,15 @@ export class Vpc extends VpcBase { filter.isDefault = options.isDefault ? 'true' : 'false'; } + const overrides: {[key: string]: string} = {}; + if (options.region) { + overrides.region = options.region; + } + const attributes: cxapi.VpcContextResponse = ContextProvider.getValue(scope, { provider: cxschema.ContextProvider.VPC_PROVIDER, props: { + ...overrides, filter, returnAsymmetricSubnets: true, subnetGroupNameTag: options.subnetGroupNameTag, diff --git a/packages/@aws-cdk/aws-ec2/test/vpc.from-lookup.test.ts b/packages/@aws-cdk/aws-ec2/test/vpc.from-lookup.test.ts index 4ad08203a525e..30c0ab1cf2a80 100644 --- a/packages/@aws-cdk/aws-ec2/test/vpc.from-lookup.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc.from-lookup.test.ts @@ -250,6 +250,24 @@ describe('vpc from lookup', () => { restoreContextProvider(previous); }); + test('passes account and region', () => { + const previous = mockVpcContextProviderWith({ + vpcId: 'vpc-1234', + subnetGroups: [], + }, options => { + expect(options.region).toEqual('region-1234'); + }); + + const stack = new Stack(); + const vpc = Vpc.fromLookup(stack, 'Vpc', { + vpcId: 'vpc-1234', + region: 'region-1234', + }); + + expect(vpc.vpcId).toEqual('vpc-1234'); + + restoreContextProvider(previous); + }); }); }); From 8d0c555d048c07518c89e69951a1e9f21ba99bd7 Mon Sep 17 00:00:00 2001 From: Naseem <24660299+naseemkullah@users.noreply.github.com> Date: Mon, 25 Oct 2021 11:36:21 -0400 Subject: [PATCH 028/148] feat(cloudfront): add amplify managed cache policy (#16880) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-cloudfront/lib/cache-policy.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-cloudfront/lib/cache-policy.ts b/packages/@aws-cdk/aws-cloudfront/lib/cache-policy.ts index d0dad353a8727..533ccbd5d78b9 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/cache-policy.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/cache-policy.ts @@ -85,9 +85,13 @@ export interface CachePolicyProps { * A Cache Policy configuration. * * @resource AWS::CloudFront::CachePolicy + * @link https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-cache-policies.html */ export class CachePolicy extends Resource implements ICachePolicy { - + /** + * This policy is designed for use with an origin that is an AWS Amplify web app. + */ + public static readonly AMPLIFY = CachePolicy.fromManagedCachePolicy('2e54312d-136d-493c-8eb9-b001f22f67d2'); /** * Optimize cache efficiency by minimizing the values that CloudFront includes in the cache key. * Query strings and cookies are not included in the cache key, and only the normalized 'Accept-Encoding' header is included. From 7b31376e6349440f7b215d6e11c3dd900d50df34 Mon Sep 17 00:00:00 2001 From: Lukas Fruntke Date: Mon, 25 Oct 2021 18:28:33 +0200 Subject: [PATCH 029/148] feat(ec2): add vpcArn to IVpc and Vpc (#16666) fixes #16493 introduces context aware ARN for VPC, dervied from the current stack. This allows easier referencing compared to constructing the ARN from the vpc id. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-ec2/README.md | 2 +- packages/@aws-cdk/aws-ec2/lib/vpc.ts | 35 +++++++++++++++++++++- packages/@aws-cdk/aws-ec2/test/vpc.test.ts | 7 ++++- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2/README.md b/packages/@aws-cdk/aws-ec2/README.md index eecc6f3857da4..7b00a026bf871 100644 --- a/packages/@aws-cdk/aws-ec2/README.md +++ b/packages/@aws-cdk/aws-ec2/README.md @@ -744,7 +744,7 @@ By default, a new security group is created and logging is enabled. Moreover, a authorize all users to the VPC CIDR is created. To customize authorization rules, set the `authorizeAllUsersToVpcCidr` prop to `false` -and use `addaddAuthorizationRule()`: +and use `addAuthorizationRule()`: ```ts fixture=client-vpn const endpoint = vpc.addClientVpnEndpoint('Endpoint', { diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index 64f3bb46f14c8..cd70f71582718 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -1,7 +1,7 @@ import * as cxschema from '@aws-cdk/cloud-assembly-schema'; import { Annotations, ConcreteDependable, ContextProvider, DependableTrait, IConstruct, - IDependable, IResource, Lazy, Resource, Stack, Token, Tags, Names, + IDependable, IResource, Lazy, Resource, Stack, Token, Tags, Names, Arn, } from '@aws-cdk/core'; import * as cxapi from '@aws-cdk/cx-api'; import { Construct, Node } from 'constructs'; @@ -78,6 +78,12 @@ export interface IVpc extends IResource { */ readonly vpcId: string; + /** + * ARN for this VPC + * @attribute + */ + readonly vpcArn: string; + /** * CIDR range for this VPC * @@ -357,6 +363,11 @@ abstract class VpcBase extends Resource implements IVpc { */ public abstract readonly vpcId: string; + /** + * Arn of this VPC + */ + public abstract readonly vpcArn: string; + /** * CIDR range for this VPC */ @@ -1153,6 +1164,11 @@ export class Vpc extends VpcBase { */ public readonly vpcId: string; + /** + * @attribute + */ + public readonly vpcArn: string; + /** * @attribute */ @@ -1283,6 +1299,11 @@ export class Vpc extends VpcBase { this.availabilityZones = this.availabilityZones.slice(0, maxAZs); this.vpcId = this.resource.ref; + this.vpcArn = Arn.format({ + service: 'ec2', + resource: 'vpc', + resourceName: this.vpcId, + }, stack); const defaultSubnet = props.natGateways === 0 ? Vpc.DEFAULT_SUBNETS_NO_NAT : Vpc.DEFAULT_SUBNETS; this.subnetConfiguration = ifUndefined(props.subnetConfiguration, defaultSubnet); @@ -1859,6 +1880,7 @@ function ifUndefined(value: T | undefined, defaultValue: T): T { class ImportedVpc extends VpcBase { public readonly vpcId: string; + public readonly vpcArn: string; public readonly publicSubnets: ISubnet[]; public readonly privateSubnets: ISubnet[]; public readonly isolatedSubnets: ISubnet[]; @@ -1870,6 +1892,11 @@ class ImportedVpc extends VpcBase { super(scope, id); this.vpcId = props.vpcId; + this.vpcArn = Arn.format({ + service: 'ec2', + resource: 'vpc', + resourceName: this.vpcId, + }, Stack.of(this)); this.cidr = props.vpcCidrBlock; this.availabilityZones = props.availabilityZones; this._vpnGatewayId = props.vpnGatewayId; @@ -1903,6 +1930,7 @@ class ImportedVpc extends VpcBase { class LookedUpVpc extends VpcBase { public readonly vpcId: string; + public readonly vpcArn: string; public readonly internetConnectivityEstablished: IDependable = new ConcreteDependable(); public readonly availabilityZones: string[]; public readonly publicSubnets: ISubnet[]; @@ -1914,6 +1942,11 @@ class LookedUpVpc extends VpcBase { super(scope, id); this.vpcId = props.vpcId; + this.vpcArn = Arn.format({ + service: 'ec2', + resource: 'vpc', + resourceName: this.vpcId, + }, Stack.of(this)); this.cidr = props.vpcCidrBlock; this._vpnGatewayId = props.vpnGatewayId; this.incompleteSubnetDefinition = isIncomplete; diff --git a/packages/@aws-cdk/aws-ec2/test/vpc.test.ts b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts index 90942056865c7..eedc950ab584b 100644 --- a/packages/@aws-cdk/aws-ec2/test/vpc.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts @@ -36,7 +36,12 @@ describe('vpc', () => { const stack = getTestStack(); const vpc = new Vpc(stack, 'TheVPC'); expect(stack.resolve(vpc.vpcId)).toEqual({ Ref: 'TheVPC92636AB0' }); + }); + test('vpc.vpcArn returns a token to the VPC ID', () => { + const stack = getTestStack(); + const vpc = new Vpc(stack, 'TheVPC'); + expect(stack.resolve(vpc.vpcArn)).toEqual({ 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':ec2:us-east-1:123456789012:vpc/', { Ref: 'TheVPC92636AB0' }]] }); }); test('it uses the correct network range', () => { @@ -1786,4 +1791,4 @@ function hasTags(expectedTags: Array<{Key: string, Value: string}>): (props: any throw e; } }; -} +} \ No newline at end of file From 443a23e8c1e0de97f6ae05a3e451b0407165a447 Mon Sep 17 00:00:00 2001 From: Julian Michel Date: Mon, 25 Oct 2021 19:20:46 +0200 Subject: [PATCH 030/148] feat(ec2): add X2g instances (for RDS) (#17081) Add support for X2g instances. Announcements: - https://aws.amazon.com/about-aws/whats-new/2021/09/amazon-aurora-supports-aws-graviton2-based-x2g-instances/ - https://aws.amazon.com/about-aws/whats-new/2021/09/amazon-rds-x2g-mysql-mariadb-postgresql/ X2g instances are only supported in RDS. They are not available in EC2. RDS uses instances types from module EC2. Therefore, X2g should be added in EC2 (see skinny85's [comment](https://github.com/aws/aws-cdk/issues/16948#issuecomment-946254267)). Closes #16948. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-ec2/lib/instance-types.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts index 1b778fee66e6e..97d3d03e55219 100644 --- a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts +++ b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts @@ -372,6 +372,20 @@ export enum InstanceClass { */ X1E = 'x1e', + /** + * Memory-intensive instances, 2nd generation with Graviton2 processors + * + * This instance type can be used only in RDS. It is not supported in EC2. + */ + MEMORY_INTENSIVE_2_GRAVITON2 = 'x2g', + + /** + * Memory-intensive instances, 2nd generation with Graviton2 processors + * + * This instance type can be used only in RDS. It is not supported in EC2. + */ + X2G = 'x2g', + /** * Memory-intensive instances, 2nd generation with Graviton2 processors and local NVME drive */ From 691d3771d32002b3cd4cb1221af92762b749e716 Mon Sep 17 00:00:00 2001 From: Lukas Fruntke Date: Mon, 25 Oct 2021 20:12:51 +0200 Subject: [PATCH 031/148] feat(ec2): add region parameter for UserData via addS3DownloadCommand (#16667) Allow the specification of a region in `addS3DownloadCommand()` in the UserData helper. Fixes #8287 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-ec2/README.md | 1 + packages/@aws-cdk/aws-ec2/lib/user-data.ts | 10 +++- .../@aws-cdk/aws-ec2/test/userdata.test.ts | 59 +++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2/README.md b/packages/@aws-cdk/aws-ec2/README.md index 7b00a026bf871..f450e29dfcf20 100644 --- a/packages/@aws-cdk/aws-ec2/README.md +++ b/packages/@aws-cdk/aws-ec2/README.md @@ -1110,6 +1110,7 @@ const instance = new ec2.Instance(this, 'Instance', { const localPath = instance.userData.addS3DownloadCommand({ bucket:asset.bucket, bucketKey:asset.s3ObjectKey, + region: 'us-east-1', // Optional }); instance.userData.addExecuteFileCommand({ filePath:localPath, diff --git a/packages/@aws-cdk/aws-ec2/lib/user-data.ts b/packages/@aws-cdk/aws-ec2/lib/user-data.ts index 9b835744b3a6e..14b94d2d2ad4a 100644 --- a/packages/@aws-cdk/aws-ec2/lib/user-data.ts +++ b/packages/@aws-cdk/aws-ec2/lib/user-data.ts @@ -37,6 +37,12 @@ export interface S3DownloadOptions { */ readonly localFile?: string; + /** + * The region of the S3 Bucket (needed for access via VPC Gateway) + * @default none + */ + readonly region?: string + } /** @@ -156,7 +162,7 @@ class LinuxUserData extends UserData { const localPath = ( params.localFile && params.localFile.length !== 0 ) ? params.localFile : `/tmp/${ params.bucketKey }`; this.addCommands( `mkdir -p $(dirname '${localPath}')`, - `aws s3 cp '${s3Path}' '${localPath}'`, + `aws s3 cp '${s3Path}' '${localPath}'` + (params.region !== undefined ? ` --region ${params.region}` : ''), ); return localPath; @@ -215,7 +221,7 @@ class WindowsUserData extends UserData { const localPath = ( params.localFile && params.localFile.length !== 0 ) ? params.localFile : `C:/temp/${ params.bucketKey }`; this.addCommands( `mkdir (Split-Path -Path '${localPath}' ) -ea 0`, - `Read-S3Object -BucketName '${params.bucket.bucketName}' -key '${params.bucketKey}' -file '${localPath}' -ErrorAction Stop`, + `Read-S3Object -BucketName '${params.bucket.bucketName}' -key '${params.bucketKey}' -file '${localPath}' -ErrorAction Stop` + (params.region !== undefined ? ` -Region ${params.region}` : ''), ); return localPath; } diff --git a/packages/@aws-cdk/aws-ec2/test/userdata.test.ts b/packages/@aws-cdk/aws-ec2/test/userdata.test.ts index 272ad60a84b00..e2596d8699abd 100644 --- a/packages/@aws-cdk/aws-ec2/test/userdata.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/userdata.test.ts @@ -85,6 +85,35 @@ describe('user data', () => { 'Read-S3Object -BucketName \'test2\' -key \'filename2.bat\' -file \'c:\\test\\location\\otherScript.bat\' -ErrorAction Stop', ); + }); + test('can windows userdata download S3 files with given region', () => { + // GIVEN + const stack = new Stack(); + const userData = ec2.UserData.forWindows(); + const bucket = Bucket.fromBucketName( stack, 'testBucket', 'test' ); + const bucket2 = Bucket.fromBucketName( stack, 'testBucket2', 'test2' ); + + // WHEN + userData.addS3DownloadCommand({ + bucket, + bucketKey: 'filename.bat', + region: 'us-east-1', + } ); + userData.addS3DownloadCommand({ + bucket: bucket2, + bucketKey: 'filename2.bat', + localFile: 'c:\\test\\location\\otherScript.bat', + region: 'us-east-1', + } ); + + // THEN + const rendered = userData.render(); + expect(rendered).toEqual('mkdir (Split-Path -Path \'C:/temp/filename.bat\' ) -ea 0\n' + + 'Read-S3Object -BucketName \'test\' -key \'filename.bat\' -file \'C:/temp/filename.bat\' -ErrorAction Stop -Region us-east-1\n' + + 'mkdir (Split-Path -Path \'c:\\test\\location\\otherScript.bat\' ) -ea 0\n' + + 'Read-S3Object -BucketName \'test2\' -key \'filename2.bat\' -file \'c:\\test\\location\\otherScript.bat\' -ErrorAction Stop -Region us-east-1', + ); + }); test('can windows userdata execute files', () => { // GIVEN @@ -189,6 +218,36 @@ describe('user data', () => { 'aws s3 cp \'s3://test2/filename2.sh\' \'c:\\test\\location\\otherScript.sh\'', ); + }); + test('can linux userdata download S3 files from specific region', () => { + // GIVEN + const stack = new Stack(); + const userData = ec2.UserData.forLinux(); + const bucket = Bucket.fromBucketName( stack, 'testBucket', 'test' ); + const bucket2 = Bucket.fromBucketName( stack, 'testBucket2', 'test2' ); + + // WHEN + userData.addS3DownloadCommand({ + bucket, + bucketKey: 'filename.sh', + region: 'us-east-1', + } ); + userData.addS3DownloadCommand({ + bucket: bucket2, + bucketKey: 'filename2.sh', + localFile: 'c:\\test\\location\\otherScript.sh', + region: 'us-east-1', + } ); + + // THEN + const rendered = userData.render(); + expect(rendered).toEqual('#!/bin/bash\n' + + 'mkdir -p $(dirname \'/tmp/filename.sh\')\n' + + 'aws s3 cp \'s3://test/filename.sh\' \'/tmp/filename.sh\' --region us-east-1\n' + + 'mkdir -p $(dirname \'c:\\test\\location\\otherScript.sh\')\n' + + 'aws s3 cp \'s3://test2/filename2.sh\' \'c:\\test\\location\\otherScript.sh\' --region us-east-1', + ); + }); test('can linux userdata execute files', () => { // GIVEN From bdf30c696b04b26a8e41548839d5c4cf61d471cc Mon Sep 17 00:00:00 2001 From: Kyle Roach Date: Mon, 25 Oct 2021 19:06:25 +0000 Subject: [PATCH 032/148] fix(redshift): cluster uses key ARN instead of key ID (#17108) Field was incorrectly using key arn instead of id. Fixes #17032 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-redshift/lib/cluster.ts | 2 +- .../aws-redshift/test/cluster.test.ts | 5 +-- .../test/integ.database.expected.json | 38 +++++++++++++++++++ .../aws-redshift/test/integ.database.ts | 2 + 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk/aws-redshift/lib/cluster.ts b/packages/@aws-cdk/aws-redshift/lib/cluster.ts index a94bfa31b7fb5..a43b6f6993c72 100644 --- a/packages/@aws-cdk/aws-redshift/lib/cluster.ts +++ b/packages/@aws-cdk/aws-redshift/lib/cluster.ts @@ -483,7 +483,7 @@ export class Cluster extends ClusterBase { dbName: props.defaultDatabaseName || 'default_db', publiclyAccessible: props.publiclyAccessible || false, // Encryption - kmsKeyId: props.encryptionKey && props.encryptionKey.keyArn, + kmsKeyId: props.encryptionKey?.keyId, encrypted: props.encrypted ?? true, }); diff --git a/packages/@aws-cdk/aws-redshift/test/cluster.test.ts b/packages/@aws-cdk/aws-redshift/test/cluster.test.ts index a1091815a30c1..d771e8e66b0de 100644 --- a/packages/@aws-cdk/aws-redshift/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-redshift/test/cluster.test.ts @@ -249,10 +249,7 @@ test('create an encrypted cluster with custom KMS key', () => { // THEN Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { KmsKeyId: { - 'Fn::GetAtt': [ - 'Key961B73FD', - 'Arn', - ], + Ref: 'Key961B73FD', }, }); }); diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.expected.json b/packages/@aws-cdk/aws-redshift/test/integ.database.expected.json index 16d60bb08c0d0..4cfb1faea5118 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.database.expected.json +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.expected.json @@ -580,6 +580,41 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "customkmskey377C6F9A": { + "Type": "AWS::KMS::Key", + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, "ClusterSubnetsDCFA5CB7": { "Type": "AWS::Redshift::ClusterSubnetGroup", "Properties": { @@ -680,6 +715,9 @@ "Ref": "ClusterSubnetsDCFA5CB7" }, "Encrypted": true, + "KmsKeyId": { + "Ref": "customkmskey377C6F9A" + }, "NumberOfNodes": 2, "PubliclyAccessible": true, "VpcSecurityGroupIds": [ diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.ts b/packages/@aws-cdk/aws-redshift/test/integ.database.ts index 3a3b955a2b5aa..6e4893c0c0089 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.database.ts +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node /// !cdk-integ pragma:ignore-assets import * as ec2 from '@aws-cdk/aws-ec2'; +import * as kms from '@aws-cdk/aws-kms'; import * as cdk from '@aws-cdk/core'; import * as constructs from 'constructs'; import * as redshift from '../lib'; @@ -28,6 +29,7 @@ const cluster = new redshift.Cluster(stack, 'Cluster', { }, defaultDatabaseName: databaseName, publiclyAccessible: true, + encryptionKey: new kms.Key(stack, 'custom-kms-key'), }); const databaseOptions = { From 3eab4279f7fbd7ce4ec9d99dd822dd8d30d22ca3 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Mon, 25 Oct 2021 21:58:56 +0200 Subject: [PATCH 033/148] chore(cli): make integ tests v2-aware (#17122) Integ tests for v2 requires installing different packages and switching off some tests that don't make sense. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/test/integ/cli/app/app.js | 49 ++++-- .../test/integ/cli/app/nested-stack.js | 14 +- .../test/integ/cli/bootstrapping.integtest.ts | 39 +++-- .../aws-cdk/test/integ/cli/cli.integtest.ts | 155 +++++++++--------- packages/aws-cdk/test/integ/helpers/cdk.ts | 49 ++++-- .../aws-cdk/test/integ/run-against-dist.bash | 2 + 6 files changed, 183 insertions(+), 125 deletions(-) diff --git a/packages/aws-cdk/test/integ/cli/app/app.js b/packages/aws-cdk/test/integ/cli/app/app.js index 205d7014503dc..450662ac268e0 100644 --- a/packages/aws-cdk/test/integ/cli/app/app.js +++ b/packages/aws-cdk/test/integ/cli/app/app.js @@ -1,14 +1,28 @@ const path = require('path'); -const cdk = require('@aws-cdk/core'); -const ec2 = require('@aws-cdk/aws-ec2'); -const ssm = require('@aws-cdk/aws-ssm'); -const iam = require('@aws-cdk/aws-iam'); -const sns = require('@aws-cdk/aws-sns'); -const lambda = require('@aws-cdk/aws-lambda'); -const docker = require('@aws-cdk/aws-ecr-assets'); -const core = require('@aws-cdk/core') + +var constructs = require('constructs'); +if (process.env.PACKAGE_LAYOUT_VERSION === '1') { + var cdk = require('@aws-cdk/core'); + var ec2 = require('@aws-cdk/aws-ec2'); + var ssm = require('@aws-cdk/aws-ssm'); + var iam = require('@aws-cdk/aws-iam'); + var sns = require('@aws-cdk/aws-sns'); + var lambda = require('@aws-cdk/aws-lambda'); + var docker = require('@aws-cdk/aws-ecr-assets'); +} else { + var cdk = require('aws-cdk-lib'); + var { + aws_ec2: ec2, + aws_ssm: ssm, + aws_iam: iam, + aws_sns: sns, + aws_lambda: lambda, + aws_ecr_assets: docker + } = require('aws-cdk-lib'); +} + +const { Annotations } = cdk; const { StackWithNestedStack, StackWithNestedStackUsingParameters } = require('./nested-stack'); -const { Annotations } = require('@aws-cdk/core'); const stackPrefix = process.env.STACK_NAME_PREFIX; if (!stackPrefix) { @@ -48,11 +62,11 @@ class YourStack extends cdk.Stack { class StackUsingContext extends cdk.Stack { constructor(parent, id, props) { super(parent, id, props); - new core.CfnResource(this, 'Handle', { + new cdk.CfnResource(this, 'Handle', { type: 'AWS::CloudFormation::WaitConditionHandle' }); - new core.CfnOutput(this, 'Output', { + new cdk.CfnOutput(this, 'Output', { value: this.availabilityZones, }); } @@ -167,7 +181,7 @@ class MissingSSMParameterStack extends cdk.Stack { constructor(parent, id, props) { super(parent, id, props); - const parameterName = this.node.tryGetContext('test:ssm-parameter-name'); + const parameterName = constructs.Node.of(this).tryGetContext('test:ssm-parameter-name'); if (parameterName) { const param = getSsmParameterValue(this, parameterName); new iam.Role(this, 'PhonyRole', { assumedBy: new iam.AccountPrincipal(param) }); @@ -199,7 +213,7 @@ class DockerStack extends cdk.Stack { // Add at least a single resource (WaitConditionHandle), otherwise this stack will never // be deployed (and its assets never built) - new core.CfnResource(this, 'Handle', { + new cdk.CfnResource(this, 'Handle', { type: 'AWS::CloudFormation::WaitConditionHandle' }); } @@ -216,7 +230,7 @@ class DockerStackWithCustomFile extends cdk.Stack { // Add at least a single resource (WaitConditionHandle), otherwise this stack will never // be deployed (and its assets never built) - new core.CfnResource(this, 'Handle', { + new cdk.CfnResource(this, 'Handle', { type: 'AWS::CloudFormation::WaitConditionHandle' }); } @@ -228,7 +242,7 @@ class FailedStack extends cdk.Stack { super(parent, id, props); // fails on 'Property PolicyDocument cannot be empty'. - new core.CfnResource(this, 'EmptyPolicy', { + new cdk.CfnResource(this, 'EmptyPolicy', { type: 'AWS::IAM::Policy' }) @@ -243,9 +257,10 @@ class DefineVpcStack extends cdk.Stack { constructor(parent, id, props) { super(parent, id, props); - new ec2.Vpc(this, 'VPC', { + const vpc = new ec2.Vpc(this, 'VPC', { maxAzs: 1, - }).node.applyAspect(new cdk.Tag(VPC_TAG_NAME, VPC_TAG_VALUE)); + }) + cdk.Aspects.of(vpc).add(new cdk.Tag(VPC_TAG_NAME, VPC_TAG_VALUE)); } } diff --git a/packages/aws-cdk/test/integ/cli/app/nested-stack.js b/packages/aws-cdk/test/integ/cli/app/nested-stack.js index 3b3125963679b..87a45bb64b036 100644 --- a/packages/aws-cdk/test/integ/cli/app/nested-stack.js +++ b/packages/aws-cdk/test/integ/cli/app/nested-stack.js @@ -1,6 +1,14 @@ -const cfn = require('@aws-cdk/aws-cloudformation'); -const sns = require('@aws-cdk/aws-sns'); -const { Stack, CfnParameter } = require('@aws-cdk/core'); +if (process.env.PACKAGE_LAYOUT_VERSION === '1') { + var cfn = require('@aws-cdk/aws-cloudformation'); + var sns = require('@aws-cdk/aws-sns'); + var { Stack, CfnParameter } = require('@aws-cdk/core'); +} else { + var { + aws_cloudformation: cfn, + aws_sns: sns, + } = require('aws-cdk-lib'); + var { Stack, CfnParameter } = require('aws-cdk-lib'); +} class StackWithNestedStack extends Stack { constructor(scope, id) { diff --git a/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts b/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts index 6fce054dbbf10..d7716a2ac3e70 100644 --- a/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts +++ b/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts @@ -1,6 +1,6 @@ import * as fs from 'fs'; import * as path from 'path'; -import { randomString, withDefaultFixture } from '../helpers/cdk'; +import { MAJOR_VERSION, randomString, withDefaultFixture } from '../helpers/cdk'; import { integTest } from '../helpers/test-helpers'; const timeout = process.env.CODEBUILD_BUILD_ID ? // if the process is running in CodeBuild @@ -129,22 +129,27 @@ integTest('deploy old style synthesis to new style bootstrap', withDefaultFixtur }); })); -integTest('deploying new style synthesis to old style bootstrap fails', withDefaultFixture(async (fixture) => { - const bootstrapStackName = fixture.bootstrapStackName; - - await fixture.cdkBootstrapLegacy({ - toolkitStackName: bootstrapStackName, - }); - - // Deploy stack that uses file assets, this fails because the bootstrap stack - // is version checked. - await expect(fixture.cdkDeploy('lambda', { - options: [ - '--toolkit-stack-name', bootstrapStackName, - '--context', '@aws-cdk/core:newStyleStackSynthesis=1', - ], - })).rejects.toThrow('exited with error'); -})); +if (MAJOR_VERSION === '1') { + // For v2, the default bootstrap is the modern bootstrap, so this test is predicated on invalid + // assumptions. + + integTest('deploying new style synthesis to old style bootstrap fails', withDefaultFixture(async (fixture) => { + const bootstrapStackName = fixture.bootstrapStackName; + + await fixture.cdkBootstrapLegacy({ + toolkitStackName: bootstrapStackName, + }); + + // Deploy stack that uses file assets, this fails because the bootstrap stack + // is version checked. + await expect(fixture.cdkDeploy('lambda', { + options: [ + '--toolkit-stack-name', bootstrapStackName, + '--context', '@aws-cdk/core:newStyleStackSynthesis=1', + ], + })).rejects.toThrow('exited with error'); + })); +} integTest('can create a legacy bootstrap stack with --public-access-block-configuration=false', withDefaultFixture(async (fixture) => { const bootstrapStackName = fixture.bootstrapStackName; diff --git a/packages/aws-cdk/test/integ/cli/cli.integtest.ts b/packages/aws-cdk/test/integ/cli/cli.integtest.ts index 873e3a1787ee5..127734a136491 100644 --- a/packages/aws-cdk/test/integ/cli/cli.integtest.ts +++ b/packages/aws-cdk/test/integ/cli/cli.integtest.ts @@ -2,7 +2,7 @@ import { promises as fs } from 'fs'; import * as os from 'os'; import * as path from 'path'; import { retry, sleep } from '../helpers/aws'; -import { cloneDirectory, shell, withDefaultFixture } from '../helpers/cdk'; +import { cloneDirectory, MAJOR_VERSION, shell, withDefaultFixture } from '../helpers/cdk'; import { integTest } from '../helpers/test-helpers'; jest.setTimeout(600 * 1000); @@ -40,7 +40,7 @@ integTest('Termination protection', withDefaultFixture(async (fixture) => { integTest('cdk synth', withDefaultFixture(async (fixture) => { await fixture.cdk(['synth', fixture.fullStackName('test-1')]); - expect(fixture.template('test-1')).toEqual({ + expect(fixture.template('test-1')).toEqual(expect.objectContaining({ Resources: { topic69831491: { Type: 'AWS::SNS::Topic', @@ -49,10 +49,10 @@ integTest('cdk synth', withDefaultFixture(async (fixture) => { }, }, }, - }); + })); await fixture.cdk(['synth', fixture.fullStackName('test-2')], { verbose: false }); - expect(fixture.template('test-2')).toEqual({ + expect(fixture.template('test-2')).toEqual(expect.objectContaining({ Resources: { topic152D84A37: { Type: 'AWS::SNS::Topic', @@ -67,8 +67,7 @@ integTest('cdk synth', withDefaultFixture(async (fixture) => { }, }, }, - }); - + })); })); integTest('ssm parameter provider error', withDefaultFixture(async (fixture) => { @@ -223,12 +222,12 @@ integTest('deploy with parameters', withDefaultFixture(async (fixture) => { StackName: stackArn, }); - expect(response.Stacks?.[0].Parameters).toEqual([ + expect(response.Stacks?.[0].Parameters).toContainEqual( { ParameterKey: 'TopicNameParam', ParameterValue: `${fixture.stackNamePrefix}bazinga`, }, - ]); + ); })); integTest('update to stack in ROLLBACK_COMPLETE state will delete stack and create a new one', withDefaultFixture(async (fixture) => { @@ -262,12 +261,12 @@ integTest('update to stack in ROLLBACK_COMPLETE state will delete stack and crea // THEN expect (stackArn).not.toEqual(newStackArn); // new stack was created expect(newStackResponse.Stacks?.[0].StackStatus).toEqual('CREATE_COMPLETE'); - expect(newStackResponse.Stacks?.[0].Parameters).toEqual([ + expect(newStackResponse.Stacks?.[0].Parameters).toContainEqual( { ParameterKey: 'TopicNameParam', ParameterValue: `${fixture.stackNamePrefix}allgood`, }, - ]); + ); })); integTest('stack in UPDATE_ROLLBACK_COMPLETE state can be updated', withDefaultFixture(async (fixture) => { @@ -313,12 +312,12 @@ integTest('stack in UPDATE_ROLLBACK_COMPLETE state can be updated', withDefaultF // THEN expect(response.Stacks?.[0].StackStatus).toEqual('UPDATE_COMPLETE'); - expect(response.Stacks?.[0].Parameters).toEqual([ + expect(response.Stacks?.[0].Parameters).toContainEqual( { ParameterKey: 'TopicNameParam', ParameterValue: `${fixture.stackNamePrefix}allgood`, }, - ]); + ); })); integTest('deploy with wildcard and parameters', withDefaultFixture(async (fixture) => { @@ -348,16 +347,18 @@ integTest('deploy with parameters multi', withDefaultFixture(async (fixture) => StackName: stackArn, }); - expect(response.Stacks?.[0].Parameters).toEqual([ + expect(response.Stacks?.[0].Parameters).toContainEqual( { ParameterKey: 'DisplayNameParam', ParameterValue: paramVal1, }, + ); + expect(response.Stacks?.[0].Parameters).toContainEqual( { ParameterKey: 'OtherDisplayNameParam', ParameterValue: paramVal2, }, - ]); + ); })); integTest('deploy with notification ARN', withDefaultFixture(async (fixture) => { @@ -382,82 +383,86 @@ integTest('deploy with notification ARN', withDefaultFixture(async (fixture) => } })); -integTest('deploy with role', withDefaultFixture(async (fixture) => { - const roleName = `${fixture.stackNamePrefix}-test-role`; - - await deleteRole(); - - const createResponse = await fixture.aws.iam('createRole', { - RoleName: roleName, - AssumeRolePolicyDocument: JSON.stringify({ - Version: '2012-10-17', - Statement: [{ - Action: 'sts:AssumeRole', - Principal: { Service: 'cloudformation.amazonaws.com' }, - Effect: 'Allow', - }, { - Action: 'sts:AssumeRole', - Principal: { AWS: (await fixture.aws.sts('getCallerIdentity', {})).Arn }, - Effect: 'Allow', - }], - }), - }); - const roleArn = createResponse.Role.Arn; - try { - await fixture.aws.iam('putRolePolicy', { +if (MAJOR_VERSION === '1') { + // NOTE: this doesn't currently work with modern-style synthesis, as the bootstrap + // role by default will not have permission to iam:PassRole the created role. + integTest('deploy with role', withDefaultFixture(async (fixture) => { + const roleName = `${fixture.stackNamePrefix}-test-role`; + + await deleteRole(); + + const createResponse = await fixture.aws.iam('createRole', { RoleName: roleName, - PolicyName: 'DefaultPolicy', - PolicyDocument: JSON.stringify({ + AssumeRolePolicyDocument: JSON.stringify({ Version: '2012-10-17', Statement: [{ - Action: '*', - Resource: '*', + Action: 'sts:AssumeRole', + Principal: { Service: 'cloudformation.amazonaws.com' }, + Effect: 'Allow', + }, { + Action: 'sts:AssumeRole', + Principal: { AWS: (await fixture.aws.sts('getCallerIdentity', {})).Arn }, Effect: 'Allow', }], }), }); + const roleArn = createResponse.Role.Arn; + try { + await fixture.aws.iam('putRolePolicy', { + RoleName: roleName, + PolicyName: 'DefaultPolicy', + PolicyDocument: JSON.stringify({ + Version: '2012-10-17', + Statement: [{ + Action: '*', + Resource: '*', + Effect: 'Allow', + }], + }), + }); - await retry(fixture.output, 'Trying to assume fresh role', retry.forSeconds(300), async () => { - await fixture.aws.sts('assumeRole', { - RoleArn: roleArn, - RoleSessionName: 'testing', + await retry(fixture.output, 'Trying to assume fresh role', retry.forSeconds(300), async () => { + await fixture.aws.sts('assumeRole', { + RoleArn: roleArn, + RoleSessionName: 'testing', + }); }); - }); - // In principle, the role has replicated from 'us-east-1' to wherever we're testing. - // Give it a little more sleep to make sure CloudFormation is not hitting a box - // that doesn't have it yet. - await sleep(5000); + // In principle, the role has replicated from 'us-east-1' to wherever we're testing. + // Give it a little more sleep to make sure CloudFormation is not hitting a box + // that doesn't have it yet. + await sleep(5000); - await fixture.cdkDeploy('test-2', { - options: ['--role-arn', roleArn], - }); + await fixture.cdkDeploy('test-2', { + options: ['--role-arn', roleArn], + }); - // Immediately delete the stack again before we delete the role. - // - // Since roles are sticky, if we delete the role before the stack, subsequent DeleteStack - // operations will fail when CloudFormation tries to assume the role that's already gone. - await fixture.cdkDestroy('test-2'); + // Immediately delete the stack again before we delete the role. + // + // Since roles are sticky, if we delete the role before the stack, subsequent DeleteStack + // operations will fail when CloudFormation tries to assume the role that's already gone. + await fixture.cdkDestroy('test-2'); - } finally { - await deleteRole(); - } + } finally { + await deleteRole(); + } - async function deleteRole() { - try { - for (const policyName of (await fixture.aws.iam('listRolePolicies', { RoleName: roleName })).PolicyNames) { - await fixture.aws.iam('deleteRolePolicy', { - RoleName: roleName, - PolicyName: policyName, - }); + async function deleteRole() { + try { + for (const policyName of (await fixture.aws.iam('listRolePolicies', { RoleName: roleName })).PolicyNames) { + await fixture.aws.iam('deleteRolePolicy', { + RoleName: roleName, + PolicyName: policyName, + }); + } + await fixture.aws.iam('deleteRole', { RoleName: roleName }); + } catch (e) { + if (e.message.indexOf('cannot be found') > -1) { return; } + throw e; } - await fixture.aws.iam('deleteRole', { RoleName: roleName }); - } catch (e) { - if (e.message.indexOf('cannot be found') > -1) { return; } - throw e; } - } -})); + })); +} integTest('cdk diff', withDefaultFixture(async (fixture) => { const diff1 = await fixture.cdk(['diff', fixture.fullStackName('test-1')]); @@ -734,7 +739,7 @@ integTest('templates on disk contain metadata resource, also in nested assemblie expect(JSON.parse(templateContents).Resources.CDKMetadata).toBeTruthy(); // Load template from nested assembly - const nestedTemplateContents = await fixture.shell(['cat', 'cdk.out/assembly-*-stage/*-stage-StackInStage.template.json']); + const nestedTemplateContents = await fixture.shell(['cat', 'cdk.out/assembly-*-stage/*StackInStage*.template.json']); expect(JSON.parse(nestedTemplateContents).Resources.CDKMetadata).toBeTruthy(); })); diff --git a/packages/aws-cdk/test/integ/helpers/cdk.ts b/packages/aws-cdk/test/integ/helpers/cdk.ts index 4a09f43063600..edf996ba36ed6 100644 --- a/packages/aws-cdk/test/integ/helpers/cdk.ts +++ b/packages/aws-cdk/test/integ/helpers/cdk.ts @@ -12,10 +12,23 @@ const REGIONS = process.env.AWS_REGIONS ? process.env.AWS_REGIONS.split(',') : [process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? 'us-east-1']; -const FRAMEWORK_VERSION = process.env.FRAMEWORK_VERSION; +const FRAMEWORK_VERSION = process.env.FRAMEWORK_VERSION ?? '*'; + +export let MAJOR_VERSION = FRAMEWORK_VERSION.split('.')[0]; +if (MAJOR_VERSION === '*') { + if (process.env.REPO_ROOT) { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const releaseJson = require(path.resolve(process.env.REPO_ROOT, 'release.json')); + MAJOR_VERSION = `${releaseJson.majorVersion}`; + } else { + // eslint-disable-next-line no-console + console.error('[WARNING] Have to guess at major version. Guessing version 1 to not break anything, but this should not happen'); + MAJOR_VERSION = '1'; + } +} process.stdout.write(`Using regions: ${REGIONS}\n`); -process.stdout.write(`Using framework version: ${FRAMEWORK_VERSION}\n`); +process.stdout.write(`Using framework version: ${FRAMEWORK_VERSION} (major version ${MAJOR_VERSION})\n`); const REGION_POOL = new ResourcePool(REGIONS); @@ -63,17 +76,26 @@ export function withCdkApp(block: (context: let success = true; try { - const version = FRAMEWORK_VERSION ?? '*'; - await installNpmPackages(fixture, { - '@aws-cdk/core': version, - '@aws-cdk/aws-sns': version, - '@aws-cdk/aws-iam': version, - '@aws-cdk/aws-lambda': version, - '@aws-cdk/aws-ssm': version, - '@aws-cdk/aws-ecr-assets': version, - '@aws-cdk/aws-cloudformation': version, - '@aws-cdk/aws-ec2': version, - }); + const installationVersion = FRAMEWORK_VERSION; + + if (MAJOR_VERSION === '1') { + await installNpmPackages(fixture, { + '@aws-cdk/core': installationVersion, + '@aws-cdk/aws-sns': installationVersion, + '@aws-cdk/aws-iam': installationVersion, + '@aws-cdk/aws-lambda': installationVersion, + '@aws-cdk/aws-ssm': installationVersion, + '@aws-cdk/aws-ecr-assets': installationVersion, + '@aws-cdk/aws-cloudformation': installationVersion, + '@aws-cdk/aws-ec2': installationVersion, + 'constructs': '^3', + }); + } else { + await installNpmPackages(fixture, { + 'aws-cdk-lib': installationVersion, + 'constructs': '^10', + }); + } await ensureBootstrapped(fixture); @@ -377,6 +399,7 @@ export class TestFixture { AWS_REGION: this.aws.region, AWS_DEFAULT_REGION: this.aws.region, STACK_NAME_PREFIX: this.stackNamePrefix, + PACKAGE_LAYOUT_VERSION: MAJOR_VERSION, ...options.modEnv, }, }); diff --git a/packages/aws-cdk/test/integ/run-against-dist.bash b/packages/aws-cdk/test/integ/run-against-dist.bash index 0d5dc245df5e7..84162031f5068 100644 --- a/packages/aws-cdk/test/integ/run-against-dist.bash +++ b/packages/aws-cdk/test/integ/run-against-dist.bash @@ -4,6 +4,8 @@ npmws=/tmp/cdk-rundist rm -rf $npmws mkdir -p $npmws +set -x + # This script must create 1 or 2 traps, and the 'trap' command will replace # the previous trap, so get some 'dynamic traps' mechanism in place TRAPS=() From c36c73fa428a302af412d8bbb8ef30f746ba2ec8 Mon Sep 17 00:00:00 2001 From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com> Date: Mon, 25 Oct 2021 16:52:08 -0400 Subject: [PATCH 034/148] docs(stepfunctions-tasks): make examples compile (#17143) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-stepfunctions-tasks/README.md | 100 ++++++++++-------- .../lib/sagemaker/base-types.ts | 8 +- .../rosetta/default.ts-fixture | 24 +---- .../rosetta/with-batch-job.ts-fixture | 38 ------- 4 files changed, 64 insertions(+), 106 deletions(-) delete mode 100644 packages/@aws-cdk/aws-stepfunctions-tasks/rosetta/with-batch-job.ts-fixture diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md index a0f47ee7519c1..cedf89eefe07c 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md @@ -110,9 +110,10 @@ The following example provides the field named `input` as the input to the `Task state that runs a Lambda function. ```ts +declare const fn: lambda.Function; const submitJob = new tasks.LambdaInvoke(this, 'Invoke Handler', { lambdaFunction: fn, - inputPath: '$.input' + inputPath: '$.input', }); ``` @@ -130,9 +131,10 @@ as well as other metadata. The following example assigns the output from the Task to a field named `result` ```ts +declare const fn: lambda.Function; const submitJob = new tasks.LambdaInvoke(this, 'Invoke Handler', { lambdaFunction: fn, - outputPath: '$.Payload.result' + outputPath: '$.Payload.result', }); ``` @@ -149,6 +151,7 @@ The following example extracts the output payload of a Lambda function Task and it with some static values and the state name from the context object. ```ts +declare const fn: lambda.Function; new tasks.LambdaInvoke(this, 'Invoke Handler', { lambdaFunction: fn, resultSelector: { @@ -159,7 +162,7 @@ new tasks.LambdaInvoke(this, 'Invoke Handler', { }, stateName: sfn.JsonPath.stringAt('$$.State.Name'), }, -}) +}); ``` ### ResultPath @@ -174,9 +177,10 @@ The following example adds the item from calling DynamoDB's `getItem` API to the input and passes it to the next state. ```ts +declare const myTable: dynamodb.Table; new tasks.DynamoPutItem(this, 'PutItem', { item: { - MessageId: tasks.DynamoAttributeValue.fromString('message-id') + MessageId: tasks.DynamoAttributeValue.fromString('message-id'), }, table: myTable, resultPath: `$.Item`, @@ -199,6 +203,7 @@ The following example provides the field named `input` as the input to the Lambd and invokes it asynchronously. ```ts +declare const fn: lambda.Function; const submitJob = new tasks.LambdaInvoke(this, 'Invoke Handler', { lambdaFunction: fn, payload: sfn.TaskInput.fromJsonPathAt('$.input'), @@ -258,14 +263,14 @@ const publishMessage = new tasks.SnsPublish(this, 'Publish message', { }); const wait = new sfn.Wait(this, 'Wait', { - time: sfn.WaitTime.secondsPath('$.waitSeconds') + time: sfn.WaitTime.secondsPath('$.waitSeconds'), }); new sfn.StateMachine(this, 'StateMachine', { definition: convertToSeconds .next(createMessage) .next(publishMessage) - .next(wait) + .next(wait), }); ``` @@ -286,15 +291,13 @@ Previous-generation REST APIs currently offer more features. More details can be The `CallApiGatewayRestApiEndpoint` calls the REST API endpoint. ```ts -import * as sfn from '@aws-cdk/aws-stepfunctions'; -import * as tasks from `@aws-cdk/aws-stepfunctions-tasks`; - -const restApi = new apigateway.RestApi(stack, 'MyRestApi'); +import * as apigateway from '@aws-cdk/aws-apigateway'; +const restApi = new apigateway.RestApi(this, 'MyRestApi'); -const invokeTask = new tasks.CallApiGatewayRestApiEndpoint(stack, 'Call REST API', { +const invokeTask = new tasks.CallApiGatewayRestApiEndpoint(this, 'Call REST API', { api: restApi, stageName: 'prod', - method: HttpMethod.GET, + method: tasks.HttpMethod.GET, }); ``` @@ -303,15 +306,13 @@ const invokeTask = new tasks.CallApiGatewayRestApiEndpoint(stack, 'Call REST API The `CallApiGatewayHttpApiEndpoint` calls the HTTP API endpoint. ```ts -import * as sfn from '@aws-cdk/aws-stepfunctions'; -import * as tasks from `@aws-cdk/aws-stepfunctions-tasks`; - -const httpApi = new apigatewayv2.HttpApi(stack, 'MyHttpApi'); +import * as apigatewayv2 from '@aws-cdk/aws-apigatewayv2'; +const httpApi = new apigatewayv2.HttpApi(this, 'MyHttpApi'); -const invokeTask = new tasks.CallApiGatewayHttpApiEndpoint(stack, 'Call HTTP API', { +const invokeTask = new tasks.CallApiGatewayHttpApiEndpoint(this, 'Call HTTP API', { apiId: httpApi.apiId, - apiStack: cdk.Stack.of(httpApi), - method: HttpMethod.GET, + apiStack: Stack.of(httpApi), + method: tasks.HttpMethod.GET, }); ``` @@ -324,6 +325,7 @@ You can use Step Functions' AWS SDK integrations to call any of the over two hun directly from your state machine, giving you access to over nine thousand API actions. ```ts +declare const myBucket: s3.Bucket; const getObject = new tasks.CallAwsService(this, 'GetObject', { service: 's3', action: 'getObject', @@ -348,7 +350,7 @@ const listBuckets = new tasks.CallAwsService(this, 'ListBuckets', { service: 's3', action: 'ListBuckets', iamResources: ['*'], - iamAction: 's3:ListAllMyBuckets' + iamAction: 's3:ListAllMyBuckets', }); ``` @@ -416,11 +418,15 @@ Step Functions supports [Batch](https://docs.aws.amazon.com/step-functions/lates The [SubmitJob](https://docs.aws.amazon.com/batch/latest/APIReference/API_SubmitJob.html) API submits an AWS Batch job from a job definition. -```ts fixture=with-batch-job +```ts +import * as batch from '@aws-cdk/aws-batch'; +declare const batchJobDefinition: batch.JobDefinition; +declare const batchQueue: batch.JobQueue; + const task = new tasks.BatchSubmitJob(this, 'Submit Job', { - jobDefinitionArn: batchJobDefinitionArn, + jobDefinitionArn: batchJobDefinition.jobDefinitionArn, jobName: 'MyJob', - jobQueueArn: batchQueueArn, + jobQueueArn: batchQueue.jobQueueArn, }); ``` @@ -471,6 +477,7 @@ Read more about calling DynamoDB APIs [here](https://docs.aws.amazon.com/step-fu The [GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html) operation returns a set of attributes for the item with the given primary key. ```ts +declare const myTable: dynamodb.Table; new tasks.DynamoGetItem(this, 'Get Item', { key: { messageId: tasks.DynamoAttributeValue.fromString('message-007') }, table: myTable, @@ -482,6 +489,7 @@ new tasks.DynamoGetItem(this, 'Get Item', { The [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html) operation creates a new item, or replaces an old item with a new item. ```ts +declare const myTable: dynamodb.Table; new tasks.DynamoPutItem(this, 'PutItem', { item: { MessageId: tasks.DynamoAttributeValue.fromString('message-007'), @@ -497,6 +505,7 @@ new tasks.DynamoPutItem(this, 'PutItem', { The [DeleteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html) operation deletes a single item in a table by primary key. ```ts +declare const myTable: dynamodb.Table; new tasks.DynamoDeleteItem(this, 'DeleteItem', { key: { MessageId: tasks.DynamoAttributeValue.fromString('message-007') }, table: myTable, @@ -510,6 +519,7 @@ The [UpdateItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/ to the table if it does not already exist. ```ts +declare const myTable: dynamodb.Table; new tasks.DynamoUpdateItem(this, 'UpdateItem', { key: { MessageId: tasks.DynamoAttributeValue.fromString('message-007') @@ -547,8 +557,6 @@ The latest ACTIVE revision of the passed task definition is used for running the The following example runs a job from a task definition on EC2 ```ts -import * as ecs from '@aws-cdk/aws-ecs'; - const vpc = ec2.Vpc.fromLookup(this, 'Vpc', { isDefault: true, }); @@ -579,7 +587,7 @@ const runTask = new tasks.EcsRunTask(this, 'Run', { ecs.PlacementStrategy.randomly(), ], placementConstraints: [ - ecs.PlacementConstraint.memberOf('blieptuut') + ecs.PlacementConstraint.memberOf('blieptuut'), ], }), }); @@ -602,8 +610,6 @@ task definition is used for running the task. Learn more about The following example runs a job from a task definition on Fargate ```ts -import * as ecs from '@aws-cdk/aws-ecs'; - const vpc = ec2.Vpc.fromLookup(this, 'Vpc', { isDefault: true, }); @@ -648,7 +654,6 @@ Creates and starts running a cluster (job flow). Corresponds to the [`runJobFlow`](https://docs.aws.amazon.com/emr/latest/APIReference/API_RunJobFlow.html) API in EMR. ```ts - const clusterRole = new iam.Role(this, 'ClusterRole', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'), }); @@ -689,7 +694,8 @@ and 256 inclusive, where the default concurrency of 1 means no step concurrency ```ts new tasks.EmrCreateCluster(this, 'Create Cluster', { - // ... + instances: {}, + name: sfn.TaskInput.fromJsonPathAt('$.ClusterName').value, stepConcurrencyLevel: 10, }); ``` @@ -715,7 +721,7 @@ Corresponds to the [`terminateJobFlows`](https://docs.aws.amazon.com/emr/latest/ ```ts new tasks.EmrTerminateCluster(this, 'Task', { - clusterId: 'ClusterId' + clusterId: 'ClusterId', }); ``` @@ -793,17 +799,15 @@ The following code snippet includes a Task state that uses eks:call to list the ```ts import * as eks from '@aws-cdk/aws-eks'; -import * as sfn from '@aws-cdk/aws-stepfunctions'; -import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; const myEksCluster = new eks.Cluster(this, 'my sample cluster', { version: eks.KubernetesVersion.V1_18, clusterName: 'myEksCluster', }); -new tasks.EksCall(stack, 'Call a EKS Endpoint', { +new tasks.EksCall(this, 'Call a EKS Endpoint', { cluster: myEksCluster, - httpMethod: MethodType.GET, + httpMethod: tasks.HttpMethods.GET, httpPath: '/api/v1/namespaces/default/pods', }); ``` @@ -824,14 +828,12 @@ The following code snippet includes a Task state that uses events:putevents to s ```ts import * as events from '@aws-cdk/aws-events'; -import * as sfn from '@aws-cdk/aws-stepfunctions'; -import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; -const myEventBus = events.EventBus(stack, 'EventBus', { +const myEventBus = new events.EventBus(this, 'EventBus', { eventBusName: 'MyEventBus1', }); -new tasks.EventBridgePutEvents(stack, 'Send an event to EventBridge', { +new tasks.EventBridgePutEvents(this, 'Send an event to EventBridge', { entries: [{ detail: sfn.TaskInput.fromObject({ Message: 'Hello from Step Functions!', @@ -855,8 +857,8 @@ new tasks.GlueStartJobRun(this, 'Task', { arguments: sfn.TaskInput.fromObject({ key: 'value', }), - timeout: cdk.Duration.minutes(30), - notifyDelayAfter: cdk.Duration.minutes(5), + timeout: Duration.minutes(30), + notifyDelayAfter: Duration.minutes(5), }); ``` @@ -884,6 +886,7 @@ The following snippet invokes a Lambda Function with the state input as the payl by referencing the `$` path. ```ts +declare const fn: lambda.Function; new tasks.LambdaInvoke(this, 'Invoke with state input', { lambdaFunction: fn, }); @@ -899,6 +902,7 @@ The following snippet invokes a Lambda Function by referencing the `$.Payload` p to reference the output of a Lambda executed before it. ```ts +declare const fn: lambda.Function; new tasks.LambdaInvoke(this, 'Invoke with empty object as payload', { lambdaFunction: fn, payload: sfn.TaskInput.fromObject({}), @@ -915,6 +919,7 @@ The following snippet invokes a Lambda and sets the task output to only include the Lambda function response. ```ts +declare const fn: lambda.Function; new tasks.LambdaInvoke(this, 'Invoke and set function response as task output', { lambdaFunction: fn, outputPath: '$.Payload', @@ -927,6 +932,7 @@ Lambda function ARN directly in the "Resource" string, but it conflicts with the integrationPattern, invocationType, clientContext, and qualifier properties. ```ts +declare const fn: lambda.Function; new tasks.LambdaInvoke(this, 'Invoke and combine function response with task input', { lambdaFunction: fn, payloadResponseOnly: true, @@ -945,6 +951,7 @@ The following snippet invokes a Lambda with the task token as part of the input to the Lambda. ```ts +declare const fn: lambda.Function; new tasks.LambdaInvoke(this, 'Invoke with callback', { lambdaFunction: fn, integrationPattern: sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN, @@ -998,11 +1005,11 @@ new tasks.SageMakerCreateTrainingJob(this, 'TrainSagemaker', { }, resourceConfig: { instanceCount: 1, - instanceType: new ec2.InstanceType(JsonPath.stringAt('$.InstanceType')), - volumeSize: cdk.Size.gibibytes(50), + instanceType: new ec2.InstanceType(sfn.JsonPath.stringAt('$.InstanceType')), + volumeSize: Size.gibibytes(50), }, // optional: default is 1 instance of EC2 `M4.XLarge` with `10GB` volume stoppingCondition: { - maxRuntime: cdk.Duration.hours(2), + maxRuntime: Duration.hours(2), }, // optional: default is 1 hour }); ``` @@ -1017,7 +1024,7 @@ new tasks.SageMakerCreateTransformJob(this, 'Batch Inference', { modelName: 'MyModelName', modelClientOptions: { invocationsMaxRetries: 3, // default is 0 - invocationsTimeout: cdk.Duration.minutes(5), // default is 60 seconds + invocationsTimeout: Duration.minutes(5), // default is 60 seconds }, transformInput: { transformDataSource: { @@ -1111,7 +1118,7 @@ const task1 = new tasks.SnsPublish(this, 'Publish1', { }, pic: { // BINARY must be explicitly set - type: MessageAttributeDataType.BINARY, + dataType: tasks.MessageAttributeDataType.BINARY, value: sfn.JsonPath.stringAt('$.pic'), }, people: { @@ -1170,6 +1177,7 @@ via the `associateWithParent` property. This allows the Step Functions UI to lin executions from parent executions, making it easier to trace execution flow across state machines. ```ts +declare const child: sfn.StateMachine; const task = new tasks.StepFunctionsStartExecution(this, 'ChildTask', { stateMachine: child, associateWithParent: true, diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/base-types.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/base-types.ts index 10c35d847ecd1..e11a04c111856 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/base-types.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sagemaker/base-types.ts @@ -206,8 +206,12 @@ export interface ResourceConfig { /** * ML compute instance type. * - * @example To provide an instance type from the task input, write - * `new ec2.InstanceType(sfn.JsonPath.stringAt('$.path.to.instanceType'))`, where the value in the task input is an EC2 instance type prepended with "ml.". + * To provide an instance type from the task input, supply an instance type in the following way + * where the value in the task input is an EC2 instance type prepended with "ml.": + * + * ```ts + * new ec2.InstanceType(sfn.JsonPath.stringAt('$.path.to.instanceType')); + * ``` * @see https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_ResourceConfig.html#sagemaker-Type-ResourceConfig-InstanceType * * @default ec2.InstanceType(ec2.InstanceClass.M4, ec2.InstanceType.XLARGE) diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-stepfunctions-tasks/rosetta/default.ts-fixture index 11558a599e5f4..927b8e5fd6886 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/rosetta/default.ts-fixture +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/rosetta/default.ts-fixture @@ -1,8 +1,9 @@ // Fixture with packages imported, but nothing else -import * as cdk from '@aws-cdk/core'; +import { Duration, RemovalPolicy, Size, Stack } from '@aws-cdk/core'; import { Construct } from 'constructs'; -import * as ddb from '@aws-cdk/aws-dynamodb'; +import * as dynamodb from '@aws-cdk/aws-dynamodb'; import * as ec2 from '@aws-cdk/aws-ec2'; +import * as ecs from '@aws-cdk/aws-ecs'; import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; import * as s3 from '@aws-cdk/aws-s3'; @@ -11,27 +12,10 @@ import * as sns from '@aws-cdk/aws-sns'; import * as sqs from '@aws-cdk/aws-sqs'; import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; -class Fixture extends cdk.Stack { +class Fixture extends Stack { constructor(scope: Construct, id: string) { super(scope, id); - const fn = new lambda.Function(this, 'lambdaFunction', { - code: lambda.Code.fromInline(`exports.handler = async () => { - return { "hello world"}; - `), - runtime: lambda.Runtime.NODEJS_12_X, - handler: 'index.handler', - }); - - const myTable = new ddb.Table(this, 'Messages', { - tableName: 'my-table', - partitionKey: { - name: 'MessageId', - type: ddb.AttributeType.STRING, - }, - removalPolicy: cdk.RemovalPolicy.DESTROY, - }); - /// here } } diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/rosetta/with-batch-job.ts-fixture b/packages/@aws-cdk/aws-stepfunctions-tasks/rosetta/with-batch-job.ts-fixture deleted file mode 100644 index 47672ba140841..0000000000000 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/rosetta/with-batch-job.ts-fixture +++ /dev/null @@ -1,38 +0,0 @@ -// Fixture with packages imported, but nothing else -import { Stack } from '@aws-cdk/core'; -import { Construct } from 'constructs'; -import * as sfn from '@aws-cdk/aws-stepfunctions'; -import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; -import * as batch from '@aws-cdk/aws-batch'; -import * as ec2 from '@aws-cdk/aws-ec2'; -import * as ecs from '@aws-cdk/aws-ecs'; -import * as path from 'path'; - -class Fixture extends Stack { - constructor(scope: Construct, id: string) { - super(scope, id); - - const vpc = ec2.Vpc.fromLookup(this, 'Vpc', { - isDefault: true, - }); - - const batchQueue = new batch.JobQueue(this, 'JobQueue', { - computeEnvironments: [ - { - order: 1, - computeEnvironment: new batch.ComputeEnvironment(this, 'ComputeEnv', { - computeResources: { vpc }, - }), - }, - ], - }); - - const batchJobDefinition = new batch.JobDefinition(this, 'JobDefinition', { - container: { - image: ecs.ContainerImage.fromAsset(path.resolve(__dirname, 'batchjob-image')), - }, - }); - - /// here - } -} From 8343beccbee06f453b63387f54768b320fe01339 Mon Sep 17 00:00:00 2001 From: Michael Sambol Date: Mon, 25 Oct 2021 14:45:10 -0700 Subject: [PATCH 035/148] feat(synthetics): add syn-nodejs-puppeteer-3.3 runtime (#17132) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-synthetics/README.md | 6 +- .../@aws-cdk/aws-synthetics/lib/runtime.ts | 10 ++ .../test/integ.canary.expected.json | 167 ++++++++++++++++++ .../aws-synthetics/test/integ.canary.ts | 10 ++ 4 files changed, 190 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-synthetics/README.md b/packages/@aws-cdk/aws-synthetics/README.md index ba0482d3aa263..7f7665e02238c 100644 --- a/packages/@aws-cdk/aws-synthetics/README.md +++ b/packages/@aws-cdk/aws-synthetics/README.md @@ -127,7 +127,7 @@ new synthetics.Canary(this, 'Inline Canary', { code: synthetics.Code.fromInline('/* Synthetics handler code */'), handler: 'index.handler', // must be 'index.handler' }), - runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_1, + runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_3, }); // To supply the code from your local filesystem: @@ -136,7 +136,7 @@ new synthetics.Canary(this, 'Asset Canary', { code: synthetics.Code.fromAsset(path.join(__dirname, 'canary')), handler: 'index.handler', // must end with '.handler' }), - runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_1, + runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_3, }); // To supply the code from a S3 bucket: @@ -147,7 +147,7 @@ new synthetics.Canary(this, 'Bucket Canary', { code: synthetics.Code.fromBucket(bucket, 'canary.zip'), handler: 'index.handler', // must end with '.handler' }), - runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_1, + runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_3, }); ``` diff --git a/packages/@aws-cdk/aws-synthetics/lib/runtime.ts b/packages/@aws-cdk/aws-synthetics/lib/runtime.ts index c710d68a34e35..81ac1a857e6db 100644 --- a/packages/@aws-cdk/aws-synthetics/lib/runtime.ts +++ b/packages/@aws-cdk/aws-synthetics/lib/runtime.ts @@ -104,6 +104,16 @@ export class Runtime { */ public static readonly SYNTHETICS_NODEJS_PUPPETEER_3_2 = new Runtime('syn-nodejs-puppeteer-3.2', RuntimeFamily.NODEJS); + /** + * `syn-nodejs-puppeteer-3.3` includes the following: + * - Lambda runtime Node.js 12.x + * - Puppeteer-core version 5.5.0 + * - Chromium version 88.0.4298.0 + * + * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Library_nodejs_puppeteer.html#CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-3.3 + */ + public static readonly SYNTHETICS_NODEJS_PUPPETEER_3_3 = new Runtime('syn-nodejs-puppeteer-3.3', RuntimeFamily.NODEJS); + /** * `syn-python-selenium-1.0` includes the following: * - Lambda runtime Python 3.8 diff --git a/packages/@aws-cdk/aws-synthetics/test/integ.canary.expected.json b/packages/@aws-cdk/aws-synthetics/test/integ.canary.expected.json index 70d3908aa07f6..988973d8bfe78 100644 --- a/packages/@aws-cdk/aws-synthetics/test/integ.canary.expected.json +++ b/packages/@aws-cdk/aws-synthetics/test/integ.canary.expected.json @@ -456,6 +456,173 @@ "StartCanaryAfterCreation": true } }, + "MyCanaryThreeArtifactsBucket894E857E": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketEncryption": { + "ServerSideEncryptionConfiguration": [ + { + "ServerSideEncryptionByDefault": { + "SSEAlgorithm": "aws:kms" + } + } + ] + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "MyCanaryThreeServiceRole68117E65": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "s3:ListAllMyBuckets", + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "s3:PutObject", + "s3:GetBucketLocation" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyCanaryThreeArtifactsBucket894E857E", + "Arn" + ] + }, + "/*" + ] + ] + } + }, + { + "Action": "cloudwatch:PutMetricData", + "Condition": { + "StringEquals": { + "cloudwatch:namespace": "CloudWatchSynthetics" + } + }, + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "logs:CreateLogStream", + "logs:CreateLogGroup", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:::*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "canaryPolicy" + } + ] + } + }, + "MyCanaryThree968B1271": { + "Type": "AWS::Synthetics::Canary", + "Properties": { + "ArtifactS3Location": { + "Fn::Join": [ + "", + [ + "s3://", + { + "Ref": "MyCanaryThreeArtifactsBucket894E857E" + } + ] + ] + }, + "Code": { + "Handler": "canary.handler", + "S3Bucket": { + "Ref": "AssetParametersb1b777dcb79a2fa2790059927207d10bf5f4747d6dd1516e2780726d9d6fa820S3Bucket705C3761" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParametersb1b777dcb79a2fa2790059927207d10bf5f4747d6dd1516e2780726d9d6fa820S3VersionKeyE546342B" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParametersb1b777dcb79a2fa2790059927207d10bf5f4747d6dd1516e2780726d9d6fa820S3VersionKeyE546342B" + } + ] + } + ] + } + ] + ] + } + }, + "ExecutionRoleArn": { + "Fn::GetAtt": [ + "MyCanaryThreeServiceRole68117E65", + "Arn" + ] + }, + "Name": "assetcanary-three", + "RuntimeVersion": "syn-nodejs-puppeteer-3.3", + "Schedule": { + "DurationInSeconds": "0", + "Expression": "rate(5 minutes)" + }, + "StartCanaryAfterCreation": true + } + }, "MyPythonCanaryArtifactsBucket7AE88133": { "Type": "AWS::S3::Bucket", "Properties": { diff --git a/packages/@aws-cdk/aws-synthetics/test/integ.canary.ts b/packages/@aws-cdk/aws-synthetics/test/integ.canary.ts index 54822badf1c99..268667b8439f3 100644 --- a/packages/@aws-cdk/aws-synthetics/test/integ.canary.ts +++ b/packages/@aws-cdk/aws-synthetics/test/integ.canary.ts @@ -11,6 +11,7 @@ import * as synthetics from '../lib'; * -- aws synthetics get-canary --name canary-integ has a state of 'RUNNING' * -- aws synthetics get-canary --name assetcanary-one has a state of 'RUNNING' * -- aws synthetics get-canary --name assetcanary-two has a state of 'RUNNING' + * -- aws synthetics get-canary --name assetcanary-three has a state of 'RUNNING' */ const app = new cdk.App(); const stack = new cdk.Stack(app, 'canary-one'); @@ -50,6 +51,15 @@ new synthetics.Canary(stack, 'MyCanaryTwo', { runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_2, }); +new synthetics.Canary(stack, 'MyCanaryThree', { + canaryName: 'assetcanary-three', + test: synthetics.Test.custom({ + handler: 'canary.handler', + code: synthetics.Code.fromAsset(path.join(__dirname, 'canary.zip')), + }), + runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_3, +}); + new synthetics.Canary(stack, 'MyPythonCanary', { canaryName: 'py-canary-integ', test: synthetics.Test.custom({ From 06fb9f93dec448f8536fd19e116f4a2a7b163ee4 Mon Sep 17 00:00:00 2001 From: Calvin Combs <66279577+comcalvi@users.noreply.github.com> Date: Mon, 25 Oct 2021 15:37:13 -0700 Subject: [PATCH 036/148] chore(cli): do not hardcode AWS::URLSuffix in hotswapping (#17104) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/lib/api/aws-auth/sdk.ts | 20 ++++++ packages/aws-cdk/lib/api/deploy-stack.ts | 26 ++----- .../aws-cdk/lib/api/hotswap-deployments.ts | 3 +- .../evaluate-cloudformation-template.ts | 14 +++- .../aws-cdk/test/api/deploy-stack.test.ts | 3 +- .../api/hotswap/hotswap-deployments.test.ts | 69 +++++++++++++++++++ .../test/api/hotswap/hotswap-test-setup.ts | 4 ++ packages/aws-cdk/test/util/mock-sdk.ts | 12 ++++ 8 files changed, 126 insertions(+), 25 deletions(-) diff --git a/packages/aws-cdk/lib/api/aws-auth/sdk.ts b/packages/aws-cdk/lib/api/aws-auth/sdk.ts index 91fcdc2fede7d..c9c64d5e10ec1 100644 --- a/packages/aws-cdk/lib/api/aws-auth/sdk.ts +++ b/packages/aws-cdk/lib/api/aws-auth/sdk.ts @@ -5,6 +5,20 @@ import { cached } from '../../util/functions'; import { AccountAccessKeyCache } from './account-cache'; import { Account } from './sdk-provider'; +// We need to map regions to domain suffixes, and the SDK already has a function to do this. +// It's not part of the public API, but it's also unlikely to go away. +// +// Reuse that function, and add a safety check so we don't accidentally break if they ever +// refactor that away. + +/* eslint-disable @typescript-eslint/no-require-imports */ +const regionUtil = require('aws-sdk/lib/region_config'); +/* eslint-enable @typescript-eslint/no-require-imports */ + +if (!regionUtil.getEndpointSuffix) { + throw new Error('This version of AWS SDK for JS does not have the \'getEndpointSuffix\' function!'); +} + export interface ISDK { /** * The region this SDK has been instantiated for @@ -22,6 +36,8 @@ export interface ISDK { */ currentAccount(): Promise; + getEndpointSuffix(region: string): string; + lambda(): AWS.Lambda; cloudFormation(): AWS.CloudFormation; ec2(): AWS.EC2; @@ -190,6 +206,10 @@ export class SDK implements ISDK { } } + public getEndpointSuffix(region: string): string { + return regionUtil.getEndpointSuffix(region); + } + /** * Return a wrapping object for the underlying service object * diff --git a/packages/aws-cdk/lib/api/deploy-stack.ts b/packages/aws-cdk/lib/api/deploy-stack.ts index 6b5afe9673ead..ab662d34b517c 100644 --- a/packages/aws-cdk/lib/api/deploy-stack.ts +++ b/packages/aws-cdk/lib/api/deploy-stack.ts @@ -18,20 +18,6 @@ import { } from './util/cloudformation'; import { StackActivityMonitor, StackActivityProgress } from './util/cloudformation/stack-activity-monitor'; -// We need to map regions to domain suffixes, and the SDK already has a function to do this. -// It's not part of the public API, but it's also unlikely to go away. -// -// Reuse that function, and add a safety check so we don't accidentally break if they ever -// refactor that away. - -/* eslint-disable @typescript-eslint/no-require-imports */ -const regionUtil = require('aws-sdk/lib/region_config'); -/* eslint-enable @typescript-eslint/no-require-imports */ - -if (!regionUtil.getEndpointSuffix) { - throw new Error('This version of AWS SDK for JS does not have the \'getEndpointSuffix\' function!'); -} - type TemplateBodyParameter = { TemplateBody?: string TemplateURL?: string @@ -247,8 +233,7 @@ export async function deployStack(options: DeployStackOptions): Promise { + toolkitInfo: ToolkitInfo, + sdk: ISDK): Promise { // If the template has already been uploaded to S3, just use it from there. if (stack.stackTemplateAssetObjectUrl) { - return { TemplateURL: restUrlFromManifest(stack.stackTemplateAssetObjectUrl, resolvedEnvironment) }; + return { TemplateURL: restUrlFromManifest(stack.stackTemplateAssetObjectUrl, resolvedEnvironment, sdk) }; } // Otherwise, pass via API call (if small) or upload here (if large) @@ -553,7 +539,7 @@ function compareTags(a: Tag[], b: Tag[]): boolean { * and reformats s3://.../... urls into S3 REST URLs (which CloudFormation * expects) */ -function restUrlFromManifest(url: string, environment: cxapi.Environment): string { +function restUrlFromManifest(url: string, environment: cxapi.Environment, sdk: ISDK): string { const doNotUseMarker = '**DONOTUSE**'; // This URL may contain placeholders, so still substitute those. url = cxapi.EnvironmentPlaceholders.replace(url, { @@ -576,6 +562,6 @@ function restUrlFromManifest(url: string, environment: cxapi.Environment): strin const bucketName = s3Url[1]; const objectKey = s3Url[2]; - const urlSuffix: string = regionUtil.getEndpointSuffix(environment.region); + const urlSuffix: string = sdk.getEndpointSuffix(environment.region); return `https://s3.${environment.region}.${urlSuffix}/${bucketName}/${objectKey}`; } diff --git a/packages/aws-cdk/lib/api/hotswap-deployments.ts b/packages/aws-cdk/lib/api/hotswap-deployments.ts index 19b8405a7de19..08a22d3944437 100644 --- a/packages/aws-cdk/lib/api/hotswap-deployments.ts +++ b/packages/aws-cdk/lib/api/hotswap-deployments.ts @@ -36,8 +36,7 @@ export async function tryHotswapDeployment( account: resolvedEnv.account, region: resolvedEnv.region, partition: (await sdk.currentAccount()).partition, - // ToDo make this better: - urlSuffix: 'amazonaws.com', + urlSuffix: sdk.getEndpointSuffix, listStackResources, }); diff --git a/packages/aws-cdk/lib/api/hotswap/evaluate-cloudformation-template.ts b/packages/aws-cdk/lib/api/hotswap/evaluate-cloudformation-template.ts index 59d8d7df19445..5dc9f948a4250 100644 --- a/packages/aws-cdk/lib/api/hotswap/evaluate-cloudformation-template.ts +++ b/packages/aws-cdk/lib/api/hotswap/evaluate-cloudformation-template.ts @@ -16,7 +16,7 @@ export interface EvaluateCloudFormationTemplateProps { readonly account: string; readonly region: string; readonly partition: string; - readonly urlSuffix: string; + readonly urlSuffix: (region: string) => string; readonly listStackResources: ListStackResources; } @@ -27,6 +27,8 @@ export class EvaluateCloudFormationTemplate { private readonly account: string; private readonly region: string; private readonly partition: string; + private readonly urlSuffix: (region: string) => string; + private cachedUrlSuffix: string | undefined; constructor(props: EvaluateCloudFormationTemplateProps) { this.stackResources = props.listStackResources; @@ -35,12 +37,12 @@ export class EvaluateCloudFormationTemplate { 'AWS::AccountId': props.account, 'AWS::Region': props.region, 'AWS::Partition': props.partition, - 'AWS::URLSuffix': props.urlSuffix, ...props.parameters, }; this.account = props.account; this.region = props.region; this.partition = props.partition; + this.urlSuffix = props.urlSuffix; } public async findPhysicalNameFor(logicalId: string): Promise { @@ -184,6 +186,14 @@ export class EvaluateCloudFormationTemplate { private async findRefTarget(logicalId: string): Promise { // first, check to see if the Ref is a Parameter who's value we have + if (logicalId === 'AWS::URLSuffix') { + if (!this.cachedUrlSuffix) { + this.cachedUrlSuffix = this.urlSuffix(this.region); + } + + return this.cachedUrlSuffix; + } + const parameterTarget = this.context[logicalId]; if (parameterTarget) { return parameterTarget; diff --git a/packages/aws-cdk/test/api/deploy-stack.test.ts b/packages/aws-cdk/test/api/deploy-stack.test.ts index eb551ac528ec4..13e4640ff01ec 100644 --- a/packages/aws-cdk/test/api/deploy-stack.test.ts +++ b/packages/aws-cdk/test/api/deploy-stack.test.ts @@ -29,6 +29,7 @@ const FAKE_STACK_TERMINATION_PROTECTION = testStack({ let sdk: MockSdk; let sdkProvider: MockSdkProvider; let cfnMocks: MockedObject>; + beforeEach(() => { jest.resetAllMocks(); @@ -62,7 +63,7 @@ beforeEach(() => { updateTerminationProtection: jest.fn((_o) => ({ StackId: 'stack-id' })), }; sdk.stubCloudFormation(cfnMocks as any); - + sdk.stubGetEndpointSuffix(() => 'amazonaws.com'); }); function standardDeployStackArguments(): DeployStackOptions { diff --git a/packages/aws-cdk/test/api/hotswap/hotswap-deployments.test.ts b/packages/aws-cdk/test/api/hotswap/hotswap-deployments.test.ts index 26a8d08c27290..5d059df860cb8 100644 --- a/packages/aws-cdk/test/api/hotswap/hotswap-deployments.test.ts +++ b/packages/aws-cdk/test/api/hotswap/hotswap-deployments.test.ts @@ -4,13 +4,16 @@ import * as setup from './hotswap-test-setup'; let cfnMockProvider: setup.CfnMockProvider; let mockUpdateLambdaCode: (params: Lambda.Types.UpdateFunctionCodeRequest) => Lambda.Types.FunctionConfiguration; let mockUpdateMachineDefinition: (params: StepFunctions.Types.UpdateStateMachineInput) => StepFunctions.Types.UpdateStateMachineOutput; +let mockGetEndpointSuffix: () => string; beforeEach(() => { cfnMockProvider = setup.setupHotswapTests(); mockUpdateLambdaCode = jest.fn(); mockUpdateMachineDefinition = jest.fn(); + mockGetEndpointSuffix = jest.fn(() => 'amazonaws.com'); cfnMockProvider.setUpdateFunctionCodeMock(mockUpdateLambdaCode); cfnMockProvider.setUpdateStateMachineMock(mockUpdateMachineDefinition); + cfnMockProvider.stubGetEndpointSuffix(mockGetEndpointSuffix); }); test('returns a deployStackResult with noOp=true when it receives an empty set of changes', async () => { @@ -240,3 +243,69 @@ test('can correctly reference AWS::Partition in hotswappable changes', async () S3Key: 'new-key', }); }); + +test('can correctly reference AWS::URLSuffix in hotswappable changes', async () => { + // GIVEN + setup.setCurrentCfnStackTemplate({ + Resources: { + Func: { + Type: 'AWS::Lambda::Function', + Properties: { + Code: { + S3Bucket: 'current-bucket', + S3Key: 'current-key', + }, + FunctionName: { + 'Fn::Join': ['', [ + 'my-function-', + { Ref: 'AWS::URLSuffix' }, + '-', + { Ref: 'AWS::URLSuffix' }, + ]], + }, + }, + Metadata: { + 'aws:asset:path': 'old-path', + }, + }, + }, + }); + const cdkStackArtifact = setup.cdkStackArtifactOf({ + template: { + Resources: { + Func: { + Type: 'AWS::Lambda::Function', + Properties: { + Code: { + S3Bucket: 'current-bucket', + S3Key: 'new-key', + }, + FunctionName: { + 'Fn::Join': ['', [ + 'my-function-', + { Ref: 'AWS::URLSuffix' }, + '-', + { Ref: 'AWS::URLSuffix' }, + ]], + }, + }, + Metadata: { + 'aws:asset:path': 'new-path', + }, + }, + }, + }, + }); + + // WHEN + const deployStackResult = await cfnMockProvider.tryHotswapDeployment(cdkStackArtifact); + + // THEN + expect(deployStackResult).not.toBeUndefined(); + expect(mockUpdateLambdaCode).toHaveBeenCalledWith({ + FunctionName: 'my-function-amazonaws.com-amazonaws.com', + S3Bucket: 'current-bucket', + S3Key: 'new-key', + }); + expect(mockGetEndpointSuffix).toHaveBeenCalledTimes(1); +}); diff --git a/packages/aws-cdk/test/api/hotswap/hotswap-test-setup.ts b/packages/aws-cdk/test/api/hotswap/hotswap-test-setup.ts index c41d67752b791..87e06465c61dd 100644 --- a/packages/aws-cdk/test/api/hotswap/hotswap-test-setup.ts +++ b/packages/aws-cdk/test/api/hotswap/hotswap-test-setup.ts @@ -97,4 +97,8 @@ export class CfnMockProvider { ): Promise { return deployments.tryHotswapDeployment(this.mockSdkProvider, assetParams, currentCfnStack, stackArtifact); } + + public stubGetEndpointSuffix(stub: () => string) { + this.mockSdkProvider.stubGetEndpointSuffix(stub); + } } diff --git a/packages/aws-cdk/test/util/mock-sdk.ts b/packages/aws-cdk/test/util/mock-sdk.ts index 7b9b4f6fb8b1a..c9afd8cd13baa 100644 --- a/packages/aws-cdk/test/util/mock-sdk.ts +++ b/packages/aws-cdk/test/util/mock-sdk.ts @@ -109,6 +109,10 @@ export class MockSdkProvider extends SdkProvider { public stubStepFunctions(stubs: SyncHandlerSubsetOf) { (this.sdk as any).stepFunctions = jest.fn().mockReturnValue(partialAwsService(stubs)); } + + public stubGetEndpointSuffix(stub: () => string) { + this.sdk.getEndpointSuffix = stub; + } } export class MockSdk implements ISDK { @@ -125,6 +129,7 @@ export class MockSdk implements ISDK { public readonly secretsManager = jest.fn(); public readonly kms = jest.fn(); public readonly stepFunctions = jest.fn(); + public readonly getEndpointSuffix = jest.fn(); public currentAccount(): Promise { return Promise.resolve({ accountId: '123456789012', partition: 'aws' }); @@ -150,6 +155,13 @@ export class MockSdk implements ISDK { public stubSsm(stubs: SyncHandlerSubsetOf) { this.ssm.mockReturnValue(partialAwsService(stubs)); } + + /** + * Replace the getEndpointSuffix client with the given object + */ + public stubGetEndpointSuffix(stub: () => string) { + this.getEndpointSuffix.mockReturnValue(stub()); + } } /** From 9f3abd745c98a65e7314528f40d08ea2ecbe19a6 Mon Sep 17 00:00:00 2001 From: Ayush Goyal Date: Tue, 26 Oct 2021 04:58:49 +0530 Subject: [PATCH 037/148] feat(amplify): Add support for custom headers in the App (#17102) feat(amplify): Add support for custom headers in the App closes #17084 Refs: 1. https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-amplify-app.html#cfn-amplify-app-customheaders 2. https://docs.aws.amazon.com/amplify/latest/userguide/custom-headers.html 3. https://www.npmjs.com/package/yaml ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- package.json | 4 ++ packages/@aws-cdk/aws-amplify/NOTICE | 21 +++++++++++ packages/@aws-cdk/aws-amplify/README.md | 29 +++++++++++++++ packages/@aws-cdk/aws-amplify/lib/app.ts | 37 +++++++++++++++++++ packages/@aws-cdk/aws-amplify/package.json | 9 ++++- .../@aws-cdk/aws-amplify/test/app.test.ts | 31 ++++++++++++++++ .../aws-amplify/test/integ.app.expected.json | 1 + .../@aws-cdk/aws-amplify/test/integ.app.ts | 15 ++++++++ 8 files changed, 145 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7db1f7c20c0ad..6115ddc36950c 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,8 @@ "@aws-cdk/assertions-alpha/string-width/**", "@aws-cdk/assertions-alpha/table", "@aws-cdk/assertions-alpha/table/**", + "@aws-cdk/aws-amplify-alpha/yaml", + "@aws-cdk/aws-amplify-alpha/yaml/**", "@aws-cdk/assertions/colors", "@aws-cdk/assertions/colors/**", "@aws-cdk/assertions/diff", @@ -91,6 +93,8 @@ "@aws-cdk/assertions/string-width/**", "@aws-cdk/assertions/table", "@aws-cdk/assertions/table/**", + "@aws-cdk/aws-amplify/yaml", + "@aws-cdk/aws-amplify/yaml/**", "@aws-cdk/aws-codebuild/yaml", "@aws-cdk/aws-codebuild/yaml/**", "@aws-cdk/aws-codepipeline-actions/case", diff --git a/packages/@aws-cdk/aws-amplify/NOTICE b/packages/@aws-cdk/aws-amplify/NOTICE index 5fc3826926b5b..c84ff36099c3b 100644 --- a/packages/@aws-cdk/aws-amplify/NOTICE +++ b/packages/@aws-cdk/aws-amplify/NOTICE @@ -1,2 +1,23 @@ AWS Cloud Development Kit (AWS CDK) Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +------------------------------------------------------------------------------- + +The AWS CDK includes the following third-party software/licensing: + +** yaml - https://www.npmjs.com/package/yaml +Copyright 2018 Eemeli Aro + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +---------------- diff --git a/packages/@aws-cdk/aws-amplify/README.md b/packages/@aws-cdk/aws-amplify/README.md index 472846ea276b6..059588e493241 100644 --- a/packages/@aws-cdk/aws-amplify/README.md +++ b/packages/@aws-cdk/aws-amplify/README.md @@ -179,3 +179,32 @@ const amplifyApp = new amplify.App(this, 'MyApp', { autoBranchDeletion: true, // Automatically disconnect a branch when you delete a branch from your repository }); ``` + +## Adding custom response headers + +Use the `customResponseHeaders` prop to configure custom response headers for an Amplify app: + +```ts +const amplifyApp = new amplify.App(stack, 'App', { + sourceCodeProvider: new amplify.GitHubSourceCodeProvider({ + owner: '', + repository: '', + oauthToken: cdk.SecretValue.secretsManager('my-github-token') + }), + customResponseHeaders: [ + { + pattern: '*.json', + headers: { + 'custom-header-name-1': 'custom-header-value-1', + 'custom-header-name-2': 'custom-header-value-2', + }, + }, + { + pattern: '/path/*', + headers: { + 'custom-header-name-1': 'custom-header-value-2', + }, + }, + ], +}); +``` diff --git a/packages/@aws-cdk/aws-amplify/lib/app.ts b/packages/@aws-cdk/aws-amplify/lib/app.ts index 831921f89dbf8..030dc58059a6e 100644 --- a/packages/@aws-cdk/aws-amplify/lib/app.ts +++ b/packages/@aws-cdk/aws-amplify/lib/app.ts @@ -2,6 +2,7 @@ import * as codebuild from '@aws-cdk/aws-codebuild'; import * as iam from '@aws-cdk/aws-iam'; import { IResource, Lazy, Resource, SecretValue } from '@aws-cdk/core'; import { Construct } from 'constructs'; +import * as YAML from 'yaml'; import { CfnApp } from './amplify.generated'; import { BasicAuth } from './basic-auth'; import { Branch, BranchOptions } from './branch'; @@ -118,6 +119,16 @@ export interface AppProps { */ readonly buildSpec?: codebuild.BuildSpec; + + /** + * The custom HTTP response headers for an Amplify app. + * + * @see https://docs.aws.amazon.com/amplify/latest/userguide/custom-headers.html + * + * @default - no custom response headers + */ + readonly customResponseHeaders?: CustomResponseHeader[]; + /** * Custom rewrite/redirect rules for the application * @@ -238,6 +249,7 @@ export class App extends Resource implements IApp, iam.IGrantable { name: props.appName || this.node.id, oauthToken: sourceCodeProviderOptions?.oauthToken?.toString(), repository: sourceCodeProviderOptions?.repository, + customHeaders: props.customResponseHeaders ? renderCustomResponseHeaders(props.customResponseHeaders) : undefined, }); this.appId = app.attrAppId; @@ -486,3 +498,28 @@ export class CustomRule { this.condition = options.condition; } } + +/** + * Custom response header of an Amplify App. + */ +export interface CustomResponseHeader { + /** + * These custom headers will be applied to all URL file paths that match this pattern. + */ + readonly pattern: string; + + /** + * The map of custom headers to be applied. + */ + readonly headers: { [key: string]: string }; +} + +function renderCustomResponseHeaders(customHeaders: CustomResponseHeader[]): string { + const modifiedHeaders = customHeaders.map(customHeader => ({ + ...customHeader, + headers: Object.entries(customHeader.headers).map(([key, value]) => ({ key, value })), + })); + + const customHeadersObject = { customHeaders: modifiedHeaders }; + return YAML.stringify(customHeadersObject); +} diff --git a/packages/@aws-cdk/aws-amplify/package.json b/packages/@aws-cdk/aws-amplify/package.json index 13bbcc0ec61d4..7ee41fd004517 100644 --- a/packages/@aws-cdk/aws-amplify/package.json +++ b/packages/@aws-cdk/aws-amplify/package.json @@ -79,7 +79,8 @@ "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/jest": "^26.0.24" + "@types/jest": "^26.0.24", + "@types/yaml": "1.9.6" }, "dependencies": { "@aws-cdk/aws-codebuild": "0.0.0", @@ -88,8 +89,12 @@ "@aws-cdk/aws-kms": "0.0.0", "@aws-cdk/aws-secretsmanager": "0.0.0", "@aws-cdk/core": "0.0.0", - "constructs": "^3.3.69" + "constructs": "^3.3.69", + "yaml": "1.10.2" }, + "bundledDependencies": [ + "yaml" + ], "peerDependencies": { "@aws-cdk/aws-codebuild": "0.0.0", "@aws-cdk/aws-codecommit": "0.0.0", diff --git a/packages/@aws-cdk/aws-amplify/test/app.test.ts b/packages/@aws-cdk/aws-amplify/test/app.test.ts index 76b6830bec1c5..87b15e143ab7f 100644 --- a/packages/@aws-cdk/aws-amplify/test/app.test.ts +++ b/packages/@aws-cdk/aws-amplify/test/app.test.ts @@ -394,3 +394,34 @@ test('with auto branch deletion', () => { EnableBranchAutoDeletion: true, }); }); + +test('with custom headers', () => { + // WHEN + new amplify.App(stack, 'App', { + sourceCodeProvider: new amplify.GitHubSourceCodeProvider({ + owner: 'aws', + repository: 'aws-cdk', + oauthToken: SecretValue.plainText('secret'), + }), + customResponseHeaders: [ + { + pattern: '*.json', + headers: { + 'custom-header-name-1': 'custom-header-value-1', + 'custom-header-name-2': 'custom-header-value-2', + }, + }, + { + pattern: '/path/*', + headers: { + 'custom-header-name-1': 'custom-header-value-2', + }, + }, + ], + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::App', { + CustomHeaders: 'customHeaders:\n - pattern: "*.json"\n headers:\n - key: custom-header-name-1\n value: custom-header-value-1\n - key: custom-header-name-2\n value: custom-header-value-2\n - pattern: /path/*\n headers:\n - key: custom-header-name-1\n value: custom-header-value-2\n', + }); +}); diff --git a/packages/@aws-cdk/aws-amplify/test/integ.app.expected.json b/packages/@aws-cdk/aws-amplify/test/integ.app.expected.json index 25971c2ea44a7..d7ddd233378e1 100644 --- a/packages/@aws-cdk/aws-amplify/test/integ.app.expected.json +++ b/packages/@aws-cdk/aws-amplify/test/integ.app.expected.json @@ -54,6 +54,7 @@ }, "Username": "aws" }, + "CustomHeaders": "customHeaders:\n - pattern: \"*.json\"\n headers:\n - key: custom-header-name-1\n value: custom-header-value-1\n - key: custom-header-name-2\n value: custom-header-value-2\n - pattern: /path/*\n headers:\n - key: custom-header-name-1\n value: custom-header-value-2\n", "CustomRules": [ { "Source": "/source", diff --git a/packages/@aws-cdk/aws-amplify/test/integ.app.ts b/packages/@aws-cdk/aws-amplify/test/integ.app.ts index 83ff527a292e2..accdaed6840bf 100644 --- a/packages/@aws-cdk/aws-amplify/test/integ.app.ts +++ b/packages/@aws-cdk/aws-amplify/test/integ.app.ts @@ -9,6 +9,21 @@ class TestStack extends Stack { const amplifyApp = new amplify.App(this, 'App', { basicAuth: amplify.BasicAuth.fromGeneratedPassword('aws'), autoBranchCreation: {}, + customResponseHeaders: [ + { + pattern: '*.json', + headers: { + 'custom-header-name-1': 'custom-header-value-1', + 'custom-header-name-2': 'custom-header-value-2', + }, + }, + { + pattern: '/path/*', + headers: { + 'custom-header-name-1': 'custom-header-value-2', + }, + }, + ], }); amplifyApp.addCustomRule({ From aea7a609412732adfcdcf1b614b9b45708cae520 Mon Sep 17 00:00:00 2001 From: Madeline Kusters <80541297+madeline-k@users.noreply.github.com> Date: Mon, 25 Oct 2021 17:21:09 -0700 Subject: [PATCH 038/148] chore(dependency upgrade): upgrade jest dependency in cdk-build-tools due to CVE-2021-23440 (#17148) We have a security vulnerability coming from a transitive dependency on `set-value` through `jest`. See: https://github.com/aws/aws-cdk/security/dependabot/yarn.lock/set-value/open Generated this diff by: ``` cd tools/@aws-cdk/cdk-build-tools yarn remove jest yarn add jest@latest ``` ### Testing - Ran `yarn audit` to verify that the security vulnerability coming from a transitive dependency on `set-value` via `jest` is in fact gone. - Waiting for the PR build to see if this major version update caused any breaking changes for us. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- tools/@aws-cdk/cdk-build-tools/package.json | 12 +- yarn.lock | 773 +++++++++++++++++++- 2 files changed, 768 insertions(+), 17 deletions(-) diff --git a/tools/@aws-cdk/cdk-build-tools/package.json b/tools/@aws-cdk/cdk-build-tools/package.json index 84005357a2458..c8dfb507afc46 100644 --- a/tools/@aws-cdk/cdk-build-tools/package.json +++ b/tools/@aws-cdk/cdk-build-tools/package.json @@ -35,13 +35,15 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/pkglint": "0.0.0", "@types/fs-extra": "^8.1.2", "@types/jest": "^26.0.24", - "@types/yargs": "^15.0.14", "@types/semver": "^7.3.8", - "@aws-cdk/pkglint": "0.0.0" + "@types/yargs": "^15.0.14" }, "dependencies": { + "@aws-cdk/eslint-plugin": "0.0.0", + "@aws-cdk/yarn-cling": "0.0.0", "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", "awslint": "0.0.0", @@ -49,11 +51,10 @@ "eslint": "^7.32.0", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^2.5.0", - "@aws-cdk/eslint-plugin": "0.0.0", "eslint-plugin-import": "^2.25.2", "eslint-plugin-jest": "^24.7.0", "fs-extra": "^9.1.0", - "jest": "^26.6.3", + "jest": "^27.3.1", "jest-junit": "^11.1.0", "jsii": "^1.40.0", "jsii-pacmak": "^1.40.0", @@ -63,8 +64,7 @@ "semver": "^7.3.5", "ts-jest": "^26.5.6", "typescript": "~3.9.10", - "yargs": "^16.2.0", - "@aws-cdk/yarn-cling": "0.0.0" + "yargs": "^16.2.0" }, "keywords": [ "aws", diff --git a/yarn.lock b/yarn.lock index 442e61841ae13..c63b92155ae6a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -32,7 +32,7 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.15.8": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.15.8": version "7.15.8" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz#45990c47adadb00c03677baa89221f7cc23d2503" integrity sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg== @@ -44,7 +44,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== -"@babel/core@^7.1.0", "@babel/core@^7.7.5": +"@babel/core@^7.1.0", "@babel/core@^7.7.2", "@babel/core@^7.7.5": version "7.15.8" resolved "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz#195b9f2bffe995d2c6c159e72fe525b4114e8c10" integrity sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og== @@ -65,7 +65,7 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.15.4", "@babel/generator@^7.15.8": +"@babel/generator@^7.15.4", "@babel/generator@^7.15.8", "@babel/generator@^7.7.2": version "7.15.8" resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz#fa56be6b596952ceb231048cf84ee499a19c0cd1" integrity sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g== @@ -199,7 +199,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.15.4", "@babel/parser@^7.15.8": +"@babel/parser@^7.1.0", "@babel/parser@^7.15.4", "@babel/parser@^7.15.8", "@babel/parser@^7.7.2": version "7.15.8" resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz#7bacdcbe71bdc3ff936d510c15dcea7cf0b99016" integrity sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA== @@ -288,6 +288,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.14.5" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716" + integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/template@^7.15.4", "@babel/template@^7.3.3": version "7.15.4" resolved "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" @@ -297,7 +304,7 @@ "@babel/parser" "^7.15.4" "@babel/types" "^7.15.4" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.15.4": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.15.4", "@babel/traverse@^7.7.2": version "7.15.4" resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA== @@ -417,6 +424,18 @@ jest-util "^26.6.2" slash "^3.0.0" +"@jest/console@^27.3.1": + version "27.3.1" + resolved "https://registry.npmjs.org/@jest/console/-/console-27.3.1.tgz#e8ea3a475d3f8162f23d69efbfaa9cbe486bee93" + integrity sha512-RkFNWmv0iui+qsOr/29q9dyfKTTT5DCuP31kUwg7rmOKPT/ozLeGLKJKVIiOfbiKyleUZKIrHwhmiZWVe8IMdw== + dependencies: + "@jest/types" "^27.2.5" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^27.3.1" + jest-util "^27.3.1" + slash "^3.0.0" + "@jest/core@^26.6.3": version "26.6.3" resolved "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz#7639fcb3833d748a4656ada54bde193051e45fad" @@ -451,6 +470,40 @@ slash "^3.0.0" strip-ansi "^6.0.0" +"@jest/core@^27.3.1": + version "27.3.1" + resolved "https://registry.npmjs.org/@jest/core/-/core-27.3.1.tgz#04992ef1b58b17c459afb87ab56d81e63d386925" + integrity sha512-DMNE90RR5QKx0EA+wqe3/TNEwiRpOkhshKNxtLxd4rt3IZpCt+RSL+FoJsGeblRZmqdK4upHA/mKKGPPRAifhg== + dependencies: + "@jest/console" "^27.3.1" + "@jest/reporters" "^27.3.1" + "@jest/test-result" "^27.3.1" + "@jest/transform" "^27.3.1" + "@jest/types" "^27.2.5" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.4" + jest-changed-files "^27.3.0" + jest-config "^27.3.1" + jest-haste-map "^27.3.1" + jest-message-util "^27.3.1" + jest-regex-util "^27.0.6" + jest-resolve "^27.3.1" + jest-resolve-dependencies "^27.3.1" + jest-runner "^27.3.1" + jest-runtime "^27.3.1" + jest-snapshot "^27.3.1" + jest-util "^27.3.1" + jest-validate "^27.3.1" + jest-watcher "^27.3.1" + micromatch "^4.0.4" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + "@jest/environment@^26.6.2": version "26.6.2" resolved "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz#ba364cc72e221e79cc8f0a99555bf5d7577cf92c" @@ -461,6 +514,16 @@ "@types/node" "*" jest-mock "^26.6.2" +"@jest/environment@^27.3.1": + version "27.3.1" + resolved "https://registry.npmjs.org/@jest/environment/-/environment-27.3.1.tgz#2182defbce8d385fd51c5e7c7050f510bd4c86b1" + integrity sha512-BCKCj4mOVLme6Tanoyc9k0ultp3pnmuyHw73UHRPeeZxirsU/7E3HC4le/VDb/SMzE1JcPnto+XBKFOcoiJzVw== + dependencies: + "@jest/fake-timers" "^27.3.1" + "@jest/types" "^27.2.5" + "@types/node" "*" + jest-mock "^27.3.0" + "@jest/fake-timers@^26.6.2": version "26.6.2" resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad" @@ -473,6 +536,18 @@ jest-mock "^26.6.2" jest-util "^26.6.2" +"@jest/fake-timers@^27.3.1": + version "27.3.1" + resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.1.tgz#1fad860ee9b13034762cdb94266e95609dfce641" + integrity sha512-M3ZFgwwlqJtWZ+QkBG5NmC23A9w+A6ZxNsO5nJxJsKYt4yguBd3i8TpjQz5NfCX91nEve1KqD9RA2Q+Q1uWqoA== + dependencies: + "@jest/types" "^27.2.5" + "@sinonjs/fake-timers" "^8.0.1" + "@types/node" "*" + jest-message-util "^27.3.1" + jest-mock "^27.3.0" + jest-util "^27.3.1" + "@jest/globals@^26.6.2": version "26.6.2" resolved "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz#5b613b78a1aa2655ae908eba638cc96a20df720a" @@ -482,6 +557,15 @@ "@jest/types" "^26.6.2" expect "^26.6.2" +"@jest/globals@^27.3.1": + version "27.3.1" + resolved "https://registry.npmjs.org/@jest/globals/-/globals-27.3.1.tgz#ce1dfb03d379237a9da6c1b99ecfaca1922a5f9e" + integrity sha512-Q651FWiWQAIFiN+zS51xqhdZ8g9b88nGCobC87argAxA7nMfNQq0Q0i9zTfQYgLa6qFXk2cGANEqfK051CZ8Pg== + dependencies: + "@jest/environment" "^27.3.1" + "@jest/types" "^27.2.5" + expect "^27.3.1" + "@jest/reporters@^26.6.2": version "26.6.2" resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz#1f518b99637a5f18307bd3ecf9275f6882a667f6" @@ -514,6 +598,37 @@ optionalDependencies: node-notifier "^8.0.0" +"@jest/reporters@^27.3.1": + version "27.3.1" + resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.1.tgz#28b5c1f5789481e23788048fa822ed15486430b9" + integrity sha512-m2YxPmL9Qn1emFVgZGEiMwDntDxRRQ2D58tiDQlwYTg5GvbFOKseYCcHtn0WsI8CG4vzPglo3nqbOiT8ySBT/w== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^27.3.1" + "@jest/test-result" "^27.3.1" + "@jest/transform" "^27.3.1" + "@jest/types" "^27.2.5" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.2.4" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^4.0.3" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.0.2" + jest-haste-map "^27.3.1" + jest-resolve "^27.3.1" + jest-util "^27.3.1" + jest-worker "^27.3.1" + slash "^3.0.0" + source-map "^0.6.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^8.1.0" + "@jest/source-map@^26.6.2": version "26.6.2" resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535" @@ -523,6 +638,15 @@ graceful-fs "^4.2.4" source-map "^0.6.0" +"@jest/source-map@^27.0.6": + version "27.0.6" + resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz#be9e9b93565d49b0548b86e232092491fb60551f" + integrity sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.4" + source-map "^0.6.0" + "@jest/test-result@^26.6.2": version "26.6.2" resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18" @@ -533,6 +657,16 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" +"@jest/test-result@^27.3.1": + version "27.3.1" + resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.1.tgz#89adee8b771877c69b3b8d59f52f29dccc300194" + integrity sha512-mLn6Thm+w2yl0opM8J/QnPTqrfS4FoXsXF2WIWJb2O/GBSyResL71BRuMYbYRsGt7ELwS5JGcEcGb52BNrumgg== + dependencies: + "@jest/console" "^27.3.1" + "@jest/types" "^27.2.5" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + "@jest/test-sequencer@^26.6.3": version "26.6.3" resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz#98e8a45100863886d074205e8ffdc5a7eb582b17" @@ -544,6 +678,16 @@ jest-runner "^26.6.3" jest-runtime "^26.6.3" +"@jest/test-sequencer@^27.3.1": + version "27.3.1" + resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.1.tgz#4b3bde2dbb05ee74afdae608cf0768e3354683b1" + integrity sha512-siySLo07IMEdSjA4fqEnxfIX8lB/lWYsBPwNFtkOvsFQvmBrL3yj3k3uFNZv/JDyApTakRpxbKLJ3CT8UGVCrA== + dependencies: + "@jest/test-result" "^27.3.1" + graceful-fs "^4.2.4" + jest-haste-map "^27.3.1" + jest-runtime "^27.3.1" + "@jest/transform@^26.6.2": version "26.6.2" resolved "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" @@ -565,6 +709,27 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" +"@jest/transform@^27.3.1": + version "27.3.1" + resolved "https://registry.npmjs.org/@jest/transform/-/transform-27.3.1.tgz#ff80eafbeabe811e9025e4b6f452126718455220" + integrity sha512-3fSvQ02kuvjOI1C1ssqMVBKJpZf6nwoCiSu00zAKh5nrp3SptNtZy/8s5deayHnqxhjD9CWDJ+yqQwuQ0ZafXQ== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^27.2.5" + babel-plugin-istanbul "^6.0.0" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.4" + jest-haste-map "^27.3.1" + jest-regex-util "^27.0.6" + jest-util "^27.3.1" + micromatch "^4.0.4" + pirates "^4.0.1" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + "@jest/types@^26.6.2": version "26.6.2" resolved "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" @@ -576,6 +741,17 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@jest/types@^27.2.5": + version "27.2.5" + resolved "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz#420765c052605e75686982d24b061b4cbba22132" + integrity sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + "@jsii/check-node@1.40.0": version "1.40.0" resolved "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.40.0.tgz#49882a61ad1b3a37cd35c35fa1a2301955f1c058" @@ -1528,6 +1704,13 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@sinonjs/fake-timers@^8.0.1": + version "8.0.1" + resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.0.1.tgz#1c1c9a91419f804e59ae8df316a07dd1c3a76b94" + integrity sha512-AU7kwFxreVd6OAXcAFlKSmZquiRUU0FvYm44k1Y1QbK7Co4m0aqfGMhjykIeQp/H6rcl+nFmj0zfdUcGVs9Dew== + dependencies: + "@sinonjs/commons" "^1.7.0" + "@sinonjs/samsam@^5.3.1": version "5.3.1" resolved "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz#375a45fe6ed4e92fca2fb920e007c48232a6507f" @@ -1588,7 +1771,7 @@ resolved "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.84.tgz#b1f391ceeb6908b28d8416d93f27afe8d1348d4e" integrity sha512-5V78eLtmN0d4RA14hKDwcsMQRl3JotQJlhGFDBo/jdE2TyDFRaYwB/UmMUC4SzhSvRGn+YMkh7jGPnXi8COAng== -"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7": +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.7": version "7.1.16" resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz#bc12c74b7d65e82d29876b5d0baf5c625ac58702" integrity sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ== @@ -1764,7 +1947,7 @@ resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== -"@types/prettier@^2.0.0": +"@types/prettier@^2.0.0", "@types/prettier@^2.1.5": version "2.4.1" resolved "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz#e1303048d5389563e130f5bdd89d37a99acb75eb" integrity sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw== @@ -1858,6 +2041,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/yargs@^16.0.0": + version "16.0.4" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" + integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + dependencies: + "@types/yargs-parser" "*" + "@types/yarnpkg__lockfile@^1.1.5": version "1.1.5" resolved "https://registry.npmjs.org/@types/yarnpkg__lockfile/-/yarnpkg__lockfile-1.1.5.tgz#9639020e1fb65120a2f4387db8f1e8b63efdf229" @@ -2060,6 +2250,11 @@ ansi-regex@^2.0.0: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" @@ -2084,6 +2279,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -2365,6 +2565,20 @@ babel-jest@^26.6.3: graceful-fs "^4.2.4" slash "^3.0.0" +babel-jest@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.1.tgz#0636a3404c68e07001e434ac4956d82da8a80022" + integrity sha512-SjIF8hh/ir0peae2D6S6ZKRhUy7q/DnpH7k/V6fT4Bgs/LXXUztOpX4G2tCgq8mLo5HA9mN6NmlFMeYtKmIsTQ== + dependencies: + "@jest/transform" "^27.3.1" + "@jest/types" "^27.2.5" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.0.0" + babel-preset-jest "^27.2.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" + slash "^3.0.0" + babel-plugin-istanbul@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" @@ -2386,6 +2600,16 @@ babel-plugin-jest-hoist@^26.6.2: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" +babel-plugin-jest-hoist@^27.2.0: + version "27.2.0" + resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz#79f37d43f7e5c4fdc4b2ca3e10cc6cf545626277" + integrity sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + babel-preset-current-node-syntax@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" @@ -2412,6 +2636,14 @@ babel-preset-jest@^26.6.2: babel-plugin-jest-hoist "^26.6.2" babel-preset-current-node-syntax "^1.0.0" +babel-preset-jest@^27.2.0: + version "27.2.0" + resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz#556bbbf340608fed5670ab0ea0c8ef2449fba885" + integrity sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg== + dependencies: + babel-plugin-jest-hoist "^27.2.0" + babel-preset-current-node-syntax "^1.0.0" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -2748,11 +2980,21 @@ ci-info@^2.0.0: resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +ci-info@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6" + integrity sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A== + cjs-module-lexer@^0.6.0: version "0.6.0" resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz#4186fcca0eae175970aee870b9fe2d6cf8d5655f" integrity sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw== +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -2836,6 +3078,11 @@ co@^4.6.0: resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + codemaker@^1.39.0: version "1.39.0" resolved "https://registry.npmjs.org/codemaker/-/codemaker-1.39.0.tgz#d8103f4b587210b1d6aa073d62ffb510ac20bc42" @@ -3529,6 +3776,11 @@ diff-sequences@^26.6.2: resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== +diff-sequences@^27.0.6: + version "27.0.6" + resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723" + integrity sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ== + diff@^4.0.1, diff@^4.0.2: version "4.0.2" resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" @@ -3636,6 +3888,11 @@ emittery@^0.7.1: resolved "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82" integrity sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ== +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -4207,6 +4464,18 @@ expect@^26.6.2: jest-message-util "^26.6.2" jest-regex-util "^26.0.0" +expect@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/expect/-/expect-27.3.1.tgz#d0f170b1f5c8a2009bab0beffd4bb94f043e38e7" + integrity sha512-MrNXV2sL9iDRebWPGOGFdPQRl2eDQNu/uhxIMShjjx74T6kC6jFIkmQ6OqXDtevjGUkyB2IT56RzDBqXf/QPCg== + dependencies: + "@jest/types" "^27.2.5" + ansi-styles "^5.0.0" + jest-get-type "^27.3.1" + jest-matcher-utils "^27.3.1" + jest-message-util "^27.3.1" + jest-regex-util "^27.0.6" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -4554,7 +4823,7 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^2.1.2: +fsevents@^2.1.2, fsevents@^2.3.2: version "2.3.2" resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -5267,6 +5536,18 @@ is-extglob@^2.1.1: resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -5563,6 +5844,40 @@ jest-changed-files@^26.6.2: execa "^4.0.0" throat "^5.0.0" +jest-changed-files@^27.3.0: + version "27.3.0" + resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz#22a02cc2b34583fc66e443171dc271c0529d263c" + integrity sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg== + dependencies: + "@jest/types" "^27.2.5" + execa "^5.0.0" + throat "^6.0.1" + +jest-circus@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.1.tgz#1679e74387cbbf0c6a8b42de963250a6469e0797" + integrity sha512-v1dsM9II6gvXokgqq6Yh2jHCpfg7ZqV4jWY66u7npz24JnhP3NHxI0sKT7+ZMQ7IrOWHYAaeEllOySbDbWsiXw== + dependencies: + "@jest/environment" "^27.3.1" + "@jest/test-result" "^27.3.1" + "@jest/types" "^27.2.5" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.3.1" + is-generator-fn "^2.0.0" + jest-each "^27.3.1" + jest-matcher-utils "^27.3.1" + jest-message-util "^27.3.1" + jest-runtime "^27.3.1" + jest-snapshot "^27.3.1" + jest-util "^27.3.1" + pretty-format "^27.3.1" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" + jest-cli@^26.6.3: version "26.6.3" resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz#43117cfef24bc4cd691a174a8796a532e135e92a" @@ -5582,6 +5897,24 @@ jest-cli@^26.6.3: prompts "^2.0.1" yargs "^15.4.1" +jest-cli@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.1.tgz#b576f9d146ba6643ce0a162d782b40152b6b1d16" + integrity sha512-WHnCqpfK+6EvT62me6WVs8NhtbjAS4/6vZJnk7/2+oOr50cwAzG4Wxt6RXX0hu6m1169ZGMlhYYUNeKBXCph/Q== + dependencies: + "@jest/core" "^27.3.1" + "@jest/test-result" "^27.3.1" + "@jest/types" "^27.2.5" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.4" + import-local "^3.0.2" + jest-config "^27.3.1" + jest-util "^27.3.1" + jest-validate "^27.3.1" + prompts "^2.0.1" + yargs "^16.2.0" + jest-config@^26.6.3: version "26.6.3" resolved "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz#64f41444eef9eb03dc51d5c53b75c8c71f645349" @@ -5606,6 +5939,33 @@ jest-config@^26.6.3: micromatch "^4.0.2" pretty-format "^26.6.2" +jest-config@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-config/-/jest-config-27.3.1.tgz#cb3b7f6aaa8c0a7daad4f2b9573899ca7e09bbad" + integrity sha512-KY8xOIbIACZ/vdYCKSopL44I0xboxC751IX+DXL2+Wx6DKNycyEfV3rryC3BPm5Uq/BBqDoMrKuqLEUNJmMKKg== + dependencies: + "@babel/core" "^7.1.0" + "@jest/test-sequencer" "^27.3.1" + "@jest/types" "^27.2.5" + babel-jest "^27.3.1" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.1" + graceful-fs "^4.2.4" + jest-circus "^27.3.1" + jest-environment-jsdom "^27.3.1" + jest-environment-node "^27.3.1" + jest-get-type "^27.3.1" + jest-jasmine2 "^27.3.1" + jest-regex-util "^27.0.6" + jest-resolve "^27.3.1" + jest-runner "^27.3.1" + jest-util "^27.3.1" + jest-validate "^27.3.1" + micromatch "^4.0.4" + pretty-format "^27.3.1" + jest-diff@^26.0.0, jest-diff@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" @@ -5616,6 +5976,16 @@ jest-diff@^26.0.0, jest-diff@^26.6.2: jest-get-type "^26.3.0" pretty-format "^26.6.2" +jest-diff@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.1.tgz#d2775fea15411f5f5aeda2a5e02c2f36440f6d55" + integrity sha512-PCeuAH4AWUo2O5+ksW4pL9v5xJAcIKPUPfIhZBcG1RKv/0+dvaWTQK1Nrau8d67dp65fOqbeMdoil+6PedyEPQ== + dependencies: + chalk "^4.0.0" + diff-sequences "^27.0.6" + jest-get-type "^27.3.1" + pretty-format "^27.3.1" + jest-docblock@^26.0.0: version "26.0.0" resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5" @@ -5623,6 +5993,13 @@ jest-docblock@^26.0.0: dependencies: detect-newline "^3.0.0" +jest-docblock@^27.0.6: + version "27.0.6" + resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz#cc78266acf7fe693ca462cbbda0ea4e639e4e5f3" + integrity sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA== + dependencies: + detect-newline "^3.0.0" + jest-each@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz#02526438a77a67401c8a6382dfe5999952c167cb" @@ -5634,6 +6011,17 @@ jest-each@^26.6.2: jest-util "^26.6.2" pretty-format "^26.6.2" +jest-each@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-each/-/jest-each-27.3.1.tgz#14c56bb4f18dd18dc6bdd853919b5f16a17761ff" + integrity sha512-E4SwfzKJWYcvOYCjOxhZcxwL+AY0uFMvdCOwvzgutJiaiodFjkxQQDxHm8FQBeTqDnSmKsQWn7ldMRzTn2zJaQ== + dependencies: + "@jest/types" "^27.2.5" + chalk "^4.0.0" + jest-get-type "^27.3.1" + jest-util "^27.3.1" + pretty-format "^27.3.1" + jest-environment-jsdom@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz#78d09fe9cf019a357009b9b7e1f101d23bd1da3e" @@ -5647,6 +6035,19 @@ jest-environment-jsdom@^26.6.2: jest-util "^26.6.2" jsdom "^16.4.0" +jest-environment-jsdom@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.1.tgz#63ac36d68f7a9303494df783494856222b57f73e" + integrity sha512-3MOy8qMzIkQlfb3W1TfrD7uZHj+xx8Olix5vMENkj5djPmRqndMaXtpnaZkxmxM+Qc3lo+yVzJjzuXbCcZjAlg== + dependencies: + "@jest/environment" "^27.3.1" + "@jest/fake-timers" "^27.3.1" + "@jest/types" "^27.2.5" + "@types/node" "*" + jest-mock "^27.3.0" + jest-util "^27.3.1" + jsdom "^16.6.0" + jest-environment-node@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz#824e4c7fb4944646356f11ac75b229b0035f2b0c" @@ -5659,11 +6060,28 @@ jest-environment-node@^26.6.2: jest-mock "^26.6.2" jest-util "^26.6.2" +jest-environment-node@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.1.tgz#af7d0eed04edafb740311b303f3fe7c8c27014bb" + integrity sha512-T89F/FgkE8waqrTSA7/ydMkcc52uYPgZZ6q8OaZgyiZkJb5QNNCF6oPZjH9IfPFfcc9uBWh1574N0kY0pSvTXw== + dependencies: + "@jest/environment" "^27.3.1" + "@jest/fake-timers" "^27.3.1" + "@jest/types" "^27.2.5" + "@types/node" "*" + jest-mock "^27.3.0" + jest-util "^27.3.1" + jest-get-type@^26.3.0: version "26.3.0" resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== +jest-get-type@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.3.1.tgz#a8a2b0a12b50169773099eee60a0e6dd11423eff" + integrity sha512-+Ilqi8hgHSAdhlQ3s12CAVNd8H96ZkQBfYoXmArzZnOfAtVAJEiPDBirjByEblvG/4LPJmkL+nBqPO3A1YJAEg== + jest-haste-map@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" @@ -5685,6 +6103,26 @@ jest-haste-map@^26.6.2: optionalDependencies: fsevents "^2.1.2" +jest-haste-map@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.1.tgz#7656fbd64bf48bda904e759fc9d93e2c807353ee" + integrity sha512-lYfNZIzwPccDJZIyk9Iz5iQMM/MH56NIIcGj7AFU1YyA4ewWFBl8z+YPJuSCRML/ee2cCt2y3W4K3VXPT6Nhzg== + dependencies: + "@jest/types" "^27.2.5" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + jest-regex-util "^27.0.6" + jest-serializer "^27.0.6" + jest-util "^27.3.1" + jest-worker "^27.3.1" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + jest-jasmine2@^26.6.3: version "26.6.3" resolved "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz#adc3cf915deacb5212c93b9f3547cd12958f2edd" @@ -5709,6 +6147,30 @@ jest-jasmine2@^26.6.3: pretty-format "^26.6.2" throat "^5.0.0" +jest-jasmine2@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.1.tgz#df6d3d07c7dafc344feb43a0072a6f09458d32b0" + integrity sha512-WK11ZUetDQaC09w4/j7o4FZDUIp+4iYWH/Lik34Pv7ukL+DuXFGdnmmi7dT58J2ZYKFB5r13GyE0z3NPeyJmsg== + dependencies: + "@babel/traverse" "^7.1.0" + "@jest/environment" "^27.3.1" + "@jest/source-map" "^27.0.6" + "@jest/test-result" "^27.3.1" + "@jest/types" "^27.2.5" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + expect "^27.3.1" + is-generator-fn "^2.0.0" + jest-each "^27.3.1" + jest-matcher-utils "^27.3.1" + jest-message-util "^27.3.1" + jest-runtime "^27.3.1" + jest-snapshot "^27.3.1" + jest-util "^27.3.1" + pretty-format "^27.3.1" + throat "^6.0.1" + jest-junit@^11.1.0: version "11.1.0" resolved "https://registry.npmjs.org/jest-junit/-/jest-junit-11.1.0.tgz#79cd53948e44d62b2b30fa23ea0d7a899d2c8d7a" @@ -5737,6 +6199,14 @@ jest-leak-detector@^26.6.2: jest-get-type "^26.3.0" pretty-format "^26.6.2" +jest-leak-detector@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.1.tgz#7fb632c2992ef707a1e73286e1e704f9cc1772b2" + integrity sha512-78QstU9tXbaHzwlRlKmTpjP9k4Pvre5l0r8Spo4SbFFVy/4Abg9I6ZjHwjg2QyKEAMg020XcjP+UgLZIY50yEg== + dependencies: + jest-get-type "^27.3.1" + pretty-format "^27.3.1" + jest-matcher-utils@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a" @@ -5747,6 +6217,16 @@ jest-matcher-utils@^26.6.2: jest-get-type "^26.3.0" pretty-format "^26.6.2" +jest-matcher-utils@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.1.tgz#257ad61e54a6d4044e080d85dbdc4a08811e9c1c" + integrity sha512-hX8N7zXS4k+8bC1Aj0OWpGb7D3gIXxYvPNK1inP5xvE4ztbz3rc4AkI6jGVaerepBnfWB17FL5lWFJT3s7qo8w== + dependencies: + chalk "^4.0.0" + jest-diff "^27.3.1" + jest-get-type "^27.3.1" + pretty-format "^27.3.1" + jest-message-util@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" @@ -5762,6 +6242,21 @@ jest-message-util@^26.6.2: slash "^3.0.0" stack-utils "^2.0.2" +jest-message-util@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.1.tgz#f7c25688ad3410ab10bcb862bcfe3152345c6436" + integrity sha512-bh3JEmxsTZ/9rTm0jQrPElbY2+y48Rw2t47uMfByNyUVR+OfPh4anuyKsGqsNkXk/TI4JbLRZx+7p7Hdt6q1yg== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.2.5" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" + micromatch "^4.0.4" + pretty-format "^27.3.1" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302" @@ -5770,6 +6265,14 @@ jest-mock@^26.6.2: "@jest/types" "^26.6.2" "@types/node" "*" +jest-mock@^27.3.0: + version "27.3.0" + resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz#ddf0ec3cc3e68c8ccd489bef4d1f525571a1b867" + integrity sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw== + dependencies: + "@jest/types" "^27.2.5" + "@types/node" "*" + jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" @@ -5780,6 +6283,11 @@ jest-regex-util@^26.0.0: resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== +jest-regex-util@^27.0.6: + version "27.0.6" + resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz#02e112082935ae949ce5d13b2675db3d8c87d9c5" + integrity sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ== + jest-resolve-dependencies@^26.6.3: version "26.6.3" resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz#6680859ee5d22ee5dcd961fe4871f59f4c784fb6" @@ -5789,6 +6297,15 @@ jest-resolve-dependencies@^26.6.3: jest-regex-util "^26.0.0" jest-snapshot "^26.6.2" +jest-resolve-dependencies@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.1.tgz#85b99bdbdfa46e2c81c6228fc4c91076f624f6e2" + integrity sha512-X7iLzY8pCiYOnvYo2YrK3P9oSE8/3N2f4pUZMJ8IUcZnT81vlSonya1KTO9ZfKGuC+svE6FHK/XOb8SsoRUV1A== + dependencies: + "@jest/types" "^27.2.5" + jest-regex-util "^27.0.6" + jest-snapshot "^27.3.1" + jest-resolve@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz#a3ab1517217f469b504f1b56603c5bb541fbb507" @@ -5803,6 +6320,22 @@ jest-resolve@^26.6.2: resolve "^1.18.1" slash "^3.0.0" +jest-resolve@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.1.tgz#0e5542172a1aa0270be6f66a65888647bdd74a3e" + integrity sha512-Dfzt25CFSPo3Y3GCbxynRBZzxq9AdyNN+x/v2IqYx6KVT5Z6me2Z/PsSGFSv3cOSUZqJ9pHxilao/I/m9FouLw== + dependencies: + "@jest/types" "^27.2.5" + chalk "^4.0.0" + graceful-fs "^4.2.4" + jest-haste-map "^27.3.1" + jest-pnp-resolver "^1.2.2" + jest-util "^27.3.1" + jest-validate "^27.3.1" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + jest-runner@^26.6.3: version "26.6.3" resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz#2d1fed3d46e10f233fd1dbd3bfaa3fe8924be159" @@ -5829,6 +6362,34 @@ jest-runner@^26.6.3: source-map-support "^0.5.6" throat "^5.0.0" +jest-runner@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.1.tgz#1d594dcbf3bd8600a7e839e790384559eaf96e3e" + integrity sha512-r4W6kBn6sPr3TBwQNmqE94mPlYVn7fLBseeJfo4E2uCTmAyDFm2O5DYAQAFP7Q3YfiA/bMwg8TVsciP7k0xOww== + dependencies: + "@jest/console" "^27.3.1" + "@jest/environment" "^27.3.1" + "@jest/test-result" "^27.3.1" + "@jest/transform" "^27.3.1" + "@jest/types" "^27.2.5" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.4" + jest-docblock "^27.0.6" + jest-environment-jsdom "^27.3.1" + jest-environment-node "^27.3.1" + jest-haste-map "^27.3.1" + jest-leak-detector "^27.3.1" + jest-message-util "^27.3.1" + jest-resolve "^27.3.1" + jest-runtime "^27.3.1" + jest-util "^27.3.1" + jest-worker "^27.3.1" + source-map-support "^0.5.6" + throat "^6.0.1" + jest-runtime@^26.6.3: version "26.6.3" resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz#4f64efbcfac398331b74b4b3c82d27d401b8fa2b" @@ -5862,6 +6423,38 @@ jest-runtime@^26.6.3: strip-bom "^4.0.0" yargs "^15.4.1" +jest-runtime@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.1.tgz#80fa32eb85fe5af575865ddf379874777ee993d7" + integrity sha512-qtO6VxPbS8umqhEDpjA4pqTkKQ1Hy4ZSi9mDVeE9Za7LKBo2LdW2jmT+Iod3XFaJqINikZQsn2wEi0j9wPRbLg== + dependencies: + "@jest/console" "^27.3.1" + "@jest/environment" "^27.3.1" + "@jest/globals" "^27.3.1" + "@jest/source-map" "^27.0.6" + "@jest/test-result" "^27.3.1" + "@jest/transform" "^27.3.1" + "@jest/types" "^27.2.5" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.4" + jest-haste-map "^27.3.1" + jest-message-util "^27.3.1" + jest-mock "^27.3.0" + jest-regex-util "^27.0.6" + jest-resolve "^27.3.1" + jest-snapshot "^27.3.1" + jest-util "^27.3.1" + jest-validate "^27.3.1" + slash "^3.0.0" + strip-bom "^4.0.0" + yargs "^16.2.0" + jest-serializer@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" @@ -5870,6 +6463,14 @@ jest-serializer@^26.6.2: "@types/node" "*" graceful-fs "^4.2.4" +jest-serializer@^27.0.6: + version "27.0.6" + resolved "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz#93a6c74e0132b81a2d54623251c46c498bb5bec1" + integrity sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.4" + jest-snapshot@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz#f3b0af1acb223316850bd14e1beea9837fb39c84" @@ -5892,6 +6493,36 @@ jest-snapshot@^26.6.2: pretty-format "^26.6.2" semver "^7.3.2" +jest-snapshot@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.1.tgz#1da5c0712a252d70917d46c037054f5918c49ee4" + integrity sha512-APZyBvSgQgOT0XumwfFu7X3G5elj6TGhCBLbBdn3R1IzYustPGPE38F51dBWMQ8hRXa9je0vAdeVDtqHLvB6lg== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/parser" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.0.0" + "@jest/transform" "^27.3.1" + "@jest/types" "^27.2.5" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.3.1" + graceful-fs "^4.2.4" + jest-diff "^27.3.1" + jest-get-type "^27.3.1" + jest-haste-map "^27.3.1" + jest-matcher-utils "^27.3.1" + jest-message-util "^27.3.1" + jest-resolve "^27.3.1" + jest-util "^27.3.1" + natural-compare "^1.4.0" + pretty-format "^27.3.1" + semver "^7.3.2" + jest-util@^26.1.0, jest-util@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" @@ -5904,6 +6535,18 @@ jest-util@^26.1.0, jest-util@^26.6.2: is-ci "^2.0.0" micromatch "^4.0.2" +jest-util@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-util/-/jest-util-27.3.1.tgz#a58cdc7b6c8a560caac9ed6bdfc4e4ff23f80429" + integrity sha512-8fg+ifEH3GDryLQf/eKZck1DEs2YuVPBCMOaHQxVVLmQwl/CDhWzrvChTX4efLZxGrw+AA0mSXv78cyytBt/uw== + dependencies: + "@jest/types" "^27.2.5" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.4" + picomatch "^2.2.3" + jest-validate@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec" @@ -5916,6 +6559,18 @@ jest-validate@^26.6.2: leven "^3.1.0" pretty-format "^26.6.2" +jest-validate@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.1.tgz#3a395d61a19cd13ae9054af8cdaf299116ef8a24" + integrity sha512-3H0XCHDFLA9uDII67Bwi1Vy7AqwA5HqEEjyy934lgVhtJ3eisw6ShOF1MDmRPspyikef5MyExvIm0/TuLzZ86Q== + dependencies: + "@jest/types" "^27.2.5" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.3.1" + leven "^3.1.0" + pretty-format "^27.3.1" + jest-watcher@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz#a5b683b8f9d68dbcb1d7dae32172d2cca0592975" @@ -5929,6 +6584,19 @@ jest-watcher@^26.6.2: jest-util "^26.6.2" string-length "^4.0.1" +jest-watcher@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.1.tgz#ba5e0bc6aa843612b54ddb7f009d1cbff7e05f3e" + integrity sha512-9/xbV6chABsGHWh9yPaAGYVVKurWoP3ZMCv6h+O1v9/+pkOroigs6WzZ0e9gLP/njokUwM7yQhr01LKJVMkaZA== + dependencies: + "@jest/test-result" "^27.3.1" + "@jest/types" "^27.2.5" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^27.3.1" + string-length "^4.0.1" + jest-worker@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" @@ -5938,6 +6606,15 @@ jest-worker@^26.6.2: merge-stream "^2.0.0" supports-color "^7.0.0" +jest-worker@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz#0def7feae5b8042be38479799aeb7b5facac24b2" + integrity sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + jest@^26.6.3: version "26.6.3" resolved "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz#40e8fdbe48f00dfa1f0ce8121ca74b88ac9148ef" @@ -5947,6 +6624,15 @@ jest@^26.6.3: import-local "^3.0.2" jest-cli "^26.6.3" +jest@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/jest/-/jest-27.3.1.tgz#b5bab64e8f56b6f7e275ba1836898b0d9f1e5c8a" + integrity sha512-U2AX0AgQGd5EzMsiZpYt8HyZ+nSVIh5ujQ9CPp9EQZJMjXIiSZpJNweZl0swatKRoqHWgGKM3zaSwm4Zaz87ng== + dependencies: + "@jest/core" "^27.3.1" + import-local "^3.0.2" + jest-cli "^27.3.1" + jmespath@0.15.0: version "0.15.0" resolved "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" @@ -5982,7 +6668,7 @@ jsbn@~0.1.0: resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsdom@^16.4.0: +jsdom@^16.4.0, jsdom@^16.6.0: version "16.7.0" resolved "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== @@ -7286,6 +7972,11 @@ null-check@^1.0.0: resolved "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" integrity sha1-l33/1xdgErnsMNKjnbXPcqBDnt0= +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" @@ -7873,6 +8564,16 @@ pretty-format@^26.0.0, pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" +pretty-format@^27.3.1: + version "27.3.1" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz#7e9486365ccdd4a502061fa761d3ab9ca1b78df5" + integrity sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA== + dependencies: + "@jest/types" "^27.2.5" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + printj@~1.1.0: version "1.1.2" resolved "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" @@ -8321,6 +9022,11 @@ resolve-url@^0.2.1: resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.1, resolve@^1.18.1, resolve@^1.20.0: version "1.20.0" resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" @@ -8830,7 +9536,7 @@ ssri@^8.0.0, ssri@^8.0.1: dependencies: minipass "^3.1.1" -stack-utils@^2.0.2: +stack-utils@^2.0.2, stack-utils@^2.0.3: version "2.0.5" resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== @@ -8893,7 +9599,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -string-width@*, string-width@^1.0.1, "string-width@^1.0.2 || 2", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +string-width@*, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -8902,6 +9608,23 @@ string-width@*, string-width@^1.0.1, "string-width@^1.0.2 || 2", string-width@^4 is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + string.prototype.repeat@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz#aba36de08dcee6a5a337d49b2ea1da1b28fc0ecf" @@ -8954,6 +9677,13 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" @@ -9023,6 +9753,13 @@ supports-color@^7.0.0, supports-color@^7.1.0, supports-color@^7.2.0: dependencies: has-flag "^4.0.0" +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + supports-hyperlinks@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" @@ -9145,6 +9882,11 @@ throat@^5.0.0: resolved "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== +throat@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + through2@^2.0.0: version "2.0.5" resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -9607,6 +10349,15 @@ v8-to-istanbul@^7.0.0: convert-source-map "^1.6.0" source-map "^0.7.3" +v8-to-istanbul@^8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz#0aeb763894f1a0a1676adf8a8b7612a38902446c" + integrity sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" From e1bf1b9e1813bf3964f3fd63139dc814fde8d8fb Mon Sep 17 00:00:00 2001 From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com> Date: Mon, 25 Oct 2021 23:13:31 -0400 Subject: [PATCH 039/148] docs(stepfunctions): make examples compile (#17141) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-stepfunctions/README.md | 135 ++++++++++++------ .../rosetta/default.ts-fixture | 14 ++ .../scripts/verify-readme-import-rewrites.ts | 4 +- 3 files changed, 107 insertions(+), 46 deletions(-) create mode 100644 packages/@aws-cdk/aws-stepfunctions/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-stepfunctions/README.md b/packages/@aws-cdk/aws-stepfunctions/README.md index 52aa717e6d1a2..e74367df84676 100644 --- a/packages/@aws-cdk/aws-stepfunctions/README.md +++ b/packages/@aws-cdk/aws-stepfunctions/README.md @@ -22,13 +22,10 @@ example](https://docs.aws.amazon.com/step-functions/latest/dg/job-status-poller- ## Example ```ts -import * as cdk from '@aws-cdk/core'; -import * as sfn from '@aws-cdk/aws-stepfunctions'; -import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; import * as lambda from '@aws-cdk/aws-lambda'; -const submitLambda = new lambda.Function(this, 'SubmitLambda', { ... }); -const getStatusLambda = new lambda.Function(this, 'CheckLambda', { ... }); +declare const submitLambda: lambda.Function; +declare const getStatusLambda: lambda.Function; const submitJob = new tasks.LambdaInvoke(this, 'Submit Job', { lambdaFunction: submitLambda, @@ -71,7 +68,7 @@ const definition = submitJob new sfn.StateMachine(this, 'StateMachine', { definition, - timeout: cdk.Duration.minutes(5), + timeout: Duration.minutes(5), }); ``` @@ -145,6 +142,7 @@ const pass = new sfn.Pass(this, 'Add Hello World', { }); // Set the next state +const nextState = new sfn.Pass(this, 'NextState'); pass.next(nextState); ``` @@ -183,6 +181,7 @@ const wait = new sfn.Wait(this, 'Wait For Trigger Time', { }); // Set the next state +const startTheWork = new sfn.Pass(this, 'StartTheWork'); wait.next(startTheWork); ``` @@ -195,10 +194,13 @@ values in the execution's JSON state: const choice = new sfn.Choice(this, 'Did it work?'); // Add conditions with .when() +const successState = new sfn.Pass(this, 'SuccessState'); +const failureState = new sfn.Pass(this, 'FailureState'); choice.when(sfn.Condition.stringEquals('$.status', 'SUCCESS'), successState); choice.when(sfn.Condition.numberGreaterThan('$.attempts', 5), failureState); // Use .otherwise() to indicate what should be done if none of the conditions match +const tryAgainState = new sfn.Pass(this, 'TryAgainState'); choice.otherwise(tryAgainState); ``` @@ -208,11 +210,15 @@ then ... else` works in a programming language), use the `.afterwards()` method: ```ts const choice = new sfn.Choice(this, 'What color is it?'); +const handleBlueItem = new sfn.Pass(this, 'HandleBlueItem'); +const handleRedItem = new sfn.Pass(this, 'HandleRedItem'); +const handleOtherItemColor = new sfn.Pass(this, 'HanldeOtherItemColor'); choice.when(sfn.Condition.stringEquals('$.color', 'BLUE'), handleBlueItem); choice.when(sfn.Condition.stringEquals('$.color', 'RED'), handleRedItem); choice.otherwise(handleOtherItemColor); // Use .afterwards() to join all possible paths back together and continue +const shipTheItem = new sfn.Pass(this, 'ShipTheItem'); choice.afterwards().next(shipTheItem); ``` @@ -279,6 +285,9 @@ be used to catch and recover from errors in subworkflows. const parallel = new sfn.Parallel(this, 'Do the work in parallel'); // Add branches to be executed in parallel +const shipItem = new sfn.Pass(this, 'ShipItem'); +const sendInvoice = new sfn.Pass(this, 'SendInvoice'); +const restock = new sfn.Pass(this, 'Restock'); parallel.branch(shipItem); parallel.branch(sendInvoice); parallel.branch(restock); @@ -287,9 +296,11 @@ parallel.branch(restock); parallel.addRetry({ maxAttempts: 1 }); // How to recover from errors +const sendFailureNotification = new sfn.Pass(this, 'SendFailureNotification'); parallel.addCatch(sendFailureNotification); // What to do in case everything succeeded +const closeOrder = new sfn.Pass(this, 'CloseOrder'); parallel.next(closeOrder); ``` @@ -354,19 +365,17 @@ the State Machine uses. The following example uses the `DynamoDB` service integration to insert data into a DynamoDB table. ```ts -import * as cdk from '@aws-cdk/core'; -import * as ddb from '@aws-cdk/aws-dynamodb'; -import * as sfn from '@aws-cdk/aws-stepfunctions'; +import * as dynamodb from '@aws-cdk/aws-dynamodb'; // create a table -const table = new ddb.Table(this, 'montable', { +const table = new dynamodb.Table(this, 'montable', { partitionKey: { name: 'id', - type: ddb.AttributeType.STRING, + type: dynamodb.AttributeType.STRING, }, }); -const finalStatus = new sfn.Pass(stack, 'final step'); +const finalStatus = new sfn.Pass(this, 'final step'); // States language JSON to put an item into DynamoDB // snippet generated from https://docs.aws.amazon.com/step-functions/latest/dg/tutorial-code-snippet.html#tutorial-code-snippet-1 @@ -394,7 +403,7 @@ const chain = sfn.Chain.start(custom) const sm = new sfn.StateMachine(this, 'StateMachine', { definition: chain, - timeout: cdk.Duration.seconds(30), + timeout: Duration.seconds(30), }); // don't forget permissions. You need to assign them @@ -410,6 +419,21 @@ In particular, the `.next()` method can be repeated. The result of a series of targets of `Choice.on` or `Parallel.branch`: ```ts +const step1 = new sfn.Pass(this, 'Step1'); +const step2 = new sfn.Pass(this, 'Step2'); +const step3 = new sfn.Pass(this, 'Step3'); +const step4 = new sfn.Pass(this, 'Step4'); +const step5 = new sfn.Pass(this, 'Step5'); +const step6 = new sfn.Pass(this, 'Step6'); +const step7 = new sfn.Pass(this, 'Step7'); +const step8 = new sfn.Pass(this, 'Step8'); +const step9 = new sfn.Pass(this, 'Step9'); +const step10 = new sfn.Pass(this, 'Step10'); +const choice = new sfn.Choice(this, 'Choice'); +const condition1 = sfn.Condition.stringEquals('$.status', 'SUCCESS'); +const parallel = new sfn.Parallel(this, 'Parallel'); +const finish = new sfn.Pass(this, 'Finish'); + const definition = step1 .next(step2) .next(choice @@ -430,6 +454,10 @@ If you don't like the visual look of starting a chain directly off the first step, you can use `Chain.start`: ```ts +const step1 = new sfn.Pass(this, 'Step1'); +const step2 = new sfn.Pass(this, 'Step2'); +const step3 = new sfn.Pass(this, 'Step3'); + const definition = sfn.Chain .start(step1) .next(step2) @@ -456,7 +484,11 @@ The class `StateMachineFragment` contains some helper functions (like `prefixStates()`) to make it easier for you to do this. If you define your state machine as a subclass of this, it will be convenient to use: -```ts +```ts nofixture +import { Construct, Stack } from '@aws-cdk/core'; +import * as sfn from '@aws-cdk/aws-stepfunctions'; +import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; + interface MyJobProps { jobFlavor: string; } @@ -465,23 +497,30 @@ class MyJob extends sfn.StateMachineFragment { public readonly startState: sfn.State; public readonly endStates: sfn.INextable[]; - constructor(parent: cdk.Construct, id: string, props: MyJobProps) { + constructor(parent: Construct, id: string, props: MyJobProps) { super(parent, id); - const first = new sfn.Task(this, 'First', { ... }); + const choice = new sfn.Choice(this, 'Choice') + .when(sfn.Condition.stringEquals('$.branch', 'left'), new sfn.Pass(this, 'Left Branch')) + .when(sfn.Condition.stringEquals('$.branch', 'right'), new sfn.Pass(this, 'Right Branch')); + // ... - const last = new sfn.Task(this, 'Last', { ... }); - this.startState = first; - this.endStates = [last]; + this.startState = choice; + this.endStates = choice.afterwards().endStates; } } -// Do 3 different variants of MyJob in parallel -new sfn.Parallel(this, 'All jobs') - .branch(new MyJob(this, 'Quick', { jobFlavor: 'quick' }).prefixStates()) - .branch(new MyJob(this, 'Medium', { jobFlavor: 'medium' }).prefixStates()) - .branch(new MyJob(this, 'Slow', { jobFlavor: 'slow' }).prefixStates()); +class MyStack extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + // Do 3 different variants of MyJob in parallel + new sfn.Parallel(this, 'All jobs') + .branch(new MyJob(this, 'Quick', { jobFlavor: 'quick' }).prefixStates()) + .branch(new MyJob(this, 'Medium', { jobFlavor: 'medium' }).prefixStates()) + .branch(new MyJob(this, 'Slow', { jobFlavor: 'slow' }).prefixStates()); + } +} ``` A few utility functions are available to parse state machine fragments. @@ -504,7 +543,7 @@ const activity = new sfn.Activity(this, 'Activity'); // Read this CloudFormation Output from your application and use it to poll for work on // the activity. -new cdk.CfnOutput(this, 'ActivityArn', { value: activity.activityArn }); +new CfnOutput(this, 'ActivityArn', { value: activity.activityArn }); ``` ### Activity-Level Permissions @@ -514,7 +553,7 @@ Granting IAM permissions to an activity can be achieved by calling the `grant(pr ```ts const activity = new sfn.Activity(this, 'Activity'); -const role = new iam.Role(stack, 'Role', { +const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), }); @@ -529,6 +568,7 @@ This will grant the IAM principal the specified actions onto the activity. to create an alarm on a particular task failing: ```ts +declare const task: sfn.Task; new cloudwatch.Alarm(this, 'TaskAlarm', { metric: task.metricFailed(), threshold: 1, @@ -539,6 +579,7 @@ new cloudwatch.Alarm(this, 'TaskAlarm', { There are also metrics on the complete state machine: ```ts +declare const stateMachine: sfn.StateMachine; new cloudwatch.Alarm(this, 'StateMachineAlarm', { metric: stateMachine.metricFailed(), threshold: 1, @@ -550,7 +591,7 @@ And there are metrics on the capacity of all state machines in your account: ```ts new cloudwatch.Alarm(this, 'ThrottledAlarm', { - metric: StateTransitionMetrics.metricThrottledEvents(), + metric: sfn.StateTransitionMetric.metricThrottledEvents(), threshold: 10, evaluationPeriods: 2, }); @@ -578,10 +619,12 @@ Enable logging to CloudWatch by passing a logging configuration with a destination LogGroup: ```ts -const logGroup = new logs.LogGroup(stack, 'MyLogGroup'); +import * as logs from '@aws-cdk/aws-logs'; + +const logGroup = new logs.LogGroup(this, 'MyLogGroup'); -new sfn.StateMachine(stack, 'MyStateMachine', { - definition: sfn.Chain.start(new sfn.Pass(stack, 'Pass')), +new sfn.StateMachine(this, 'MyStateMachine', { + definition: sfn.Chain.start(new sfn.Pass(this, 'Pass')), logs: { destination: logGroup, level: sfn.LogLevel.ALL, @@ -594,8 +637,8 @@ new sfn.StateMachine(stack, 'MyStateMachine', { Enable X-Ray tracing for StateMachine: ```ts -new sfn.StateMachine(stack, 'MyStateMachine', { - definition: sfn.Chain.start(new sfn.Pass(stack, 'Pass')), +new sfn.StateMachine(this, 'MyStateMachine', { + definition: sfn.Chain.start(new sfn.Pass(this, 'Pass')), tracingEnabled: true, }); ``` @@ -620,11 +663,12 @@ Any object that implements the `IGrantable` interface (has an associated princip Grant permission to start an execution of a state machine by calling the `grantStartExecution()` API. ```ts -const role = new iam.Role(stack, 'Role', { +const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), }); -const stateMachine = new stepfunction.StateMachine(stack, 'StateMachine', { +declare const definition: sfn.IChainable; +const stateMachine = new sfn.StateMachine(this, 'StateMachine', { definition, }); @@ -641,11 +685,12 @@ The following permission is provided to a service principal by the `grantStartEx Grant `read` access to a state machine by calling the `grantRead()` API. ```ts -const role = new iam.Role(stack, 'Role', { +const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), }); -const stateMachine = new stepfunction.StateMachine(stack, 'StateMachine', { +declare const definition: sfn.IChainable; +const stateMachine = new sfn.StateMachine(this, 'StateMachine', { definition, }); @@ -669,11 +714,12 @@ The following read permissions are provided to a service principal by the `grant Grant permission to allow task responses to a state machine by calling the `grantTaskResponse()` API: ```ts -const role = new iam.Role(stack, 'Role', { +const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), }); -const stateMachine = new stepfunction.StateMachine(stack, 'StateMachine', { +declare const definition: sfn.IChainable; +const stateMachine = new sfn.StateMachine(this, 'StateMachine', { definition, }); @@ -692,11 +738,12 @@ The following read permissions are provided to a service principal by the `grant Grant execution-level permissions to a state machine by calling the `grantExecution()` API: ```ts -const role = new iam.Role(stack, 'Role', { +const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), }); -const stateMachine = new stepfunction.StateMachine(stack, 'StateMachine', { +declare const definition: sfn.IChainable; +const stateMachine = new sfn.StateMachine(this, 'StateMachine', { definition, }); @@ -709,9 +756,10 @@ stateMachine.grantExecution(role, 'states:GetExecutionHistory'); You can add any set of permissions to a state machine by calling the `grant()` API. ```ts -const user = new iam.User(stack, 'MyUser'); +const user = new iam.User(this, 'MyUser'); -const stateMachine = new stepfunction.StateMachine(stack, 'StateMachine', { +declare const definition: sfn.IChainable; +const stateMachine = new sfn.StateMachine(this, 'StateMachine', { definition, }); @@ -727,8 +775,7 @@ into your CDK stack. State machines can be imported by their ARN via the `StateMachine.fromStateMachineArn()` API ```ts -import * as sfn from 'aws-stepfunctions'; - +const app = new App(); const stack = new Stack(app, 'MyStack'); sfn.StateMachine.fromStateMachineArn( stack, diff --git a/packages/@aws-cdk/aws-stepfunctions/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-stepfunctions/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..91085b6c8933c --- /dev/null +++ b/packages/@aws-cdk/aws-stepfunctions/rosetta/default.ts-fixture @@ -0,0 +1,14 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { App, CfnOutput, Duration, Stack } from '@aws-cdk/core'; +import sfn = require('@aws-cdk/aws-stepfunctions'); +import tasks = require('@aws-cdk/aws-stepfunctions-tasks'); +import cloudwatch = require('@aws-cdk/aws-cloudwatch'); +import iam = require('@aws-cdk/aws-iam'); + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + /// here + } +} diff --git a/packages/aws-cdk-lib/scripts/verify-readme-import-rewrites.ts b/packages/aws-cdk-lib/scripts/verify-readme-import-rewrites.ts index a31f721c05dfc..a2e3569573ef4 100644 --- a/packages/aws-cdk-lib/scripts/verify-readme-import-rewrites.ts +++ b/packages/aws-cdk-lib/scripts/verify-readme-import-rewrites.ts @@ -23,7 +23,7 @@ const jsiiManifest = JSON.parse(fs.readFileSync(jsiiManifestPath, { encoding: 'u // If this test fails because one of the below import statements is invalid, // please update to have a new, comparable example. // This is admittedly a bit fragile; if this test breaks a lot, we should reconsider validation methodology. -// Count of times this test has been broken by README updates so far (please increment as necessary! :D): 0 +// Count of times this test has been broken by README updates so far (please increment as necessary! :D): 1 const EXPECTED_SUBMODULE_IMPORTS = { // import * as origins from '@aws-cdk/aws-cloudfront-origins'; 'aws-cdk-lib.aws_cloudfront_origins': "import { aws_cloudfront_origins as origins } from 'aws-cdk-lib';", @@ -34,7 +34,7 @@ const EXPECTED_SUBMODULE_IMPORTS = { // import { Rule, Schedule } from '@aws-cdk/aws-events'; 'aws-cdk-lib.aws_events': "import { Rule, Schedule } from 'aws-cdk-lib/aws-events';", // import * as cdk from '@aws-cdk/core'; - 'aws-cdk-lib.aws_stepfunctions': "import * as cdk from 'aws-cdk-lib';", + 'aws-cdk-lib.aws_rds': "import * as cdk from 'aws-cdk-lib';", }; Object.entries(EXPECTED_SUBMODULE_IMPORTS).forEach(([submodule, importStatement]) => { From 55d3c507707192d7aa5ea4a38ee0d1cb58f07e06 Mon Sep 17 00:00:00 2001 From: Hassan Azhar <57677979+hassanazharkhan@users.noreply.github.com> Date: Tue, 26 Oct 2021 14:11:41 +0500 Subject: [PATCH 040/148] feat(lambda-nodejs): typescript emitDecoratorMetadata support (#16543) closes [#13767](https://github.com/aws/aws-cdk/issues/13767) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-lambda-nodejs/README.md | 16 ++ .../@aws-cdk/aws-lambda-nodejs/lib/Dockerfile | 3 + .../aws-lambda-nodejs/lib/bundling.ts | 64 +++++- ...nstallation.ts => package-installation.ts} | 14 +- .../@aws-cdk/aws-lambda-nodejs/lib/types.ts | 10 + .../aws-lambda-nodejs/test/bundling.test.ts | 109 +++++++++- .../integ-handlers/ts-decorator-handler.ts | 23 ++ .../test/integ.compilations.expected.json | 198 ++++++++++++++++++ .../test/integ.compilations.ts | 39 ++++ ...n.test.ts => package-installation.test.ts} | 8 +- 10 files changed, 460 insertions(+), 24 deletions(-) rename packages/@aws-cdk/aws-lambda-nodejs/lib/{esbuild-installation.ts => package-installation.ts} (59%) create mode 100644 packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/ts-decorator-handler.ts create mode 100644 packages/@aws-cdk/aws-lambda-nodejs/test/integ.compilations.expected.json create mode 100644 packages/@aws-cdk/aws-lambda-nodejs/test/integ.compilations.ts rename packages/@aws-cdk/aws-lambda-nodejs/test/{esbuild-installation.test.ts => package-installation.test.ts} (84%) diff --git a/packages/@aws-cdk/aws-lambda-nodejs/README.md b/packages/@aws-cdk/aws-lambda-nodejs/README.md index 2c0572231a8ae..6e901612539d8 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/README.md +++ b/packages/@aws-cdk/aws-lambda-nodejs/README.md @@ -225,6 +225,22 @@ an array of commands to run. Commands are chained with `&&`. The commands will run in the environment in which bundling occurs: inside the container for Docker bundling or on the host OS for local bundling. +## Pre Compilation with TSC + +In some cases, `esbuild` may not yet support some newer features of the typescript language, such as, +[`emitDecoratorMetadata`](https://www.typescriptlang.org/tsconfig#emitDecoratorMetadata). +In such cases, it is possible to run pre-compilation using `tsc` by setting the `preCompilation` flag. + +```ts +new lambda.NodejsFunction(this, 'my-handler', { + bundling: { + preCompilation: true, + }, +}); +``` + +Note: A [`tsconfig.json` file](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) is required + ## Customizing Docker bundling Use `bundling.environment` to define environments variables when `esbuild` runs: diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/Dockerfile b/packages/@aws-cdk/aws-lambda-nodejs/lib/Dockerfile index 578b1b8135d5c..54969bb5fde2c 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/Dockerfile +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/Dockerfile @@ -9,6 +9,9 @@ RUN npm install --global yarn@1.22.5 # Install pnpm RUN npm install --global pnpm +# Install typescript +RUN npm install --global typescript + # Install esbuild # (unsafe-perm because esbuild has a postinstall script) ARG ESBUILD_VERSION=0 diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts index 3db8b21c3f592..e53e5e092de7c 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts @@ -2,7 +2,7 @@ import * as os from 'os'; import * as path from 'path'; import { Architecture, AssetCode, Code, Runtime } from '@aws-cdk/aws-lambda'; import * as cdk from '@aws-cdk/core'; -import { EsbuildInstallation } from './esbuild-installation'; +import { PackageInstallation } from './package-installation'; import { PackageManager } from './package-manager'; import { BundlingOptions, SourceMapMode } from './types'; import { exec, extractDependencies, findUp } from './util'; @@ -37,6 +37,12 @@ export interface BundlingProps extends BundlingOptions { * Path to project root */ readonly projectRoot: string; + + /** + * Run compilation using `tsc` before bundling + */ + readonly preCompilation?: boolean + } /** @@ -57,7 +63,17 @@ export class Bundling implements cdk.BundlingOptions { this.esbuildInstallation = undefined; } - private static esbuildInstallation?: EsbuildInstallation; + public static clearTscInstallationCache(): void { + this.tscInstallation = undefined; + } + + public static clearTscCompilationCache(): void { + this.tscCompiled = false; + } + + private static esbuildInstallation?: PackageInstallation; + private static tscInstallation?: PackageInstallation; + private static tscCompiled = false // Core bundling options public readonly image: cdk.DockerImage; @@ -76,7 +92,8 @@ export class Bundling implements cdk.BundlingOptions { constructor(private readonly props: BundlingProps) { this.packageManager = PackageManager.fromLockFile(props.depsLockFilePath); - Bundling.esbuildInstallation = Bundling.esbuildInstallation ?? EsbuildInstallation.detect(); + Bundling.esbuildInstallation = Bundling.esbuildInstallation ?? PackageInstallation.detect('esbuild'); + Bundling.tscInstallation = Bundling.tscInstallation ?? PackageInstallation.detect('tsc'); this.projectRoot = props.projectRoot; this.relativeEntryPath = path.relative(this.projectRoot, path.resolve(props.entry)); @@ -90,6 +107,10 @@ export class Bundling implements cdk.BundlingOptions { this.relativeTsconfigPath = path.relative(this.projectRoot, path.resolve(props.tsconfig)); } + if (props.preCompilation && !/\.tsx?$/.test(props.entry)) { + throw new Error('preCompilation can only be used with typescript files'); + } + this.externals = [ ...props.externalModules ?? ['aws-sdk'], // Mark aws-sdk as external by default (available in the runtime) ...props.nodeModules ?? [], // Mark the modules that we are going to install as externals also @@ -97,8 +118,8 @@ export class Bundling implements cdk.BundlingOptions { // Docker bundling const shouldBuildImage = props.forceDockerBundling || !Bundling.esbuildInstallation; - this.image = shouldBuildImage - ? props.dockerImage ?? cdk.DockerImage.fromBuild(path.join(__dirname, '../lib'), { + this.image = shouldBuildImage ? props.dockerImage ?? cdk.DockerImage.fromBuild(path.join(__dirname, '../lib'), + { buildArgs: { ...props.buildArgs ?? {}, IMAGE: props.runtime.bundlingImage.image, @@ -112,6 +133,7 @@ export class Bundling implements cdk.BundlingOptions { inputDir: cdk.AssetStaging.BUNDLING_INPUT_DIR, outputDir: cdk.AssetStaging.BUNDLING_OUTPUT_DIR, esbuildRunner: 'esbuild', // esbuild is installed globally in the docker image + tscRunner: 'tsc', // tsc is installed globally in the docker image osPlatform: 'linux', // linux docker image }); this.command = ['bash', '-c', bundlingCommand]; @@ -128,6 +150,27 @@ export class Bundling implements cdk.BundlingOptions { private createBundlingCommand(options: BundlingCommandOptions): string { const pathJoin = osPathJoin(options.osPlatform); + let tscCommand: string = ''; + let relativeEntryPath = this.relativeEntryPath; + + if (this.props.preCompilation) { + + let tsconfig = this.relativeTsconfigPath; + if (!tsconfig) { + const findConfig = findUp('tsconfig.json', path.dirname(this.props.entry)); + if (!findConfig) { + throw new Error('Cannot find a tsconfig.json, please specify the prop: tsconfig'); + } + tsconfig = path.relative(this.projectRoot, findConfig); + } + + relativeEntryPath = relativeEntryPath.replace(/\.ts(x?)$/, '.js$1'); + if (!Bundling.tscCompiled) { + // Intentionally Setting rootDir and outDir, so that the compiled js file always end up next ts file. + tscCommand = `${options.tscRunner} --project ${pathJoin(options.inputDir, tsconfig)} --rootDir ./ --outDir ./`; + Bundling.tscCompiled = true; + } + } const loaders = Object.entries(this.props.loader ?? {}); const defines = Object.entries(this.props.define ?? {}); @@ -135,14 +178,14 @@ export class Bundling implements cdk.BundlingOptions { if (this.props.sourceMap === false && this.props.sourceMapMode) { throw new Error('sourceMapMode cannot be used when sourceMap is false'); } - // eslint-disable-next-line no-console + const sourceMapEnabled = this.props.sourceMapMode ?? this.props.sourceMap; const sourceMapMode = this.props.sourceMapMode ?? SourceMapMode.DEFAULT; const sourceMapValue = sourceMapMode === SourceMapMode.DEFAULT ? '' : `=${this.props.sourceMapMode}`; const esbuildCommand: string[] = [ options.esbuildRunner, - '--bundle', `"${pathJoin(options.inputDir, this.relativeEntryPath)}"`, + '--bundle', `"${pathJoin(options.inputDir, relativeEntryPath)}"`, `--target=${this.props.target ?? toTarget(this.props.runtime)}`, '--platform=node', `--outfile="${pathJoin(options.outputDir, 'index.js')}"`, @@ -185,6 +228,7 @@ export class Bundling implements cdk.BundlingOptions { return chain([ ...this.props.commandHooks?.beforeBundling(options.inputDir, options.outputDir) ?? [], + tscCommand, esbuildCommand.join(' '), ...(this.props.nodeModules && this.props.commandHooks?.beforeInstall(options.inputDir, options.outputDir)) ?? [], depsCommand, @@ -194,10 +238,11 @@ export class Bundling implements cdk.BundlingOptions { private getLocalBundlingProvider(): cdk.ILocalBundling { const osPlatform = os.platform(); - const createLocalCommand = (outputDir: string, esbuild: EsbuildInstallation) => this.createBundlingCommand({ + const createLocalCommand = (outputDir: string, esbuild: PackageInstallation, tsc?: PackageInstallation) => this.createBundlingCommand({ inputDir: this.projectRoot, outputDir, esbuildRunner: esbuild.isLocal ? this.packageManager.runBinCommand('esbuild') : 'esbuild', + tscRunner: tsc && (tsc.isLocal ? this.packageManager.runBinCommand('tsc') : 'tsc'), osPlatform, }); const environment = this.props.environment ?? {}; @@ -214,7 +259,7 @@ export class Bundling implements cdk.BundlingOptions { throw new Error(`Expected esbuild version ${ESBUILD_MAJOR_VERSION}.x but got ${Bundling.esbuildInstallation.version}`); } - const localCommand = createLocalCommand(outputDir, Bundling.esbuildInstallation); + const localCommand = createLocalCommand(outputDir, Bundling.esbuildInstallation, Bundling.tscInstallation); exec( osPlatform === 'win32' ? 'cmd' : 'bash', @@ -243,6 +288,7 @@ interface BundlingCommandOptions { readonly inputDir: string; readonly outputDir: string; readonly esbuildRunner: string; + readonly tscRunner?: string; readonly osPlatform: NodeJS.Platform; } diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/esbuild-installation.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/package-installation.ts similarity index 59% rename from packages/@aws-cdk/aws-lambda-nodejs/lib/esbuild-installation.ts rename to packages/@aws-cdk/aws-lambda-nodejs/lib/package-installation.ts index 8ef2e8dbb23d9..789246badcceb 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/esbuild-installation.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/package-installation.ts @@ -2,13 +2,13 @@ import { spawnSync } from 'child_process'; import { tryGetModuleVersion } from './util'; /** - * An esbuild installation + * Package installation */ -export abstract class EsbuildInstallation { - public static detect(): EsbuildInstallation | undefined { +export abstract class PackageInstallation { + public static detect(module: string): PackageInstallation | undefined { try { // Check local version first - const version = tryGetModuleVersion('esbuild'); + const version = tryGetModuleVersion(module); if (version) { return { isLocal: true, @@ -17,11 +17,11 @@ export abstract class EsbuildInstallation { } // Fallback to a global version - const esbuild = spawnSync('esbuild', ['--version']); - if (esbuild.status === 0 && !esbuild.error) { + const proc = spawnSync(module, ['--version']); + if (proc.status === 0 && !proc.error) { return { isLocal: false, - version: esbuild.stdout.toString().trim(), + version: proc.stdout.toString().trim(), }; } return undefined; diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts index 8d0d263fe64e6..6bd26c846c6fe 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts @@ -197,6 +197,16 @@ export interface BundlingOptions { */ readonly forceDockerBundling?: boolean; + /** + * Run compilation using tsc before running file through bundling step. + * This usually is not required unless you are using new experimental features that + * are only supported by typescript's `tsc` compiler. + * One example of such feature is `emitDecoratorMetadata`. + * + * @default false + */ + readonly preCompilation?: boolean + /** * A custom bundling Docker image. * diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts index df70c1437d356..02b6030ae3e12 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts @@ -5,20 +5,22 @@ import { Architecture, Code, Runtime } from '@aws-cdk/aws-lambda'; import { AssetHashType, DockerImage } from '@aws-cdk/core'; import { version as delayVersion } from 'delay/package.json'; import { Bundling } from '../lib/bundling'; -import { EsbuildInstallation } from '../lib/esbuild-installation'; +import { PackageInstallation } from '../lib/package-installation'; import { LogLevel, SourceMapMode } from '../lib/types'; import * as util from '../lib/util'; -let detectEsbuildMock: jest.SpyInstance; + +let detectPackageInstallationMock: jest.SpyInstance; beforeEach(() => { jest.clearAllMocks(); jest.resetAllMocks(); jest.restoreAllMocks(); Bundling.clearEsbuildInstallationCache(); + Bundling.clearTscInstallationCache(); jest.spyOn(Code, 'fromAsset'); - detectEsbuildMock = jest.spyOn(EsbuildInstallation, 'detect').mockReturnValue({ + detectPackageInstallationMock = jest.spyOn(PackageInstallation, 'detect').mockReturnValue({ isLocal: true, version: '0.8.8', }); @@ -429,7 +431,7 @@ test('Local bundling', () => { test('Incorrect esbuild version', () => { - detectEsbuildMock.mockReturnValueOnce({ + detectPackageInstallationMock.mockReturnValueOnce({ isLocal: true, version: '3.4.5', }); @@ -554,3 +556,102 @@ test('esbuild bundling with projectRoot and externals and dependencies', () => { }), }); }); + +test('esbuild bundling with pre compilations', () => { + Bundling.bundle({ + entry, + projectRoot, + depsLockFilePath, + runtime: Runtime.NODEJS_14_X, + forceDockerBundling: true, + tsconfig, + preCompilation: true, + architecture: Architecture.X86_64, + }); + + // Correctly bundles with esbuild + expect(Code.fromAsset).toHaveBeenCalledWith(path.dirname(depsLockFilePath), { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + command: [ + 'bash', '-c', + [ + 'tsc --project /asset-input/lib/custom-tsconfig.ts --rootDir ./ --outDir ./ &&', + 'esbuild --bundle \"/asset-input/lib/handler.js\" --target=node14 --platform=node --outfile=\"/asset-output/index.js\"', + '--external:aws-sdk --tsconfig=/asset-input/lib/custom-tsconfig.ts', + ].join(' '), + ], + }), + }); + + Bundling.bundle({ + entry, + projectRoot, + depsLockFilePath, + runtime: Runtime.NODEJS_14_X, + forceDockerBundling: true, + tsconfig, + preCompilation: true, + architecture: Architecture.X86_64, + }); + + // Correctly bundles with esbuild + expect(Code.fromAsset).toHaveBeenCalledWith(path.dirname(depsLockFilePath), { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + command: [ + 'bash', '-c', + [ + 'esbuild --bundle \"/asset-input/lib/handler.js\" --target=node14 --platform=node --outfile=\"/asset-output/index.js\"', + '--external:aws-sdk --tsconfig=/asset-input/lib/custom-tsconfig.ts', + ].join(' '), + ], + }), + }); + +}); + +test('esbuild bundling with pre compilations with undefined tsconfig ( Should find in root directory )', () => { + Bundling.clearTscCompilationCache(); + const packageLock = path.join(__dirname, '..', 'package-lock.json'); + + Bundling.bundle({ + entry: __filename.replace('.js', '.ts'), + projectRoot: path.dirname(packageLock), + depsLockFilePath: packageLock, + runtime: Runtime.NODEJS_14_X, + forceDockerBundling: true, + preCompilation: true, + architecture: Architecture.X86_64, + }); + + // Correctly bundles with esbuild + expect(Code.fromAsset).toHaveBeenCalledWith(path.dirname(packageLock), { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + command: [ + 'bash', '-c', + [ + 'tsc --project /asset-input/tsconfig.json --rootDir ./ --outDir ./ &&', + 'esbuild --bundle \"/asset-input/test/bundling.test.js\" --target=node14 --platform=node --outfile=\"/asset-output/index.js\"', + '--external:aws-sdk', + ].join(' '), + ], + }), + }); +}); + +test('esbuild bundling with pre compilations and undefined tsconfig ( Should throw) ', () => { + expect(() => { + Bundling.bundle({ + entry, + projectRoot, + depsLockFilePath, + runtime: Runtime.NODEJS_14_X, + forceDockerBundling: true, + preCompilation: true, + architecture: Architecture.X86_64, + }); + }).toThrow('Cannot find a tsconfig.json, please specify the prop: tsconfig'); + +}); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/ts-decorator-handler.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/ts-decorator-handler.ts new file mode 100644 index 0000000000000..99ca5ee8ceec1 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ-handlers/ts-decorator-handler.ts @@ -0,0 +1,23 @@ +function enumerable(value: boolean) { + return function (_target: any, _propertyKey: string, descriptor: PropertyDescriptor) { + descriptor.enumerable = value; + }; +} + +class Greeter { + greeting: string; + constructor(message: string) { + this.greeting = message; + } + + @enumerable(false) + greet() { + return 'Hello, ' + this.greeting; + } +} + + +export async function handler(): Promise { + const message = new Greeter('World').greet(); + console.log(message); // eslint-disable-line no-console +} diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.compilations.expected.json b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.compilations.expected.json new file mode 100644 index 0000000000000..de56ccb33b617 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.compilations.expected.json @@ -0,0 +1,198 @@ +{ + "Resources": { + "tsdecoratorhandlerServiceRole61E9E52C": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "tsdecoratorhandlerC8E2F076": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "AssetParameters482454f5e1d850303130cf1cdbee1376fca84deaf9ccfa2c4cf8a246d415283fS3Bucket2B516B38" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters482454f5e1d850303130cf1cdbee1376fca84deaf9ccfa2c4cf8a246d415283fS3VersionKey4B530CD7" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters482454f5e1d850303130cf1cdbee1376fca84deaf9ccfa2c4cf8a246d415283fS3VersionKey4B530CD7" + } + ] + } + ] + } + ] + ] + } + }, + "Role": { + "Fn::GetAtt": [ + "tsdecoratorhandlerServiceRole61E9E52C", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1" + } + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "tsdecoratorhandlerServiceRole61E9E52C" + ] + }, + "tsdecoratorhandlertsconfigServiceRoleC4AE481E": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "tsdecoratorhandlertsconfig68EC191E": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "AssetParameters482454f5e1d850303130cf1cdbee1376fca84deaf9ccfa2c4cf8a246d415283fS3Bucket2B516B38" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters482454f5e1d850303130cf1cdbee1376fca84deaf9ccfa2c4cf8a246d415283fS3VersionKey4B530CD7" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters482454f5e1d850303130cf1cdbee1376fca84deaf9ccfa2c4cf8a246d415283fS3VersionKey4B530CD7" + } + ] + } + ] + } + ] + ] + } + }, + "Role": { + "Fn::GetAtt": [ + "tsdecoratorhandlertsconfigServiceRoleC4AE481E", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1" + } + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "tsdecoratorhandlertsconfigServiceRoleC4AE481E" + ] + } + }, + "Parameters": { + "AssetParameters482454f5e1d850303130cf1cdbee1376fca84deaf9ccfa2c4cf8a246d415283fS3Bucket2B516B38": { + "Type": "String", + "Description": "S3 bucket for asset \"482454f5e1d850303130cf1cdbee1376fca84deaf9ccfa2c4cf8a246d415283f\"" + }, + "AssetParameters482454f5e1d850303130cf1cdbee1376fca84deaf9ccfa2c4cf8a246d415283fS3VersionKey4B530CD7": { + "Type": "String", + "Description": "S3 key for asset version \"482454f5e1d850303130cf1cdbee1376fca84deaf9ccfa2c4cf8a246d415283f\"" + }, + "AssetParameters482454f5e1d850303130cf1cdbee1376fca84deaf9ccfa2c4cf8a246d415283fArtifactHash237F55B4": { + "Type": "String", + "Description": "Artifact hash for asset \"482454f5e1d850303130cf1cdbee1376fca84deaf9ccfa2c4cf8a246d415283f\"" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/integ.compilations.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.compilations.ts new file mode 100644 index 0000000000000..2c78bde18bbf7 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/integ.compilations.ts @@ -0,0 +1,39 @@ +/// !cdk-integ pragma:ignore-assets +import * as path from 'path'; +import { Runtime } from '@aws-cdk/aws-lambda'; +import { App, Stack, StackProps } from '@aws-cdk/core'; +import { Construct } from 'constructs'; +import * as lambda from '../lib'; + +class TestStack extends Stack { + constructor(scope: Construct, id: string, props?: StackProps) { + super(scope, id, props); + + new lambda.NodejsFunction(this, 'ts-decorator-handler', { + entry: path.join(__dirname, 'integ-handlers/ts-decorator-handler.ts'), + bundling: { + minify: true, + sourceMap: true, + sourceMapMode: lambda.SourceMapMode.BOTH, + preCompilation: true, + }, + runtime: Runtime.NODEJS_14_X, + }); + + new lambda.NodejsFunction(this, 'ts-decorator-handler-tsconfig', { + entry: path.join(__dirname, 'integ-handlers/ts-decorator-handler.ts'), + bundling: { + minify: true, + sourceMap: true, + sourceMapMode: lambda.SourceMapMode.BOTH, + tsconfig: path.join(__dirname, '..', 'tsconfig.json'), + preCompilation: true, + }, + runtime: Runtime.NODEJS_14_X, + }); + } +} + +const app = new App(); +new TestStack(app, 'cdk-integ-compilations-lambda-nodejs'); +app.synth(); diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/esbuild-installation.test.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/package-installation.test.ts similarity index 84% rename from packages/@aws-cdk/aws-lambda-nodejs/test/esbuild-installation.test.ts rename to packages/@aws-cdk/aws-lambda-nodejs/test/package-installation.test.ts index 24b9b512c98bc..e7afddc09fdbb 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/esbuild-installation.test.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/package-installation.test.ts @@ -1,12 +1,12 @@ import * as child_process from 'child_process'; -import { EsbuildInstallation } from '../lib/esbuild-installation'; +import { PackageInstallation } from '../lib/package-installation'; import * as util from '../lib/util'; // eslint-disable-next-line @typescript-eslint/no-require-imports, import/no-extraneous-dependencies const version = require('esbuild/package.json').version; test('detects local version', () => { - expect(EsbuildInstallation.detect()).toEqual({ + expect(PackageInstallation.detect('esbuild')).toEqual({ isLocal: true, version, }); @@ -23,7 +23,7 @@ test('checks global version if local detection fails', () => { signal: null, }); - expect(EsbuildInstallation.detect()).toEqual({ + expect(PackageInstallation.detect('esbuild')).toEqual({ isLocal: false, version: 'global-version', }); @@ -44,7 +44,7 @@ test('returns undefined on error', () => { signal: null, }); - expect(EsbuildInstallation.detect()).toBeUndefined(); + expect(PackageInstallation.detect('esbuild')).toBeUndefined(); spawnSyncMock.mockRestore(); getModuleVersionMock.mockRestore(); From 82de2e210286123e218116b39b1d9b26ad73ff38 Mon Sep 17 00:00:00 2001 From: Nick Lynch Date: Tue, 26 Oct 2021 12:00:10 +0100 Subject: [PATCH 041/148] chore: fix master build by skipping optional release notes copy (#17154) For releases (v1 and v2), we need to create the release notes (as part of the build) and then copy them to the dist/ directory (as part of pack). However, for `master` builds, we don't create the release notes because the BUMP_CANDIDATE builds reference a non-existent release version. Assuming the presence of the release notes in pack is causing the `master` pipeline to fail. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- pack.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pack.sh b/pack.sh index 86c29bacbd48c..168a17f972406 100755 --- a/pack.sh +++ b/pack.sh @@ -94,7 +94,10 @@ HERE # copy CHANGELOG.md and RELEASE_NOTES.md to dist/ for github releases cp ${changelog_file} ${distdir}/CHANGELOG.md -cp RELEASE_NOTES.md ${distdir}/RELEASE_NOTES.md +# Release notes are not available for bump candidate builds. +if ! ${BUMP_CANDIDATE:-false}; then + cp RELEASE_NOTES.md ${distdir}/RELEASE_NOTES.md +fi # defensive: make sure our artifacts don't use the version marker (this means # that "pack" will always fails when building in a dev environment) From 62f389ea0522cbaefca5ca17080228031d401ce6 Mon Sep 17 00:00:00 2001 From: Amir Szekely <73248943+amirfireeye@users.noreply.github.com> Date: Tue, 26 Oct 2021 04:55:07 -0700 Subject: [PATCH 042/148] feat(sns): addSubscription returns the created Subscription (#16785) Allow creating dependencies on the subscription by returning it from `addSubscription()`. Before this change the subscription resource was inaccessible. Creating a dependency required manually creating the subscription resource. Our current workaround is: ``` topic = sns.Topic(self, "topic") subscription_req = subs.SqsSubscription(queue) subscription_data = subscription_req.bind(topic) subscription = sns.Subscription( self, "Subscription", topic=topic, endpoint=subscription_data.endpoint, protocol=subscription_data.protocol, region=subscription_data.region, raw_message_delivery=subscription_data.raw_message_delivery, filter_policy=subscription_data.filter_policy, dead_letter_queue=subscription_data.dead_letter_queue, ) something.add_dependency(subscription) ``` And it would be much simpler as: ``` topic = sns.Topic(self, "topic") subscription = topic.add_subscription(subs.SqsSubscription(queue)) something.add_dependency(subscription) ``` ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-sns/lib/topic-base.ts | 6 +++--- packages/@aws-cdk/aws-sns/test/sns.test.ts | 22 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-sns/lib/topic-base.ts b/packages/@aws-cdk/aws-sns/lib/topic-base.ts index b867670474177..3d9984c86dff0 100644 --- a/packages/@aws-cdk/aws-sns/lib/topic-base.ts +++ b/packages/@aws-cdk/aws-sns/lib/topic-base.ts @@ -31,7 +31,7 @@ export interface ITopic extends IResource, notifications.INotificationRuleTarget /** * Subscribe some endpoint to this topic */ - addSubscription(subscription: ITopicSubscription): void; + addSubscription(subscription: ITopicSubscription): Subscription; /** * Adds a statement to the IAM resource policy associated with this topic. @@ -68,7 +68,7 @@ export abstract class TopicBase extends Resource implements ITopic { /** * Subscribe some endpoint to this topic */ - public addSubscription(subscription: ITopicSubscription) { + public addSubscription(subscription: ITopicSubscription): Subscription { const subscriptionConfig = subscription.bind(this); const scope = subscriptionConfig.subscriberScope || this; @@ -83,7 +83,7 @@ export abstract class TopicBase extends Resource implements ITopic { throw new Error(`A subscription with id "${id}" already exists under the scope ${scope.node.path}`); } - new Subscription(scope, id, { + return new Subscription(scope, id, { topic: this, ...subscriptionConfig, }); diff --git a/packages/@aws-cdk/aws-sns/test/sns.test.ts b/packages/@aws-cdk/aws-sns/test/sns.test.ts index 950aef6cbcef1..5bb928bff544e 100644 --- a/packages/@aws-cdk/aws-sns/test/sns.test.ts +++ b/packages/@aws-cdk/aws-sns/test/sns.test.ts @@ -480,4 +480,26 @@ describe('Topic', () => { }); + + test('result of addSubscription() can be used as a dependency', () => { + // GIVEN + const stack = new cdk.Stack(); + const topic = new sns.Topic(stack, 'Topic'); + const user = new iam.User(stack, 'User'); + + // WHEN + const subscription = topic.addSubscription({ + bind: () => ({ + protocol: sns.SubscriptionProtocol.HTTP, + endpoint: 'http://foo/bar', + subscriberId: 'my-subscription', + }), + }); + user.node.addDependency(subscription); + + // THEN + Template.fromStack(stack).hasResource('AWS::IAM::User', { + DependsOn: ['Topicmysubscription1E605DD7'], + }); + }); }); From aca19e18fefc497deebecd3ccf5b37036ba5a0a0 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Tue, 26 Oct 2021 17:33:47 +0200 Subject: [PATCH 043/148] chore(appscaling): make examples compile (#17164) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-applicationautoscaling/README.md | 88 ++++++++++--------- .../rosetta/default.ts-fixture | 48 ++++++++++ 2 files changed, 96 insertions(+), 40 deletions(-) create mode 100644 packages/@aws-cdk/aws-applicationautoscaling/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-applicationautoscaling/README.md b/packages/@aws-cdk/aws-applicationautoscaling/README.md index c00dac29ece2c..77f3858b8e6f2 100644 --- a/packages/@aws-cdk/aws-applicationautoscaling/README.md +++ b/packages/@aws-cdk/aws-applicationautoscaling/README.md @@ -51,15 +51,19 @@ There are three ways to scale your capacity: The general pattern of autoscaling will look like this: ```ts +declare const resource: SomeScalableResource; + const capacity = resource.autoScaleCapacity({ minCapacity: 5, maxCapacity: 100 }); -// Enable a type of metric scaling and/or schedule scaling -capacity.scaleOnMetric(...); -capacity.scaleToTrackMetric(...); -capacity.scaleOnSchedule(...); +// Then call a method to enable metric scaling and/or schedule scaling +// (explained below): +// +// capacity.scaleOnMetric(...); +// capacity.scaleToTrackMetric(...); +// capacity.scaleOnSchedule(...); ``` ## Step Scaling @@ -82,8 +86,11 @@ a possible one. You will have to determine what thresholds are right for you). You would configure it like this: ```ts +declare const capacity: ScalableAttribute; +declare const cpuUtilization: cloudwatch.Metric; + capacity.scaleOnMetric('ScaleToCPU', { - metric: service.metricCpuUtilization(), + metric: cpuUtilization, scalingSteps: [ { upper: 10, change: -1 }, { lower: 50, change: +1 }, @@ -92,7 +99,7 @@ capacity.scaleOnMetric('ScaleToCPU', { // Change this to AdjustmentType.PercentChangeInCapacity to interpret the // 'change' numbers before as percentages instead of capacity counts. - adjustmentType: autoscaling.AdjustmentType.CHANGE_IN_CAPACITY, + adjustmentType: appscaling.AdjustmentType.CHANGE_IN_CAPACITY, }); ``` @@ -111,6 +118,10 @@ The following example configures the read capacity of a DynamoDB table to be around 60% utilization: ```ts +import * as dynamodb from '@aws-cdk/aws-dynamodb'; + +declare const table: dynamodb.Table; + const readCapacity = table.autoScaleReadCapacity({ minCapacity: 10, maxCapacity: 1000 @@ -145,18 +156,20 @@ The following example scales the fleet out in the morning, and lets natural scaling take over at night: ```ts +declare const resource: SomeScalableResource; + const capacity = resource.autoScaleCapacity({ minCapacity: 1, maxCapacity: 50, }); capacity.scaleOnSchedule('PrescaleInTheMorning', { - schedule: autoscaling.Schedule.cron({ hour: '8', minute: '0' }), + schedule: appscaling.Schedule.cron({ hour: '8', minute: '0' }), minCapacity: 20, }); capacity.scaleOnSchedule('AllowDownscalingAtNight', { - schedule: autoscaling.Schedule.cron({ hour: '20', minute: '0' }), + schedule: appscaling.Schedule.cron({ hour: '20', minute: '0' }), minCapacity: 1 }); ``` @@ -166,35 +179,30 @@ capacity.scaleOnSchedule('AllowDownscalingAtNight', { ### Lambda Provisioned Concurrency Auto Scaling ```ts - const handler = new lambda.Function(this, 'MyFunction', { - runtime: lambda.Runtime.PYTHON_3_7, - handler: 'index.handler', - code: new lambda.InlineCode(` -import json, time -def handler(event, context): - time.sleep(1) - return { - 'statusCode': 200, - 'body': json.dumps('Hello CDK from Lambda!') - }`), - reservedConcurrentExecutions: 2, - }); - - const fnVer = handler.addVersion('CDKLambdaVersion', undefined, 'demo alias', 10); - - new apigateway.LambdaRestApi(this, 'API', { handler: fnVer }) - - const target = new applicationautoscaling.ScalableTarget(this, 'ScalableTarget', { - serviceNamespace: applicationautoscaling.ServiceNamespace.LAMBDA, - maxCapacity: 100, - minCapacity: 10, - resourceId: `function:${handler.functionName}:${fnVer.version}`, - scalableDimension: 'lambda:function:ProvisionedConcurrency', - }) -s - target.scaleToTrackMetric('PceTracking', { - targetValue: 0.9, - predefinedMetric: applicationautoscaling.PredefinedMetric.LAMBDA_PROVISIONED_CONCURRENCY_UTILIZATION, - }) - } - ``` +import * as lambda from '@aws-cdk/aws-lambda'; + +declare const code: lambda.Code; + +const handler = new lambda.Function(this, 'MyFunction', { + runtime: lambda.Runtime.PYTHON_3_7, + handler: 'index.handler', + code, + + reservedConcurrentExecutions: 2, +}); + +const fnVer = handler.addVersion('CDKLambdaVersion', undefined, 'demo alias', 10); + +const target = new appscaling.ScalableTarget(this, 'ScalableTarget', { + serviceNamespace: appscaling.ServiceNamespace.LAMBDA, + maxCapacity: 100, + minCapacity: 10, + resourceId: `function:${handler.functionName}:${fnVer.version}`, + scalableDimension: 'lambda:function:ProvisionedConcurrency', +}) + +target.scaleToTrackMetric('PceTracking', { + targetValue: 0.9, + predefinedMetric: appscaling.PredefinedMetric.LAMBDA_PROVISIONED_CONCURRENCY_UTILIZATION, +}) +``` diff --git a/packages/@aws-cdk/aws-applicationautoscaling/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-applicationautoscaling/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..9a75db0061b9d --- /dev/null +++ b/packages/@aws-cdk/aws-applicationautoscaling/rosetta/default.ts-fixture @@ -0,0 +1,48 @@ +// Fixture with packages imported, but nothing else +import { Construct, Node } from 'constructs'; +import { Aspects, CfnOutput, Stack, Duration, Resource, SecretValue } from '@aws-cdk/core'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as appscaling from '@aws-cdk/aws-applicationautoscaling'; +import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; +import * as iam from '@aws-cdk/aws-iam'; + + +interface UtilizationScalingProps { + readonly targetUtilizationPercent: number; +} + +class ScalableAttribute { + public scaleOnSchedule(id: string, action: appscaling.ScalingSchedule) { + Array.isArray(id); + Array.isArray(action); + } + public scaleOnUtilization(props: UtilizationScalingProps) { + Array.isArray(props); + } + public scaleOnMetric(id: string, props: appscaling.BasicStepScalingPolicyProps) { + Array.isArray(id); + Array.isArray(props); + } +} + +interface Caps { + readonly minCapacity: number; + readonly maxCapacity: number; +} + +class SomeScalableResource { + public autoScaleCapacity(caps: Caps) { + return new ScalableAttribute(); + } +} + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} + + + From 325952324da82265d7043099f2b5287b40266896 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Tue, 26 Oct 2021 18:25:37 +0200 Subject: [PATCH 044/148] chore(autoscaling): make examples compile (#17163) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-autoscaling/README.md | 110 +++++++++++++----- .../aws-autoscaling/lib/scheduled-action.ts | 2 - .../@aws-cdk/aws-autoscaling/lib/volume.ts | 5 +- .../rosetta/default.ts-fixture | 18 +++ 4 files changed, 104 insertions(+), 31 deletions(-) create mode 100644 packages/@aws-cdk/aws-autoscaling/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-autoscaling/README.md b/packages/@aws-cdk/aws-autoscaling/README.md index 75aa4f66807e2..11c67226afdb4 100644 --- a/packages/@aws-cdk/aws-autoscaling/README.md +++ b/packages/@aws-cdk/aws-autoscaling/README.md @@ -20,8 +20,7 @@ An `AutoScalingGroup` represents a number of instances on which you run your cod pick the size of the fleet, the instance type and the OS image: ```ts -import * as autoscaling from '@aws-cdk/aws-autoscaling'; -import * as ec2 from '@aws-cdk/aws-ec2'; +declare const vpc: ec2.Vpc; new autoscaling.AutoScalingGroup(this, 'ASG', { vpc, @@ -36,7 +35,9 @@ your instances to be able to start arbitrary connections. Alternatively, you can group to attach to the instances that are launched, rather than have the group create a new one. ```ts -const mySecurityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {...}); +declare const vpc: ec2.Vpc; + +const mySecurityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', { vpc }); new autoscaling.AutoScalingGroup(this, 'ASG', { vpc, instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), @@ -89,24 +90,31 @@ There are three ways to scale your capacity: The general pattern of autoscaling will look like this: ```ts +declare const vpc: ec2.Vpc; +declare const instanceType: ec2.InstanceType; +declare const machineImage: ec2.IMachineImage; + const autoScalingGroup = new autoscaling.AutoScalingGroup(this, 'ASG', { + vpc, + instanceType, + machineImage, + minCapacity: 5, maxCapacity: 100 // ... }); -// Step scaling -autoScalingGroup.scaleOnMetric(...); - -// Target tracking scaling -autoScalingGroup.scaleOnCpuUtilization(...); -autoScalingGroup.scaleOnIncomingBytes(...); -autoScalingGroup.scaleOnOutgoingBytes(...); -autoScalingGroup.scaleOnRequestCount(...); -autoScalingGroup.scaleToTrackMetric(...); - -// Scheduled scaling -autoScalingGroup.scaleOnSchedule(...); +// Then call one of the scaling methods (explained below) +// +// autoScalingGroup.scaleOnMetric(...); +// +// autoScalingGroup.scaleOnCpuUtilization(...); +// autoScalingGroup.scaleOnIncomingBytes(...); +// autoScalingGroup.scaleOnOutgoingBytes(...); +// autoScalingGroup.scaleOnRequestCount(...); +// autoScalingGroup.scaleToTrackMetric(...); +// +// autoScalingGroup.scaleOnSchedule(...); ``` ### Step Scaling @@ -132,12 +140,14 @@ metric representing your worker utilization from your instances. After that, you would configure the scaling something like this: ```ts +declare const autoScalingGroup: autoscaling.AutoScalingGroup; + const workerUtilizationMetric = new cloudwatch.Metric({ namespace: 'MyService', metricName: 'WorkerUtilization' }); -capacity.scaleOnMetric('ScaleToCPU', { +autoScalingGroup.scaleOnMetric('ScaleToCPU', { metric: workerUtilizationMetric, scalingSteps: [ { upper: 10, change: -1 }, @@ -170,6 +180,8 @@ The following example scales to keep the CPU usage of your instances around 50% utilization: ```ts +declare const autoScalingGroup: autoscaling.AutoScalingGroup; + autoScalingGroup.scaleOnCpuUtilization('KeepSpareCPU', { targetUtilizationPercent: 50 }); @@ -178,10 +190,12 @@ autoScalingGroup.scaleOnCpuUtilization('KeepSpareCPU', { To scale on average network traffic in and out of your instances: ```ts +declare const autoScalingGroup: autoscaling.AutoScalingGroup; + autoScalingGroup.scaleOnIncomingBytes('LimitIngressPerInstance', { targetBytesPerSecond: 10 * 1024 * 1024 // 10 MB/s }); -autoScalingGroup.scaleOnOutcomingBytes('LimitEgressPerInstance', { +autoScalingGroup.scaleOnOutgoingBytes('LimitEgressPerInstance', { targetBytesPerSecond: 10 * 1024 * 1024 // 10 MB/s }); ``` @@ -191,6 +205,8 @@ AutoScalingGroups that have been attached to Application Load Balancers): ```ts +declare const autoScalingGroup: autoscaling.AutoScalingGroup; + autoScalingGroup.scaleOnRequestCount('LimitRPS', { targetRequestsPerSecond: 1000 }); @@ -214,6 +230,8 @@ The following example scales the fleet out in the morning, going back to natural scaling (all the way down to 1 instance if necessary) at night: ```ts +declare const autoScalingGroup: autoscaling.AutoScalingGroup; + autoScalingGroup.scaleOnSchedule('PrescaleInTheMorning', { schedule: autoscaling.Schedule.cron({ hour: '8', minute: '0' }), minCapacity: 20, @@ -246,7 +264,15 @@ Here's an example of using CloudFormation Init to write a file to the instance hosts on startup: ```ts +declare const vpc: ec2.Vpc; +declare const instanceType: ec2.InstanceType; +declare const machineImage: ec2.IMachineImage; + new autoscaling.AutoScalingGroup(this, 'ASG', { + vpc, + instanceType, + machineImage, + // ... init: ec2.CloudFormationInit.fromElements( @@ -347,16 +373,30 @@ See [EC2 docs](https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance To enable group metrics monitoring using the `groupMetrics` property: ```ts +declare const vpc: ec2.Vpc; +declare const instanceType: ec2.InstanceType; +declare const machineImage: ec2.IMachineImage; + // Enable monitoring of all group metrics -new autoscaling.AutoScalingGroup(stack, 'ASG', { - groupMetrics: [GroupMetrics.all()], +new autoscaling.AutoScalingGroup(this, 'ASG', { + vpc, + instanceType, + machineImage, + // ... + + groupMetrics: [autoscaling.GroupMetrics.all()], }); // Enable monitoring for a subset of group metrics -new autoscaling.AutoScalingGroup(stack, 'ASG', { - groupMetrics: [new autoscaling.GroupMetrics(GroupMetric.MIN_SIZE, GroupMetric.MAX_SIZE)], +new autoscaling.AutoScalingGroup(this, 'ASG', { + vpc, + instanceType, + machineImage, + // ... + + groupMetrics: [new autoscaling.GroupMetrics(autoscaling.GroupMetric.MIN_SIZE, autoscaling.GroupMetric.MAX_SIZE)], }); ``` @@ -372,9 +412,18 @@ terminated. EC2 Capacity Providers for Amazon ECS requires this attribute be set to `true`. ```ts -new autoscaling.AutoScalingGroup(stack, 'ASG', { - newInstancesProtectedFromScaleIn: true, +declare const vpc: ec2.Vpc; +declare const instanceType: ec2.InstanceType; +declare const machineImage: ec2.IMachineImage; + +new autoscaling.AutoScalingGroup(this, 'ASG', { + vpc, + instanceType, + machineImage, + // ... + + newInstancesProtectedFromScaleIn: true, }); ``` @@ -389,9 +438,18 @@ To do this for a single `AutoScalingGroup`, you can use set the `requireImdsv2` The example below demonstrates IMDSv2 being required on a single `AutoScalingGroup`: ```ts -new autoscaling.AutoScalingGroup(stack, 'ASG', { - requireImdsv2: true, +declare const vpc: ec2.Vpc; +declare const instanceType: ec2.InstanceType; +declare const machineImage: ec2.IMachineImage; + +new autoscaling.AutoScalingGroup(this, 'ASG', { + vpc, + instanceType, + machineImage, + // ... + + requireImdsv2: true, }); ``` @@ -401,7 +459,7 @@ The example below demonstrates the `AutoScalingGroupRequireImdsv2Aspect` being u ```ts const aspect = new autoscaling.AutoScalingGroupRequireImdsv2Aspect(); -Aspects.of(stack).add(aspect); +Aspects.of(this).add(aspect); ``` ## Future work diff --git a/packages/@aws-cdk/aws-autoscaling/lib/scheduled-action.ts b/packages/@aws-cdk/aws-autoscaling/lib/scheduled-action.ts index 71fde34af72cd..70a269bde9239 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/scheduled-action.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/scheduled-action.ts @@ -14,8 +14,6 @@ export interface BasicScheduledActionProps { * Supports cron expressions. * * For more information about cron expressions, see https://en.wikipedia.org/wiki/Cron. - * - * @example 0 8 * * ? */ readonly schedule: Schedule; diff --git a/packages/@aws-cdk/aws-autoscaling/lib/volume.ts b/packages/@aws-cdk/aws-autoscaling/lib/volume.ts index cbe08bac7c6ab..1c5f5da6dc659 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/volume.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/volume.ts @@ -9,7 +9,7 @@ export interface BlockDevice { /** * The device name exposed to the EC2 instance * - * @example '/dev/sdh', 'xvdh' + * Supply a value like `/dev/sdh`, `xvdh`. * * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/device_naming.html */ @@ -18,8 +18,7 @@ export interface BlockDevice { /** * Defines the block device volume, to be either an Amazon EBS volume or an ephemeral instance store volume * - * @example BlockDeviceVolume.ebs(15), BlockDeviceVolume.ephemeral(0) - * + * Supply a value like `BlockDeviceVolume.ebs(15)`, `BlockDeviceVolume.ephemeral(0)`. */ readonly volume: BlockDeviceVolume; diff --git a/packages/@aws-cdk/aws-autoscaling/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-autoscaling/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..314520288f9cb --- /dev/null +++ b/packages/@aws-cdk/aws-autoscaling/rosetta/default.ts-fixture @@ -0,0 +1,18 @@ +// Fixture with packages imported, but nothing else +import { Construct, Node } from 'constructs'; +import { Aspects, CfnOutput, Stack, Duration, Resource, SecretValue } from '@aws-cdk/core'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as autoscaling from '@aws-cdk/aws-autoscaling'; +import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; +import * as iam from '@aws-cdk/aws-iam'; + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} + + + From f37991c4de21ecbc7db5117de7f9adc1ecc40f2b Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Tue, 26 Oct 2021 19:18:02 +0200 Subject: [PATCH 045/148] chore(cloudwatch): make examples compile (#17158) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-cloudwatch/README.md | 128 ++++++++++++------ .../aws-cloudwatch/rosetta/default.ts-fixture | 17 +++ 2 files changed, 100 insertions(+), 45 deletions(-) create mode 100644 packages/@aws-cdk/aws-cloudwatch/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-cloudwatch/README.md b/packages/@aws-cdk/aws-cloudwatch/README.md index 450fc8ca9821a..67b68ed46e741 100644 --- a/packages/@aws-cdk/aws-cloudwatch/README.md +++ b/packages/@aws-cdk/aws-cloudwatch/README.md @@ -25,6 +25,8 @@ For example, `lambda.Function` objects have the `fn.metricErrors()` method, whic represents the amount of errors reported by that Lambda function: ```ts +declare const fn: lambda.Function; + const errors = fn.metricErrors(); ``` @@ -37,7 +39,7 @@ For example: ```ts const hostedZone = new route53.HostedZone(this, 'MyHostedZone', { zoneName: "example.org" }); -const metric = new Metric({ +const metric = new cloudwatch.Metric({ namespace: 'AWS/Route53', metricName: 'DNSQueries', dimensionsMap: { @@ -52,7 +54,7 @@ If you want to reference a metric that is not yet exposed by an existing constru you can instantiate a `Metric` object to represent it. For example: ```ts -const metric = new Metric({ +const metric = new cloudwatch.Metric({ namespace: 'MyNamespace', metricName: 'MyMetric', dimensionsMap: { @@ -67,11 +69,13 @@ Math expressions are supported by instantiating the `MathExpression` class. For example, a math expression that sums two other metrics looks like this: ```ts -const allProblems = new MathExpression({ - expression: "errors + faults", +declare const fn: lambda.Function; + +const allProblems = new cloudwatch.MathExpression({ + expression: "errors + throttles", usingMetrics: { - errors: myConstruct.metricErrors(), - faults: myConstruct.metricFaults(), + errors: fn.metricErrors(), + faults: fn.metricThrottles(), } }); ``` @@ -80,11 +84,14 @@ You can use `MathExpression` objects like any other metric, including using them in other math expressions: ```ts -const problemPercentage = new MathExpression({ +declare const fn: lambda.Function; +declare const allProblems: cloudwatch.MathExpression; + +const problemPercentage = new cloudwatch.MathExpression({ expression: "(problems / invocations) * 100", usingMetrics: { problems: allProblems, - invocations: myConstruct.metricInvocations() + invocations: fn.metricInvocations() } }); ``` @@ -96,7 +103,7 @@ search expression returns all CPUUtilization metrics that it finds, with the graph showing the Average statistic with an aggregation period of 5 minutes: ```ts -const cpuUtilization = new MathExpression({ +const cpuUtilization = new cloudwatch.MathExpression({ expression: "SEARCH('{AWS/EC2,InstanceId} MetricName=\"CPUUtilization\"', 'Average', 300)" }); ``` @@ -120,6 +127,8 @@ the function or the period), you can do so by passing additional parameters to the metric function call: ```ts +declare const fn: lambda.Function; + const minuteErrorRate = fn.metricErrors({ statistic: 'avg', period: Duration.minutes(1), @@ -153,9 +162,10 @@ useful when embedding them in graphs, see below). Alarms can be created on metrics in one of two ways. Either create an `Alarm` object, passing the `Metric` object to set the alarm on: - ```ts -new Alarm(this, 'Alarm', { +declare const fn: lambda.Function; + +new cloudwatch.Alarm(this, 'Alarm', { metric: fn.metricErrors(), threshold: 100, evaluationPeriods: 2, @@ -165,6 +175,8 @@ new Alarm(this, 'Alarm', { Alternatively, you can call `metric.createAlarm()`: ```ts +declare const fn: lambda.Function; + fn.metricErrors().createAlarm(this, 'Alarm', { threshold: 100, evaluationPeriods: 2, @@ -188,33 +200,36 @@ an SNS topic when an alarm breaches, do the following: ```ts import * as cw_actions from '@aws-cdk/aws-cloudwatch-actions'; +declare const alarm: cloudwatch.Alarm; -// ... -const topic = new sns.Topic(stack, 'Topic'); -const alarm = new cloudwatch.Alarm(stack, 'Alarm', { /* ... */ }); - +const topic = new sns.Topic(this, 'Topic'); alarm.addAlarmAction(new cw_actions.SnsAction(topic)); ``` ### Composite Alarms -[Composite Alarms](https://aws.amazon.com/about-aws/whats-new/2020/03/amazon-cloudwatch-now-allows-you-to-combine-multiple-alarms/) +[Composite Alarms](https://aws.amazon.com/about-aws/whats-new/2020/03/amazon-cloudwatch-now-allows-you-to-combine-multiple-alarms/) can be created from existing Alarm resources. ```ts -const alarmRule = AlarmRule.anyOf( - AlarmRule.allOf( - AlarmRule.anyOf( +declare const alarm1: cloudwatch.Alarm; +declare const alarm2: cloudwatch.Alarm; +declare const alarm3: cloudwatch.Alarm; +declare const alarm4: cloudwatch.Alarm; + +const alarmRule = cloudwatch.AlarmRule.anyOf( + cloudwatch.AlarmRule.allOf( + cloudwatch.AlarmRule.anyOf( alarm1, - AlarmRule.fromAlarm(alarm2, AlarmState.OK), + cloudwatch.AlarmRule.fromAlarm(alarm2, cloudwatch.AlarmState.OK), alarm3, ), - AlarmRule.not(AlarmRule.fromAlarm(alarm4, AlarmState.INSUFFICIENT_DATA)), + cloudwatch.AlarmRule.not(cloudwatch.AlarmRule.fromAlarm(alarm4, cloudwatch.AlarmState.INSUFFICIENT_DATA)), ), - AlarmRule.fromBoolean(false), + cloudwatch.AlarmRule.fromBoolean(false), ); -new CompositeAlarm(this, 'MyAwesomeCompositeAlarm', { +new cloudwatch.CompositeAlarm(this, 'MyAwesomeCompositeAlarm', { alarmRule, }); ``` @@ -260,7 +275,11 @@ A graph widget can display any number of metrics on either the `left` or `right` vertical axis: ```ts -dashboard.addWidgets(new GraphWidget({ +declare const dashboard: cloudwatch.Dashboard; +declare const executionCountMetric: cloudwatch.Metric; +declare const errorCountMetric: cloudwatch.Metric; + +dashboard.addWidgets(new cloudwatch.GraphWidget({ title: "Executions vs error rate", left: [executionCountMetric], @@ -268,7 +287,7 @@ dashboard.addWidgets(new GraphWidget({ right: [errorCountMetric.with({ statistic: "average", label: "Error rate", - color: Color.GREEN + color: cloudwatch.Color.GREEN })] })); ``` @@ -278,12 +297,13 @@ Using the methods `addLeftMetric()` and `addRightMetric()` you can add metrics t Graph widgets can also display annotations attached to the left or the right y-axis. ```ts -dashboard.addWidgets(new GraphWidget({ - // ... +declare const dashboard: cloudwatch.Dashboard; + +dashboard.addWidgets(new cloudwatch.GraphWidget({ // ... leftAnnotations: [ - { value: 1800, label: Duration.minutes(30).toHumanString(), color: Color.RED, }, + { value: 1800, label: Duration.minutes(30).toHumanString(), color: cloudwatch.Color.RED, }, { value: 3600, label: '1 hour', color: '#2ca02c', } ], })); @@ -292,19 +312,21 @@ dashboard.addWidgets(new GraphWidget({ The graph legend can be adjusted from the default position at bottom of the widget. ```ts -dashboard.addWidgets(new GraphWidget({ - // ... +declare const dashboard: cloudwatch.Dashboard; + +dashboard.addWidgets(new cloudwatch.GraphWidget({ // ... - legendPosition: LegendPosition.RIGHT, + legendPosition: cloudwatch.LegendPosition.RIGHT, })); ``` The graph can publish live data within the last minute that has not been fully aggregated. ```ts -dashboard.addWidgets(new GraphWidget({ - // ... +declare const dashboard: cloudwatch.Dashboard; + +dashboard.addWidgets(new cloudwatch.GraphWidget({ // ... liveData: true, @@ -314,11 +336,12 @@ dashboard.addWidgets(new GraphWidget({ The graph view can be changed from default 'timeSeries' to 'bar' or 'pie'. ```ts -dashboard.addWidgets(new GraphWidget({ - // ... +declare const dashboard: cloudwatch.Dashboard; + +dashboard.addWidgets(new cloudwatch.GraphWidget({ // ... - view: GraphWidgetView.BAR, + view: cloudwatch.GraphWidgetView.BAR, })); ``` @@ -327,7 +350,10 @@ dashboard.addWidgets(new GraphWidget({ An alarm widget shows the graph and the alarm line of a single alarm: ```ts -dashboard.addWidgets(new AlarmWidget({ +declare const dashboard: cloudwatch.Dashboard; +declare const errorAlarm: cloudwatch.Alarm; + +dashboard.addWidgets(new cloudwatch.AlarmWidget({ title: "Errors", alarm: errorAlarm, })); @@ -339,7 +365,11 @@ A single-value widget shows the latest value of a set of metrics (as opposed to a graph of the value over time): ```ts -dashboard.addWidgets(new SingleValueWidget({ +declare const dashboard: cloudwatch.Dashboard; +declare const visitorCount: cloudwatch.Metric; +declare const purchaseCount: cloudwatch.Metric; + +dashboard.addWidgets(new cloudwatch.SingleValueWidget({ metrics: [visitorCount, purchaseCount], })); ``` @@ -347,9 +377,10 @@ dashboard.addWidgets(new SingleValueWidget({ Show as many digits as can fit, before rounding. ```ts -dashboard.addWidgets(new SingleValueWidget({ - // .. - // .. +declare const dashboard: cloudwatch.Dashboard; + +dashboard.addWidgets(new cloudwatch.SingleValueWidget({ + metrics: [ /* ... */ ], fullPrecision: true, })); @@ -361,7 +392,9 @@ A text widget shows an arbitrary piece of MarkDown. Use this to add explanations to your dashboard: ```ts -dashboard.addWidgets(new TextWidget({ +declare const dashboard: cloudwatch.Dashboard; + +dashboard.addWidgets(new cloudwatch.TextWidget({ markdown: '# Key Performance Indicators' })); ``` @@ -372,8 +405,11 @@ An alarm status widget displays instantly the status of any type of alarms and g ability to aggregate one or more alarms together in a small surface. ```ts +declare const dashboard: cloudwatch.Dashboard; +declare const errorAlarm: cloudwatch.Alarm; + dashboard.addWidgets( - new AlarmStatusWidget({ + new cloudwatch.AlarmStatusWidget({ alarms: [errorAlarm], }) ); @@ -384,9 +420,11 @@ dashboard.addWidgets( A `LogQueryWidget` shows the results of a query from Logs Insights: ```ts -dashboard.addWidgets(new LogQueryWidget({ +declare const dashboard: cloudwatch.Dashboard; + +dashboard.addWidgets(new cloudwatch.LogQueryWidget({ logGroupNames: ['my-log-group'], - view: LogQueryVisualizationType.TABLE, + view: cloudwatch.LogQueryVisualizationType.TABLE, // The lines will be automatically combined using '\n|'. queryLines: [ 'fields @message', diff --git a/packages/@aws-cdk/aws-cloudwatch/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-cloudwatch/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..85cc6b579f761 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudwatch/rosetta/default.ts-fixture @@ -0,0 +1,17 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { Stack, Duration } from '@aws-cdk/core'; +import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; +import * as route53 from '@aws-cdk/aws-route53'; +import * as sns from '@aws-cdk/aws-sns'; +import * as lambda from '@aws-cdk/aws-lambda'; + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} + + From 76898698d3657ab996e994c7eec79dd818684589 Mon Sep 17 00:00:00 2001 From: Nick Lynch Date: Tue, 26 Oct 2021 19:10:41 +0100 Subject: [PATCH 046/148] chore: Revert "feat(sns): addSubscription returns the created Subscription (#16785)" (#17166) This reverts commit 62f389ea0522cbaefca5ca17080228031d401ce6. Changing the return type from void to Subscription is a breaking change for F# customers, where the return type changes from "unit" to "Subscription", potentially breaking `do` statements. Example: https://github.com/aws/aws-cdk/blob/62f389ea0522cbaefca5ca17080228031d401ce6/packages/aws-cdk/lib/init-templates/v1/sample-app/fsharp/src/%25name.PascalCased%25/%25name.PascalCased%25Stack.template.fs#L14 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-sns/lib/topic-base.ts | 6 +++--- packages/@aws-cdk/aws-sns/test/sns.test.ts | 22 --------------------- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/packages/@aws-cdk/aws-sns/lib/topic-base.ts b/packages/@aws-cdk/aws-sns/lib/topic-base.ts index 3d9984c86dff0..b867670474177 100644 --- a/packages/@aws-cdk/aws-sns/lib/topic-base.ts +++ b/packages/@aws-cdk/aws-sns/lib/topic-base.ts @@ -31,7 +31,7 @@ export interface ITopic extends IResource, notifications.INotificationRuleTarget /** * Subscribe some endpoint to this topic */ - addSubscription(subscription: ITopicSubscription): Subscription; + addSubscription(subscription: ITopicSubscription): void; /** * Adds a statement to the IAM resource policy associated with this topic. @@ -68,7 +68,7 @@ export abstract class TopicBase extends Resource implements ITopic { /** * Subscribe some endpoint to this topic */ - public addSubscription(subscription: ITopicSubscription): Subscription { + public addSubscription(subscription: ITopicSubscription) { const subscriptionConfig = subscription.bind(this); const scope = subscriptionConfig.subscriberScope || this; @@ -83,7 +83,7 @@ export abstract class TopicBase extends Resource implements ITopic { throw new Error(`A subscription with id "${id}" already exists under the scope ${scope.node.path}`); } - return new Subscription(scope, id, { + new Subscription(scope, id, { topic: this, ...subscriptionConfig, }); diff --git a/packages/@aws-cdk/aws-sns/test/sns.test.ts b/packages/@aws-cdk/aws-sns/test/sns.test.ts index 5bb928bff544e..950aef6cbcef1 100644 --- a/packages/@aws-cdk/aws-sns/test/sns.test.ts +++ b/packages/@aws-cdk/aws-sns/test/sns.test.ts @@ -480,26 +480,4 @@ describe('Topic', () => { }); - - test('result of addSubscription() can be used as a dependency', () => { - // GIVEN - const stack = new cdk.Stack(); - const topic = new sns.Topic(stack, 'Topic'); - const user = new iam.User(stack, 'User'); - - // WHEN - const subscription = topic.addSubscription({ - bind: () => ({ - protocol: sns.SubscriptionProtocol.HTTP, - endpoint: 'http://foo/bar', - subscriberId: 'my-subscription', - }), - }); - user.node.addDependency(subscription); - - // THEN - Template.fromStack(stack).hasResource('AWS::IAM::User', { - DependsOn: ['Topicmysubscription1E605DD7'], - }); - }); }); From fcd17e9c9a9e1b83a29c140d558f696c0290bfd7 Mon Sep 17 00:00:00 2001 From: James Lakin Date: Tue, 26 Oct 2021 21:33:06 +0100 Subject: [PATCH 047/148] feat(rds): support backtrackWindow in DatabaseCluster (#17160) This is a small PR to fix #9369 without needing to use an escape hatch. Fixes #9369 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-rds/lib/cluster.ts | 11 ++++++++++ .../@aws-cdk/aws-rds/test/cluster.test.ts | 20 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/packages/@aws-cdk/aws-rds/lib/cluster.ts b/packages/@aws-cdk/aws-rds/lib/cluster.ts index 15f9e60215ebc..7324cacb333c2 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster.ts @@ -40,6 +40,16 @@ interface DatabaseClusterBaseProps { */ readonly instanceProps: InstanceProps; + /** + * The number of seconds to set a cluster's target backtrack window to. + * This feature is only supported by the Aurora MySQL database engine and + * cannot be enabled on existing clusters. + * + * @see https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Managing.Backtrack.html + * @default 0 seconds (no backtrack) + */ + readonly backtrackWindow?: Duration + /** * Backup settings * @@ -364,6 +374,7 @@ abstract class DatabaseClusterNew extends DatabaseClusterBase { deletionProtection: defaultDeletionProtection(props.deletionProtection, props.removalPolicy), enableIamDatabaseAuthentication: props.iamAuthentication, // Admin + backtrackWindow: props.backtrackWindow?.toSeconds(), backupRetentionPeriod: props.backup?.retention?.toDays(), preferredBackupWindow: props.backup?.preferredWindow, preferredMaintenanceWindow: props.preferredMaintenanceWindow, diff --git a/packages/@aws-cdk/aws-rds/test/cluster.test.ts b/packages/@aws-cdk/aws-rds/test/cluster.test.ts index 97d5548611fcd..5adc3d4906643 100644 --- a/packages/@aws-cdk/aws-rds/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-rds/test/cluster.test.ts @@ -2032,6 +2032,26 @@ describe('cluster', () => { CopyTagsToSnapshot: true, }); }); + + test('cluster has BacktrackWindow in seconds', () => { + // GIVEN + const stack = testStack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + + // WHEN + new DatabaseCluster(stack, 'Database', { + engine: DatabaseClusterEngine.AURORA, + instanceProps: { + vpc, + }, + backtrackWindow: cdk.Duration.days(1), + }); + + // THEN + expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + BacktrackWindow: 24 * 60 * 60, + }); + }); }); test.each([ From ad36306ed206e8102a85ee391136b84ba6f4c6e1 Mon Sep 17 00:00:00 2001 From: Adel Salakh Date: Wed, 27 Oct 2021 02:22:31 +0300 Subject: [PATCH 048/148] docs(lambda-layer-kubctl): fix incorrect versions in README (#16413) Swap Helm and Kubectl versions in the README ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/lambda-layer-kubectl/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/lambda-layer-kubectl/README.md b/packages/@aws-cdk/lambda-layer-kubectl/README.md index 3782174b1aa72..97329d16c8c50 100644 --- a/packages/@aws-cdk/lambda-layer-kubectl/README.md +++ b/packages/@aws-cdk/lambda-layer-kubectl/README.md @@ -11,8 +11,9 @@ This module exports a single class called `KubectlLayer` which is a `lambda.Layer` that bundles the [`kubectl`](https://kubernetes.io/docs/reference/kubectl/kubectl/) and the [`helm`](https://helm.sh/) command line. -> - Helm Version: 1.20.0 -> - Kubectl Version: 3.4.2 +> - Helm Version: 3.5.4 +> - Kubectl Version: 1.20.0 +> Usage: From 3efd31e478d5060f0fb45668ae3ef1cb44e9fd14 Mon Sep 17 00:00:00 2001 From: peterwoodworth Date: Tue, 26 Oct 2021 16:52:57 -0700 Subject: [PATCH 049/148] chore: add corymhall, peterwoodworth, ryparker to mergify --- .mergify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mergify.yml b/.mergify.yml index e460f1d12842f..c30db93044503 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -10,7 +10,7 @@ pull_request_rules: label: add: [ contribution/core ] conditions: - - author~=^(eladb|RomainMuller|garnaat|nija-at|skinny85|rix0rrr|NGL321|Jerry-AWS|MrArnoldPalmer|NetaNir|iliapolo|njlynch|ericzbeard|ccfife|fulghum|pkandasamy91|SoManyHs|uttarasridhar|otaviomacedo|BenChaimberg|madeline-k|BryanPan342|kaizen3031593|comcalvi|Chriscbr)$ + - author~=^(eladb|RomainMuller|garnaat|nija-at|skinny85|rix0rrr|NGL321|Jerry-AWS|MrArnoldPalmer|NetaNir|iliapolo|njlynch|ericzbeard|ccfife|fulghum|pkandasamy91|SoManyHs|uttarasridhar|otaviomacedo|BenChaimberg|madeline-k|BryanPan342|kaizen3031593|comcalvi|Chriscbr|corymhall|peterwoodworth|ryparker)$ - -label~="contribution/core" - name: automatic merge actions: From 7bdd9079d55e503cd625bc5663f0bb73ad94a40f Mon Sep 17 00:00:00 2001 From: Peter Woodworth <44349620+peterwoodworth@users.noreply.github.com> Date: Wed, 27 Oct 2021 00:31:42 -0700 Subject: [PATCH 050/148] chore: update autolabeler config (#17174) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .github/workflows/issue-label-assign.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/issue-label-assign.yml b/.github/workflows/issue-label-assign.yml index b82a4040658d8..b7bfacd0126b0 100644 --- a/.github/workflows/issue-label-assign.yml +++ b/.github/workflows/issue-label-assign.yml @@ -24,6 +24,7 @@ jobs: {"area":"@aws-cdk/alexa-ask","keywords":["alexa-ask","alexa", "cfnskill"],"labels":["@aws-cdk/alexa-ask"],"assignees":["madeline-k"]}, {"area":"@aws-cdk/app-delivery","keywords":["app-delivery","PipelineDeployStackAction"],"labels":["@aws-cdk/app-delivery"],"assignees":["skinny85"]}, {"area":"@aws-cdk/assert","keywords":["assert"],"labels":["@aws-cdk/assert"],"assignees":["nija-at"]}, + {"area":"@aws-cdk/assertions","keywords":["assertions"],"labels":["@aws-cdk/assertions"],"assignees":["nija-at"]}, {"area":"@aws-cdk/assets","keywords":["assets","staging"],"labels":["@aws-cdk/assets"],"assignees":["eladb"]}, {"area":"@aws-cdk/aws-accessanalyzer","keywords":["aws-accessanalyzer","accessanalyzer","cfnanalyzer"],"labels":["@aws-cdk/aws-accessanalyzer"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-acmpca","keywords":["aws-acmpca","acmpca","certificateauthority"],"labels":["@aws-cdk/aws-acmpca"],"assignees":["skinny85"]}, @@ -56,7 +57,7 @@ jobs: {"area":"@aws-cdk/aws-certificatemanager","keywords":["aws-certificatemanager","certificate-manager","dnsvalidatedcertificate","acm"],"labels":["@aws-cdk/aws-certificatemanager"],"assignees":["njlynch"]}, {"area":"@aws-cdk/aws-chatbot","keywords":["aws-chatbot","chatbot","slackchannelconfiguration"],"labels":["@aws-cdk/aws-chatbot"],"assignees":["kaizen3031593"]}, {"area":"@aws-cdk/aws-cloud9","keywords":["aws-cloud9","cloud 9","ec2environment"],"labels":["@aws-cdk/aws-cloud9"],"assignees":["skinny85"]}, - {"area":"@aws-cdk/aws-cloudformation","keywords":["aws-cloudformation","nestedstack","customresource"],"labels":["@aws-cdk/aws-cloudformation"],"assignees":["rix0rrr"]}, + {"area":"@aws-cdk/aws-cloudformation","keywords":["aws-cloudformation","nestedstack"],"labels":["@aws-cdk/aws-cloudformation"],"assignees":["rix0rrr"]}, {"area":"@aws-cdk/aws-cloudfront","keywords":["aws-cloudfront","cloud front","cachepolicy","cloudfrontwebdistribution"],"labels":["@aws-cdk/aws-cloudfront"],"assignees":["njlynch"]}, {"area":"@aws-cdk/aws-cloudfront-origins","keywords":["aws-cloudfront-origins","cloudfront origins"],"labels":["@aws-cdk/aws-cloudfront-origins"],"assignees":["njlynch"]}, {"area":"@aws-cdk/aws-cloudtrail","keywords":["aws-cloudtrail","cloud trail","trail"],"labels":["@aws-cdk/aws-cloudtrail"],"assignees":["rix0rrr"]}, @@ -68,8 +69,8 @@ jobs: {"area":"@aws-cdk/aws-codedeploy","keywords":["aws-codedeploy","code-deploy","customlambdadeploymentconfig","ecsapplication","lambdaapplication","lambdadeploymentgroup","serverapplication"],"labels":["@aws-cdk/aws-codedeploy"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-codeguruprofiler","keywords":["aws-codeguruprofiler","codeguru-profiler","profilinggroup"],"labels":["@aws-cdk/aws-codeguruprofiler"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-codegurureviewer","keywords":["aws-codegurureviewer","codeguru-reviewer"],"labels":["@aws-cdk/aws-codegurureviewer"],"assignees":["skinny85"]}, - {"area":"@aws-cdk/aws-codepipeline","keywords":["aws-codepipeline","code-pipeline","pipeline"],"labels":["@aws-cdk/aws-codepipeline"],"assignees":["skinny85"]}, - {"area":"@aws-cdk/aws-codepipeline-actions","keywords":["aws-codepipeline-actions","codepipeline actions","jenkinsprovider"],"labels":["@aws-cdk/aws-codepipeline-actions"],"assignees":["skinny85"]}, + {"area":"@aws-cdk/aws-codepipeline","keywords":["aws-codepipeline","code-pipeline"],"labels":["@aws-cdk/aws-codepipeline"],"assignees":["skinny85"]}, + {"area":"@aws-cdk/aws-codepipeline-actions","keywords":["aws-codepipeline-actions","codepipeline-actions","jenkinsprovider"],"labels":["@aws-cdk/aws-codepipeline-actions"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-codestar","keywords":["aws-codestar","codestar","githubrepository"],"labels":["@aws-cdk/aws-codestar"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-codestarconnections","keywords":["aws-codestarconnections","codestar-connections"],"labels":["@aws-cdk/aws-codestarconnections"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-codestarnotifications","keywords":["aws-codestarnotifications","codestar-notifications"],"labels":["@aws-cdk/aws-codestarnotifications"],"assignees":["skinny85"]}, From 3ea6873af6e36380d23979bf646451f9cc1a549e Mon Sep 17 00:00:00 2001 From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com> Date: Wed, 27 Oct 2021 05:08:43 -0400 Subject: [PATCH 051/148] docs(kms): make examples compile (#17167) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-kms/README.md | 32 +++++++++---------- .../aws-kms/rosetta/default.ts-fixture | 14 ++++++++ 2 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 packages/@aws-cdk/aws-kms/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-kms/README.md b/packages/@aws-cdk/aws-kms/README.md index 098e643440784..201accf122675 100644 --- a/packages/@aws-cdk/aws-kms/README.md +++ b/packages/@aws-cdk/aws-kms/README.md @@ -14,10 +14,8 @@ Define a KMS key: ```ts -import * as kms from '@aws-cdk/aws-kms'; - new kms.Key(this, 'MyKey', { - enableKeyRotation: true + enableKeyRotation: true, }); ``` @@ -27,7 +25,7 @@ Specifies the number of days in the waiting period before AWS KMS deletes a CMK ```ts const key = new kms.Key(this, 'MyKey', { - pendingWindow: 10 // Default to 30 Days + pendingWindow: Duration.days(10), // Default to 30 Days }); ``` @@ -48,7 +46,7 @@ Valid `keySpec` values depends on `keyUsage` value. ```ts const key = new kms.Key(this, 'MyKey', { keySpec: kms.KeySpec.ECC_SECG_P256K1, // Default to SYMMETRIC_DEFAULT - keyUsage: kms.KeyUsage.SIGN_VERIFY // and ENCRYPT_DECRYPT + keyUsage: kms.KeyUsage.SIGN_VERIFY, // and ENCRYPT_DECRYPT }); ``` @@ -84,10 +82,12 @@ If a Key has an associated Alias, the Alias can be imported by name and used in of the Key as a reference. A common scenario for this is in referencing AWS managed keys. ```ts +import * as cloudtrail from '@aws-cdk/aws-cloudtrail'; + const myKeyAlias = kms.Alias.fromAliasName(this, 'myKey', 'alias/aws/s3'); const trail = new cloudtrail.Trail(this, 'myCloudTrail', { - sendToCloudWatchLogs: true, - kmsKey: myKeyAlias + sendToCloudWatchLogs: true, + kmsKey: myKeyAlias, }); ``` @@ -110,7 +110,7 @@ Here's how `Key.fromLookup()` can be used: ```ts const myKeyLookup = kms.Key.fromLookup(this, 'MyKeyLookup', { - aliasName: 'alias/KeyAlias' + aliasName: 'alias/KeyAlias', }); const role = new iam.Role(this, 'MyRole', { @@ -138,7 +138,7 @@ which is set for all new projects; for existing projects, this same behavior can passing the `trustAccountIdentities` property as `true` when creating the key: ```ts -new kms.Key(stack, 'MyKey', { trustAccountIdentities: true }); +new kms.Key(this, 'MyKey', { trustAccountIdentities: true }); ``` With either the `@aws-cdk/aws-kms:defaultKeyPolicies` feature flag set, @@ -158,8 +158,8 @@ This enables the root account user -- via IAM policies -- to grant access to oth With the above default policy, future permissions can be added to either the key policy or IAM principal policy. ```ts -const key = new kms.Key(stack, 'MyKey'); -const user = new iam.User(stack, 'MyUser'); +const key = new kms.Key(this, 'MyKey'); +const user = new iam.User(this, 'MyUser'); key.grantEncrypt(user); // Adds encrypt permissions to user policy; key policy is unmodified. ``` @@ -177,12 +177,12 @@ A common addition to the key policy would be to add other key admins that are al via the `grantAdmin` method. ```ts -const myTrustedAdminRole = iam.Role.fromRoleArn(stack, 'TrustedRole', 'arn:aws:iam:....'); -const key = new kms.Key(stack, 'MyKey', { +const myTrustedAdminRole = iam.Role.fromRoleArn(this, 'TrustedRole', 'arn:aws:iam:....'); +const key = new kms.Key(this, 'MyKey', { admins: [myTrustedAdminRole], }); -const secondKey = new kms.Key(stack, 'MyKey2'); +const secondKey = new kms.Key(this, 'MyKey2'); secondKey.grantAdmin(myTrustedAdminRole); ``` @@ -193,7 +193,7 @@ and with `trustedAccountIdentities` set to false (the default), specifying a pol provided policy to the default key policy, rather than _replacing_ the default policy. ```ts -const myTrustedAdminRole = iam.Role.fromRoleArn(stack, 'TrustedRole', 'arn:aws:iam:....'); +const myTrustedAdminRole = iam.Role.fromRoleArn(this, 'TrustedRole', 'arn:aws:iam:....'); // Creates a limited admin policy and assigns to the account root. const myCustomPolicy = new iam.PolicyDocument({ statements: [new iam.PolicyStatement({ @@ -208,7 +208,7 @@ const myCustomPolicy = new iam.PolicyDocument({ resources: ['*'], })], }); -const key = new kms.Key(stack, 'MyKey', { +const key = new kms.Key(this, 'MyKey', { policy: myCustomPolicy, }); ``` diff --git a/packages/@aws-cdk/aws-kms/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-kms/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..3e5ab4d8a6ab9 --- /dev/null +++ b/packages/@aws-cdk/aws-kms/rosetta/default.ts-fixture @@ -0,0 +1,14 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { Duration, Stack } from '@aws-cdk/core'; +import * as kms from '@aws-cdk/aws-kms'; +import * as iam from '@aws-cdk/aws-iam'; + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} + From a605525ddda34d36ded30cd19bc0a1b45b3b870a Mon Sep 17 00:00:00 2001 From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com> Date: Wed, 27 Oct 2021 06:00:50 -0400 Subject: [PATCH 052/148] docs(ecr): make examples compile (#17169) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-ecr/README.md | 24 +++++++++---------- .../aws-ecr/rosetta/default.ts-fixture | 23 ++++++++++++++++++ 2 files changed, 34 insertions(+), 13 deletions(-) create mode 100644 packages/@aws-cdk/aws-ecr/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-ecr/README.md b/packages/@aws-cdk/aws-ecr/README.md index 03172cac6ff82..193d5de2f0645 100644 --- a/packages/@aws-cdk/aws-ecr/README.md +++ b/packages/@aws-cdk/aws-ecr/README.md @@ -27,16 +27,19 @@ const repository = new ecr.Repository(this, 'Repository'); Amazon ECR image scanning helps in identifying software vulnerabilities in your container images. You can manually scan container images stored in Amazon ECR, or you can configure your repositories to scan images when you push them to a repository. To create a new repository to scan on push, simply enable `imageScanOnPush` in the properties ```ts -const repository = new ecr.Repository(stack, 'Repo', { - imageScanOnPush: true +const repository = new ecr.Repository(this, 'Repo', { + imageScanOnPush: true, }); ``` To create an `onImageScanCompleted` event rule and trigger the event target ```ts +declare const repository: ecr.Repository; +declare const target: SomeTarget; + repository.onImageScanCompleted('ImageScanComplete') - .addTarget(...) + .addTarget(target); ``` ### Authorization Token @@ -50,10 +53,7 @@ A Docker authorization token can be obtained using the `GetAuthorizationToken` E grants an IAM user access to call this API. ```ts -import * as iam from '@aws-cdk/aws-iam'; -import * as ecr from '@aws-cdk/aws-ecr'; - -const user = new iam.User(this, 'User', { ... }); +const user = new iam.User(this, 'User'); ecr.AuthorizationToken.grantRead(user); ``` @@ -65,10 +65,7 @@ higher rate and bandwidth limits. The following code snippet grants an IAM user access to retrieve an authorization token for the public gallery. ```ts -import * as iam from '@aws-cdk/aws-iam'; -import * as ecr from '@aws-cdk/aws-ecr'; - -const user = new iam.User(this, 'User', { ... }); +const user = new iam.User(this, 'User'); ecr.PublicGalleryAuthorizationToken.grantRead(user); ``` @@ -79,7 +76,7 @@ This user can then proceed to login to the registry using one of the [authentica You can set tag immutability on images in our repository using the `imageTagMutability` construct prop. ```ts -new ecr.Repository(stack, 'Repo', { imageTagMutability: ecr.TagMutability.IMMUTABLE }); +new ecr.Repository(this, 'Repo', { imageTagMutability: ecr.TagMutability.IMMUTABLE }); ``` ## Automatically clean up repositories @@ -91,6 +88,7 @@ against that image. For example, the following deletes images older than is important here): ```ts +declare const repository: ecr.Repository; repository.addLifecycleRule({ tagPrefixList: ['prod'], maxImageCount: 9999 }); -repository.addLifecycleRule({ maxImageAge: cdk.Duration.days(30) }); +repository.addLifecycleRule({ maxImageAge: Duration.days(30) }); ``` diff --git a/packages/@aws-cdk/aws-ecr/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-ecr/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..6381522ef9b78 --- /dev/null +++ b/packages/@aws-cdk/aws-ecr/rosetta/default.ts-fixture @@ -0,0 +1,23 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { Duration, Stack } from '@aws-cdk/core'; +import * as ecr from '@aws-cdk/aws-ecr'; +import * as events from '@aws-cdk/aws-events'; +import * as iam from '@aws-cdk/aws-iam'; + +class SomeTarget implements events.IRuleTarget { + public bind(): events.RuleTargetConfig { + return { + arn: 'ARN1', + }; + } +} + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} + From f357955b9bd17bf705832336d12835c3de5c3d40 Mon Sep 17 00:00:00 2001 From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com> Date: Wed, 27 Oct 2021 06:56:03 -0400 Subject: [PATCH 053/148] docs(ecs-patterns): make examples compile (#17171) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-ecs-patterns/README.md | 233 ++++++++++-------- .../rosetta/default.ts-fixture | 17 ++ 2 files changed, 146 insertions(+), 104 deletions(-) create mode 100644 packages/@aws-cdk/aws-ecs-patterns/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-ecs-patterns/README.md b/packages/@aws-cdk/aws-ecs-patterns/README.md index 00212e704e294..386682e0b75d9 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/README.md +++ b/packages/@aws-cdk/aws-ecs-patterns/README.md @@ -24,14 +24,15 @@ To define an Amazon ECS service that is behind an application load balancer, ins * `ApplicationLoadBalancedEc2Service` ```ts -const loadBalancedEcsService = new ecsPatterns.ApplicationLoadBalancedEc2Service(stack, 'Service', { +declare const cluster: ecs.Cluster; +const loadBalancedEcsService = new ecsPatterns.ApplicationLoadBalancedEc2Service(this, 'Service', { cluster, memoryLimitMiB: 1024, taskImageOptions: { image: ecs.ContainerImage.fromRegistry('test'), environment: { TEST_ENVIRONMENT_VARIABLE1: "test environment variable 1 value", - TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value" + TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value", }, }, desiredCount: 2, @@ -41,7 +42,8 @@ const loadBalancedEcsService = new ecsPatterns.ApplicationLoadBalancedEc2Service * `ApplicationLoadBalancedFargateService` ```ts -const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'Service', { +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', { cluster, memoryLimitMiB: 1024, cpu: 512, @@ -78,7 +80,8 @@ Additionally, if more than one application target group are needed, instantiate ```ts // One application load balancer with one listener and two target groups. -const loadBalancedEc2Service = new ApplicationMultipleTargetGroupsEc2Service(stack, 'Service', { +declare const cluster: ecs.Cluster; +const loadBalancedEc2Service = new ecsPatterns.ApplicationMultipleTargetGroupsEc2Service(this, 'Service', { cluster, memoryLimitMiB: 256, taskImageOptions: { @@ -91,9 +94,9 @@ const loadBalancedEc2Service = new ApplicationMultipleTargetGroupsEc2Service(sta { containerPort: 90, pathPattern: 'a/b/c', - priority: 10 - } - ] + priority: 10, + }, + ], }); ``` @@ -101,7 +104,8 @@ const loadBalancedEc2Service = new ApplicationMultipleTargetGroupsEc2Service(sta ```ts // One application load balancer with one listener and two target groups. -const loadBalancedFargateService = new ApplicationMultipleTargetGroupsFargateService(stack, 'Service', { +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.ApplicationMultipleTargetGroupsFargateService(this, 'Service', { cluster, memoryLimitMiB: 1024, cpu: 512, @@ -115,9 +119,9 @@ const loadBalancedFargateService = new ApplicationMultipleTargetGroupsFargateSer { containerPort: 90, pathPattern: 'a/b/c', - priority: 10 - } - ] + priority: 10, + }, + ], }); ``` @@ -128,14 +132,15 @@ To define an Amazon ECS service that is behind a network load balancer, instanti * `NetworkLoadBalancedEc2Service` ```ts -const loadBalancedEcsService = new ecsPatterns.NetworkLoadBalancedEc2Service(stack, 'Service', { +declare const cluster: ecs.Cluster; +const loadBalancedEcsService = new ecsPatterns.NetworkLoadBalancedEc2Service(this, 'Service', { cluster, memoryLimitMiB: 1024, taskImageOptions: { image: ecs.ContainerImage.fromRegistry('test'), environment: { TEST_ENVIRONMENT_VARIABLE1: "test environment variable 1 value", - TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value" + TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value", }, }, desiredCount: 2, @@ -145,7 +150,8 @@ const loadBalancedEcsService = new ecsPatterns.NetworkLoadBalancedEc2Service(sta * `NetworkLoadBalancedFargateService` ```ts -const loadBalancedFargateService = new ecsPatterns.NetworkLoadBalancedFargateService(stack, 'Service', { +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.NetworkLoadBalancedFargateService(this, 'Service', { cluster, memoryLimitMiB: 1024, cpu: 512, @@ -167,7 +173,8 @@ Additionally, if more than one network target group is needed, instantiate one o ```ts // Two network load balancers, each with their own listener and target group. -const loadBalancedEc2Service = new NetworkMultipleTargetGroupsEc2Service(stack, 'Service', { +declare const cluster: ecs.Cluster; +const loadBalancedEc2Service = new ecsPatterns.NetworkMultipleTargetGroupsEc2Service(this, 'Service', { cluster, memoryLimitMiB: 256, taskImageOptions: { @@ -178,29 +185,29 @@ const loadBalancedEc2Service = new NetworkMultipleTargetGroupsEc2Service(stack, name: 'lb1', listeners: [ { - name: 'listener1' - } - ] + name: 'listener1', + }, + ], }, { name: 'lb2', listeners: [ { - name: 'listener2' - } - ] - } + name: 'listener2', + }, + ], + }, ], targetGroups: [ { containerPort: 80, - listener: 'listener1' + listener: 'listener1', }, { containerPort: 90, - listener: 'listener2' - } - ] + listener: 'listener2', + }, + ], }); ``` @@ -208,7 +215,8 @@ const loadBalancedEc2Service = new NetworkMultipleTargetGroupsEc2Service(stack, ```ts // Two network load balancers, each with their own listener and target group. -const loadBalancedFargateService = new NetworkMultipleTargetGroupsFargateService(stack, 'Service', { +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.NetworkMultipleTargetGroupsFargateService(this, 'Service', { cluster, memoryLimitMiB: 512, taskImageOptions: { @@ -219,29 +227,29 @@ const loadBalancedFargateService = new NetworkMultipleTargetGroupsFargateService name: 'lb1', listeners: [ { - name: 'listener1' - } - ] + name: 'listener1', + }, + ], }, { name: 'lb2', listeners: [ { - name: 'listener2' - } - ] - } + name: 'listener2', + }, + ], + }, ], targetGroups: [ { containerPort: 80, - listener: 'listener1' + listener: 'listener1', }, { containerPort: 90, - listener: 'listener2' - } - ] + listener: 'listener2', + }, + ], }); ``` @@ -252,7 +260,8 @@ To define a service that creates a queue and reads from that queue, instantiate * `QueueProcessingEc2Service` ```ts -const queueProcessingEc2Service = new QueueProcessingEc2Service(stack, 'Service', { +declare const cluster: ecs.Cluster; +const queueProcessingEc2Service = new ecsPatterns.QueueProcessingEc2Service(this, 'Service', { cluster, memoryLimitMiB: 1024, image: ecs.ContainerImage.fromRegistry('test'), @@ -261,9 +270,8 @@ const queueProcessingEc2Service = new QueueProcessingEc2Service(stack, 'Service' desiredTaskCount: 2, environment: { TEST_ENVIRONMENT_VARIABLE1: "test environment variable 1 value", - TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value" + TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value", }, - queue, maxScalingCapacity: 5, containerName: 'test', }); @@ -272,7 +280,8 @@ const queueProcessingEc2Service = new QueueProcessingEc2Service(stack, 'Service' * `QueueProcessingFargateService` ```ts -const queueProcessingFargateService = new QueueProcessingFargateService(stack, 'Service', { +declare const cluster: ecs.Cluster; +const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', { cluster, memoryLimitMiB: 512, image: ecs.ContainerImage.fromRegistry('test'), @@ -281,9 +290,8 @@ const queueProcessingFargateService = new QueueProcessingFargateService(stack, ' desiredTaskCount: 2, environment: { TEST_ENVIRONMENT_VARIABLE1: "test environment variable 1 value", - TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value" + TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value", }, - queue, maxScalingCapacity: 5, containerName: 'test', }); @@ -299,29 +307,31 @@ To define a task that runs periodically, there are 2 options: ```ts // Instantiate an Amazon EC2 Task to run at a scheduled interval -const ecsScheduledTask = new ScheduledEc2Task(stack, 'ScheduledTask', { +declare const cluster: ecs.Cluster; +const ecsScheduledTask = new ecsPatterns.ScheduledEc2Task(this, 'ScheduledTask', { cluster, scheduledEc2TaskImageOptions: { image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), memoryLimitMiB: 256, environment: { name: 'TRIGGER', value: 'CloudWatch Events' }, }, - schedule: events.Schedule.expression('rate(1 minute)'), + schedule: appscaling.Schedule.expression('rate(1 minute)'), enabled: true, - ruleName: 'sample-scheduled-task-rule' + ruleName: 'sample-scheduled-task-rule', }); ``` * `ScheduledFargateTask` ```ts -const scheduledFargateTask = new ScheduledFargateTask(stack, 'ScheduledFargateTask', { +declare const cluster: ecs.Cluster; +const scheduledFargateTask = new ecsPatterns.ScheduledFargateTask(this, 'ScheduledFargateTask', { cluster, scheduledFargateTaskImageOptions: { image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), memoryLimitMiB: 512, }, - schedule: events.Schedule.expression('rate(1 minute)'), + schedule: appscaling.Schedule.expression('rate(1 minute)'), platformVersion: ecs.FargatePlatformVersion.LATEST, }); ``` @@ -333,7 +343,6 @@ In addition to using the constructs, users can also add logic to customize these ### Configure HTTPS on an ApplicationLoadBalancedFargateService ```ts -import { ApplicationLoadBalancedFargateService } from './application-load-balanced-fargate-service'; import { HostedZone } from '@aws-cdk/aws-route53'; import { Certificate } from '@aws-cdk/aws-certificatemanager'; import { SslPolicy } from '@aws-cdk/aws-elasticloadbalancingv2'; @@ -341,8 +350,10 @@ import { SslPolicy } from '@aws-cdk/aws-elasticloadbalancingv2'; const domainZone = HostedZone.fromLookup(this, 'Zone', { domainName: 'example.com' }); const certificate = Certificate.fromCertificateArn(this, 'Cert', 'arn:aws:acm:us-east-1:123456:certificate/abcdefg'); -const loadBalancedFargateService = new ApplicationLoadBalancedFargateService(stack, 'Service', { - vpc +declare const vpc: ec2.Vpc; +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', { + vpc, cluster, certificate, sslPolicy: SslPolicy.RECOMMENDED, @@ -358,10 +369,8 @@ const loadBalancedFargateService = new ApplicationLoadBalancedFargateService(sta ### Add Schedule-Based Auto-Scaling to an ApplicationLoadBalancedFargateService ```ts -import { Schedule } from '@aws-cdk/aws-applicationautoscaling'; -import { ApplicationLoadBalancedFargateService, ApplicationLoadBalancedFargateServiceProps } from './application-load-balanced-fargate-service'; - -const loadBalancedFargateService = new ApplicationLoadBalancedFargateService(stack, 'Service', { +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', { cluster, memoryLimitMiB: 1024, desiredCount: 1, @@ -377,12 +386,12 @@ const scalableTarget = loadBalancedFargateService.service.autoScaleTaskCount({ }); scalableTarget.scaleOnSchedule('DaytimeScaleDown', { - schedule: Schedule.cron({ hour: '8', minute: '0'}), + schedule: appscaling.Schedule.cron({ hour: '8', minute: '0'}), minCapacity: 1, }); scalableTarget.scaleOnSchedule('EveningRushScaleUp', { - schedule: Schedule.cron({ hour: '20', minute: '0'}), + schedule: appscaling.Schedule.cron({ hour: '20', minute: '0'}), minCapacity: 10, }); ``` @@ -390,9 +399,8 @@ scalableTarget.scaleOnSchedule('EveningRushScaleUp', { ### Add Metric-Based Auto-Scaling to an ApplicationLoadBalancedFargateService ```ts -import { ApplicationLoadBalancedFargateService } from './application-load-balanced-fargate-service'; - -const loadBalancedFargateService = new ApplicationLoadBalancedFargateService(stack, 'Service', { +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', { cluster, memoryLimitMiB: 1024, desiredCount: 1, @@ -419,9 +427,8 @@ scalableTarget.scaleOnMemoryUtilization('MemoryScaling', { ### Change the default Deployment Controller ```ts -import { ApplicationLoadBalancedFargateService } from './application-load-balanced-fargate-service'; - -const loadBalancedFargateService = new ApplicationLoadBalancedFargateService(stack, 'Service', { +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', { cluster, memoryLimitMiB: 1024, desiredCount: 1, @@ -443,7 +450,8 @@ deployment circuit breaker and optionally enable `rollback` for automatic rollba for more details. ```ts -const service = new ApplicationLoadBalancedFargateService(stack, 'Service', { +declare const cluster: ecs.Cluster; +const service = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', { cluster, memoryLimitMiB: 1024, desiredCount: 1, @@ -458,7 +466,8 @@ const service = new ApplicationLoadBalancedFargateService(stack, 'Service', { ### Set deployment configuration on QueueProcessingService ```ts -const queueProcessingFargateService = new QueueProcessingFargateService(stack, 'Service', { +declare const cluster: ecs.Cluster; +const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', { cluster, memoryLimitMiB: 512, image: ecs.ContainerImage.fromRegistry('test'), @@ -466,17 +475,18 @@ const queueProcessingFargateService = new QueueProcessingFargateService(stack, ' enableLogging: false, desiredTaskCount: 2, environment: {}, - queue, maxScalingCapacity: 5, maxHealthyPercent: 200, - minHealthPercent: 66, + minHealthyPercent: 66, }); ``` ### Set taskSubnets and securityGroups for QueueProcessingFargateService ```ts -const queueProcessingFargateService = new QueueProcessingFargateService(stack, 'Service', { +declare const vpc: ec2.Vpc; +declare const securityGroup: ec2.SecurityGroup; +const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', { vpc, memoryLimitMiB: 512, image: ecs.ContainerImage.fromRegistry('test'), @@ -488,7 +498,8 @@ const queueProcessingFargateService = new QueueProcessingFargateService(stack, ' ### Define tasks with public IPs for QueueProcessingFargateService ```ts -const queueProcessingFargateService = new QueueProcessingFargateService(stack, 'Service', { +declare const vpc: ec2.Vpc; +const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', { vpc, memoryLimitMiB: 512, image: ecs.ContainerImage.fromRegistry('test'), @@ -499,24 +510,24 @@ const queueProcessingFargateService = new QueueProcessingFargateService(stack, ' ### Define tasks with custom queue parameters for QueueProcessingFargateService ```ts -const queueProcessingFargateService = new QueueProcessingFargateService(stack, 'Service', { +declare const vpc: ec2.Vpc; +const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', { vpc, memoryLimitMiB: 512, image: ecs.ContainerImage.fromRegistry('test'), maxReceiveCount: 42, - retentionPeriod: cdk.Duration.days(7), - visibilityTimeout: cdk.Duration.minutes(5), + retentionPeriod: Duration.days(7), + visibilityTimeout: Duration.minutes(5), }); ``` ### Set capacityProviderStrategies for QueueProcessingFargateService ```ts -const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 1 }); -const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); +declare const cluster: ecs.Cluster; cluster.enableFargateCapacityProviders(); -const queueProcessingFargateService = new QueueProcessingFargateService(stack, 'Service', { +const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', { cluster, memoryLimitMiB: 512, image: ecs.ContainerImage.fromRegistry('test'), @@ -536,19 +547,21 @@ const queueProcessingFargateService = new QueueProcessingFargateService(stack, ' ### Set capacityProviderStrategies for QueueProcessingEc2Service ```ts -const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 1 }); -const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); -const autoScalingGroup = new autoscaling.AutoScalingGroup(stack, 'asg', { +import * as autoscaling from '@aws-cdk/aws-autoscaling'; + +const vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 1 }); +const cluster = new ecs.Cluster(this, 'EcsCluster', { vpc }); +const autoScalingGroup = new autoscaling.AutoScalingGroup(this, 'asg', { vpc, instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), machineImage: ecs.EcsOptimizedImage.amazonLinux2(), }); -const capacityProvider = new ecs.AsgCapacityProvider(stack, 'provider', { +const capacityProvider = new ecs.AsgCapacityProvider(this, 'provider', { autoScalingGroup, }); cluster.addAsgCapacityProvider(capacityProvider); -const queueProcessingFargateService = new QueueProcessingFargateService(stack, 'Service', { +const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', { cluster, memoryLimitMiB: 512, image: ecs.ContainerImage.fromRegistry('test'), @@ -563,7 +576,8 @@ const queueProcessingFargateService = new QueueProcessingFargateService(stack, ' ### Select specific vpc subnets for ApplicationLoadBalancedFargateService ```ts -const loadBalancedFargateService = new ApplicationLoadBalancedFargateService(stack, 'Service', { +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', { cluster, memoryLimitMiB: 1024, desiredCount: 1, @@ -571,8 +585,8 @@ const loadBalancedFargateService = new ApplicationLoadBalancedFargateService(sta taskImageOptions: { image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), }, - vpcSubnets: { - subnets: [ec2.Subnet.fromSubnetId(stack, 'subnet', 'VpcISOLATEDSubnet1Subnet80F07FA0')], + taskSubnets: { + subnets: [ec2.Subnet.fromSubnetId(this, 'subnet', 'VpcISOLATEDSubnet1Subnet80F07FA0')], }, }); ``` @@ -580,13 +594,14 @@ const loadBalancedFargateService = new ApplicationLoadBalancedFargateService(sta ### Set PlatformVersion for ScheduledFargateTask ```ts -const scheduledFargateTask = new ScheduledFargateTask(stack, 'ScheduledFargateTask', { +declare const cluster: ecs.Cluster; +const scheduledFargateTask = new ecsPatterns.ScheduledFargateTask(this, 'ScheduledFargateTask', { cluster, scheduledFargateTaskImageOptions: { image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), memoryLimitMiB: 512, }, - schedule: events.Schedule.expression('rate(1 minute)'), + schedule: appscaling.Schedule.expression('rate(1 minute)'), platformVersion: ecs.FargatePlatformVersion.VERSION1_4, }); ``` @@ -594,18 +609,17 @@ const scheduledFargateTask = new ScheduledFargateTask(stack, 'ScheduledFargateTa ### Set SecurityGroups for ScheduledFargateTask ```ts -const stack = new cdk.Stack(); -const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 1 }); -const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc }); -const securityGroup = new ec2.SecurityGroup(stack, 'SG', { vpc }); +const vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 1 }); +const cluster = new ecs.Cluster(this, 'EcsCluster', { vpc }); +const securityGroup = new ec2.SecurityGroup(this, 'SG', { vpc }); -const scheduledFargateTask = new ScheduledFargateTask(stack, 'ScheduledFargateTask', { +const scheduledFargateTask = new ecsPatterns.ScheduledFargateTask(this, 'ScheduledFargateTask', { cluster, scheduledFargateTaskImageOptions: { image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), memoryLimitMiB: 512, }, - schedule: events.Schedule.expression('rate(1 minute)'), + schedule: appscaling.Schedule.expression('rate(1 minute)'), securityGroups: [securityGroup], }); ``` @@ -626,12 +640,20 @@ If a desiredCount is not passed in as input to the above constructs, CloudFormat To enable the feature flag, ensure that the REMOVE_DEFAULT_DESIRED_COUNT flag within an application stack context is set to true, like so: ```ts +declare const stack: Stack; stack.node.setContext(cxapi.ECS_REMOVE_DEFAULT_DESIRED_COUNT, true); ``` The following is an example of an application with the REMOVE_DEFAULT_DESIRED_COUNT feature flag enabled: -```ts +```ts nofixture +import { App, Stack } from '@aws-cdk/core'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as ecs from '@aws-cdk/aws-ecs'; +import * as ecsPatterns from '@aws-cdk/aws-ecs-patterns'; +import * as cxapi from '@aws-cdk/cx-api'; +import * as path from 'path'; + const app = new App(); const stack = new Stack(app, 'aws-ecs-patterns-queue'); @@ -641,7 +663,7 @@ const vpc = new ec2.Vpc(stack, 'VPC', { maxAzs: 2, }); -new QueueProcessingFargateService(stack, 'QueueProcessingService', { +new ecsPatterns.QueueProcessingFargateService(stack, 'QueueProcessingService', { vpc, memoryLimitMiB: 512, image: new ecs.AssetImage(path.join(__dirname, '..', 'sqs-reader')), @@ -653,28 +675,31 @@ new QueueProcessingFargateService(stack, 'QueueProcessingService', { The following is an example of deploying an application along with a metrics sidecar container that utilizes `dockerLabels` for discovery: ```ts -const service = new ApplicationLoadBalancedFargateService(stack, 'Service', { +declare const cluster: ecs.Cluster; +declare const vpc: ec2.Vpc; +const service = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', { cluster, vpc, desiredCount: 1, taskImageOptions: { image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), + dockerLabels: { + 'application.label.one': 'first_label', + 'application.label.two': 'second_label', + }, }, - dockerLabels: { - 'application.label.one': 'first_label' - 'application.label.two': 'second_label' - } }); service.taskDefinition.addContainer('Sidecar', { - image: ContainerImage.fromRegistry('example/metrics-sidecar') -} + image: ecs.ContainerImage.fromRegistry('example/metrics-sidecar'), +}); ``` ### Select specific load balancer name ApplicationLoadBalancedFargateService ```ts -const loadBalancedFargateService = new ApplicationLoadBalancedFargateService(stack, 'Service', { +declare const cluster: ecs.Cluster; +const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', { cluster, memoryLimitMiB: 1024, desiredCount: 1, @@ -682,8 +707,8 @@ const loadBalancedFargateService = new ApplicationLoadBalancedFargateService(sta taskImageOptions: { image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), }, - vpcSubnets: { - subnets: [ec2.Subnet.fromSubnetId(stack, 'subnet', 'VpcISOLATEDSubnet1Subnet80F07FA0')], + taskSubnets: { + subnets: [ec2.Subnet.fromSubnetId(this, 'subnet', 'VpcISOLATEDSubnet1Subnet80F07FA0')], }, loadBalancerName: 'application-lb-name', }); diff --git a/packages/@aws-cdk/aws-ecs-patterns/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-ecs-patterns/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..e998fef0a9210 --- /dev/null +++ b/packages/@aws-cdk/aws-ecs-patterns/rosetta/default.ts-fixture @@ -0,0 +1,17 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { Duration, Stack } from '@aws-cdk/core'; +import * as ecs from '@aws-cdk/aws-ecs'; +import * as ecsPatterns from '@aws-cdk/aws-ecs-patterns'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as appscaling from '@aws-cdk/aws-applicationautoscaling'; +import * as cxapi from '@aws-cdk/cx-api'; + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} + From a8528577a841064ccdc11bb1fbd8d8046073fa8a Mon Sep 17 00:00:00 2001 From: Nick Lynch Date: Wed, 27 Oct 2021 12:48:43 +0100 Subject: [PATCH 054/148] chore: update DEPRECATED_APIs.md and introduce new plaintext format (#17120) As part of the upcoming v2 GA, we need to update (and lock in) the final list of deprecated APIs that will be removed from V2. At the same time, we need to create the input for `jsii`'s new `--strip-deprecated` file input, where only a subset of deprecated items are stripped away (see #16566). This change does both by introducing a new output format for `list-deprecated-apis` and feeding that value into `jsii` at compile time. fixes #16566 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- DEPRECATED_APIs.md | 286 +++++++- deprecated_apis.txt | 1121 +++++++++++++++++++++++++++++++ scripts/list-deprecated-apis.js | 81 ++- 3 files changed, 1448 insertions(+), 40 deletions(-) create mode 100644 deprecated_apis.txt diff --git a/DEPRECATED_APIs.md b/DEPRECATED_APIs.md index a08cf9de97f86..fdf0a1877b5dc 100644 --- a/DEPRECATED_APIs.md +++ b/DEPRECATED_APIs.md @@ -3,6 +3,8 @@ | Module | API Element | Message | |--------|-------------|---------| | @aws-cdk/core | AppProps.โ€‹runtimeInfo | use `versionReporting` instead | +| @aws-cdk/core | Arn.โ€‹parse() | use split instead | +| @aws-cdk/core | ArnComponents.โ€‹sep | use arnFormat instead | | @aws-cdk/core | AssetHashType.โ€‹BUNDLE | use `OUTPUT` instead | | @aws-cdk/core | AssetStaging.โ€‹sourceHash | see `assetHash`. | | @aws-cdk/core | AssetStaging.โ€‹stagedPath | Use `absoluteStagedPath` instead. | @@ -40,11 +42,13 @@ | @aws-cdk/core | Stack.โ€‹parentStack | use `nestedStackParent` | | @aws-cdk/core | Stack.โ€‹addDockerImageAsset() | Use `stack.synthesizer.addDockerImageAsset()` if you are calling, and a different `IStackSynthesizer` class if you are implementing. | | @aws-cdk/core | Stack.โ€‹addFileAsset() | Use `stack.synthesizer.addFileAsset()` if you are calling, and a different IStackSynthesizer class if you are implementing. | +| @aws-cdk/core | Stack.โ€‹parseArn() | use splitArn instead | | @aws-cdk/core | Stack.โ€‹prepareCrossReference() | cross reference handling has been moved to `App.prepare()`. | | @aws-cdk/core | Stack.โ€‹reportMissingContext() | use `reportMissingContextKey()` | | @aws-cdk/core | SynthesisOptions | use `app.synth()` or `stage.synth()` instead | | @aws-cdk/core | SynthesisOptions.โ€‹outdir | use `app.synth()` or `stage.synth()` instead | | @aws-cdk/core | SynthesisOptions.โ€‹skipValidation | use `app.synth()` or `stage.synth()` instead | +| @aws-cdk/core | SynthesisOptions.โ€‹validateOnSynthesis | use `app.synth()` or `stage.synth()` instead | | @aws-cdk/core | Tag.โ€‹add() | use `Tags.of(scope).add()` | | @aws-cdk/core | Tag.โ€‹remove() | use `Tags.of(scope).remove()` | | @aws-cdk/cloud-assembly-schema | ContainerImageAssetMetadataEntry.โ€‹imageNameParameter | specify `repositoryName` and `imageTag` instead, and then you know where the image will go. | @@ -60,7 +64,7 @@ | @aws-cdk/cx-api | MissingContext.โ€‹provider | moved to package 'cloud-assembly-schema' | | @aws-cdk/cx-api | RuntimeInfo | moved to package 'cloud-assembly-schema' | | constructs | Construct.โ€‹onValidate() | use `Node.addValidation()` to subscribe validation functions on this construct instead of overriding this method. | -| constructs | Node.โ€‹uniqueId | please avoid using this property and use `uid` instead. This algorithm uses MD5, which is not FIPS-complient and also excludes the identity of the root construct from the calculation. | +| constructs | Node.โ€‹uniqueId | please avoid using this property and use `addr` to form unique names. This algorithm uses MD5, which is not FIPS-complient and also excludes the identity of the root construct from the calculation. | | @aws-cdk/assets | CopyOptions | see `core.CopyOptions` | | @aws-cdk/assets | CopyOptions.โ€‹exclude | see `core.CopyOptions` | | @aws-cdk/assets | CopyOptions.โ€‹follow | use `followSymlinks` instead | @@ -77,10 +81,6 @@ | @aws-cdk/assets | Staging | use `core.AssetStaging` | | @aws-cdk/assets | StagingProps | use `core.AssetStagingProps` | | @aws-cdk/assets | StagingProps.โ€‹sourcePath | use `core.AssetStagingProps` | -| @aws-cdk/aws-iam | Anyone | use `AnyPrincipal` | -| @aws-cdk/aws-iam | IPrincipal.โ€‹addToPolicy() | Use `addToPrincipalPolicy` instead. | -| @aws-cdk/aws-iam | RoleProps.โ€‹externalId | see {@link externalIds} | -| @aws-cdk/aws-kms | KeyProps.โ€‹trustAccountIdentities | redundant with the `@aws-cdk/aws-kms:defaultKeyPolicies` feature flag | | @aws-cdk/aws-codebuild | LinuxBuildImage.โ€‹UBUNTU_โ€‹14_โ€‹04_โ€‹ANDROID_โ€‹JAVA8_โ€‹24_โ€‹4_โ€‹1 | Use {@link STANDARD_2_0} and specify runtime in buildspec runtime-versions section | | @aws-cdk/aws-codebuild | LinuxBuildImage.โ€‹UBUNTU_โ€‹14_โ€‹04_โ€‹ANDROID_โ€‹JAVA8_โ€‹26_โ€‹1_โ€‹1 | Use {@link STANDARD_2_0} and specify runtime in buildspec runtime-versions section | | @aws-cdk/aws-codebuild | LinuxBuildImage.โ€‹UBUNTU_โ€‹14_โ€‹04_โ€‹BASE | Use {@link STANDARD_2_0} and specify runtime in buildspec runtime-versions section | @@ -112,10 +112,11 @@ | @aws-cdk/aws-codebuild | LinuxBuildImage.โ€‹UBUNTU_โ€‹14_โ€‹04_โ€‹RUBY_โ€‹2_โ€‹5_โ€‹1 | Use {@link STANDARD_2_0} and specify runtime in buildspec runtime-versions section | | @aws-cdk/aws-codebuild | LinuxBuildImage.โ€‹UBUNTU_โ€‹14_โ€‹04_โ€‹RUBY_โ€‹2_โ€‹5_โ€‹3 | Use {@link STANDARD_2_0} and specify runtime in buildspec runtime-versions section | | @aws-cdk/aws-codebuild | WindowsBuildImage.โ€‹WIN_โ€‹SERVER_โ€‹CORE_โ€‹2016_โ€‹BASE | `WindowsBuildImage.WINDOWS_BASE_2_0` should be used instead. | +| @aws-cdk/aws-cloudwatch | CommonMetricOptions.โ€‹dimensions | Use 'dimensionsMap' instead. | | @aws-cdk/aws-cloudwatch | CreateAlarmOptions.โ€‹period | Use `metric.with({ period: ... })` to encode the period into the Metric object | | @aws-cdk/aws-cloudwatch | CreateAlarmOptions.โ€‹statistic | Use `metric.with({ statistic: ... })` to encode the period into the Metric object | -| @aws-cdk/aws-cloudwatch | IMetric.โ€‹toAlarmConfig() | Use `toMetricsConfig()` instead. | -| @aws-cdk/aws-cloudwatch | IMetric.โ€‹toGraphConfig() | Use `toMetricsConfig()` instead. | +| @aws-cdk/aws-cloudwatch | IMetric.โ€‹toAlarmConfig() | Use `toMetricConfig()` instead. | +| @aws-cdk/aws-cloudwatch | IMetric.โ€‹toGraphConfig() | Use `toMetricConfig()` instead. | | @aws-cdk/aws-cloudwatch | MathExpression.โ€‹toAlarmConfig() | use toMetricConfig() | | @aws-cdk/aws-cloudwatch | MathExpression.โ€‹toGraphConfig() | use toMetricConfig() | | @aws-cdk/aws-cloudwatch | Metric.โ€‹toAlarmConfig() | use toMetricConfig() | @@ -143,12 +144,21 @@ | @aws-cdk/aws-cloudwatch | MetricRenderingProperties.โ€‹color | Replaced by MetricConfig. | | @aws-cdk/aws-cloudwatch | MetricRenderingProperties.โ€‹label | Replaced by MetricConfig. | | @aws-cdk/aws-cloudwatch | MetricRenderingProperties.โ€‹stat | Replaced by MetricConfig. | +| @aws-cdk/aws-iam | Anyone | use `AnyPrincipal` | +| @aws-cdk/aws-iam | IPrincipal.โ€‹addToPolicy() | Use `addToPrincipalPolicy` instead. | +| @aws-cdk/aws-iam | RoleProps.โ€‹externalId | see {@link externalIds} | | @aws-cdk/aws-events | EventBus.โ€‹grantPutEvents() | use grantAllPutEvents instead | | @aws-cdk/aws-events | RuleTargetConfig.โ€‹id | no replacement. we will always use an autogenerated id. | +| @aws-cdk/aws-ec2 | ClientVpnAuthorizationRuleProps.โ€‹clientVpnEndoint | Use `clientVpnEndpoint` instead | +| @aws-cdk/aws-ec2 | ClientVpnRouteProps.โ€‹clientVpnEndoint | Use `clientVpnEndpoint` instead | | @aws-cdk/aws-ec2 | InterfaceVpcEndpoint.โ€‹securityGroupId | use the `connections` object | | @aws-cdk/aws-ec2 | InterfaceVpcEndpointAttributes.โ€‹securityGroupId | use `securityGroups` instead | +| @aws-cdk/aws-ec2 | MachineImage.โ€‹fromSSMParameter() | Use `MachineImage.fromSsmParameter()` instead | | @aws-cdk/aws-ec2 | NatInstanceProps.โ€‹allowAllTraffic | Use `defaultAllowedTraffic`. | +| @aws-cdk/aws-ec2 | SecurityGroup.โ€‹securityGroupName | returns the security group ID, rather than the name. | | @aws-cdk/aws-ec2 | SubnetSelection.โ€‹subnetName | Use `subnetGroupName` instead | +| @aws-cdk/aws-ec2 | SubnetType.โ€‹ISOLATED | use `SubnetType.PRIVATE_ISOLATED` | +| @aws-cdk/aws-ec2 | SubnetType.โ€‹PRIVATE | use `PRIVATE_WITH_NAT` | | @aws-cdk/aws-ec2 | Vpc.โ€‹natDependencies | This value is no longer used. | | @aws-cdk/aws-ec2 | Vpc.โ€‹addDynamoDbEndpoint() | use `addGatewayEndpoint()` instead | | @aws-cdk/aws-ec2 | Vpc.โ€‹addS3Endpoint() | use `addGatewayEndpoint()` instead | @@ -168,11 +178,13 @@ | @aws-cdk/aws-ec2 | WindowsVersion.โ€‹WINDOWS_โ€‹SERVER_โ€‹2012_โ€‹RTM_โ€‹PORTUGESE_โ€‹PORTUGAL_โ€‹64BIT_โ€‹BASE | use WINDOWS_SERVER_2012_RTM_PORTUGUESE_PORTUGAL_64BIT_BASE | | @aws-cdk/aws-ec2 | WindowsVersion.โ€‹WINDOWS_โ€‹SERVER_โ€‹2019_โ€‹PORTUGESE_โ€‹BRAZIL_โ€‹FULL_โ€‹BASE | use WINDOWS_SERVER_2019_PORTUGUESE_BRAZIL_FULL_BASE | | @aws-cdk/aws-ec2 | WindowsVersion.โ€‹WINDOWS_โ€‹SERVER_โ€‹2019_โ€‹PORTUGESE_โ€‹PORTUGAL_โ€‹FULL_โ€‹BASE | use WINDOWS_SERVER_2019_PORTUGUESE_PORTUGAL_FULL_BASE | +| @aws-cdk/aws-kms | KeyProps.โ€‹trustAccountIdentities | redundant with the `@aws-cdk/aws-kms:defaultKeyPolicies` feature flag | | @aws-cdk/aws-s3-assets | Asset.โ€‹s3Url | use `httpUrl` | | @aws-cdk/aws-s3-assets | Asset.โ€‹sourceHash | see `assetHash` | | @aws-cdk/aws-s3-assets | AssetOptions.โ€‹sourceHash | see `assetHash` and `assetHashType` | | @aws-cdk/aws-ecr-assets | DockerImageAsset.โ€‹sourceHash | use assetHash | | @aws-cdk/aws-ecr-assets | DockerImageAssetOptions.โ€‹repositoryName | to control the location of docker image assets, please override `Stack.addDockerImageAsset`. this feature will be removed in future releases. | +| @aws-cdk/aws-ecr-assets | TarballImageAsset.โ€‹sourceHash | use assetHash | | @aws-cdk/aws-secretsmanager | AttachedSecretOptions | use `secret.attach()` instead | | @aws-cdk/aws-secretsmanager | AttachedSecretOptions.โ€‹target | use `secret.attach()` instead | | @aws-cdk/aws-secretsmanager | AttachmentTargetType.โ€‹INSTANCE | use RDS_DB_INSTANCE instead | @@ -181,6 +193,8 @@ | @aws-cdk/aws-secretsmanager | Secret.โ€‹fromSecretName() | use `fromSecretNameV2` | | @aws-cdk/aws-secretsmanager | Secret.โ€‹addTargetAttachment() | use `attach()` instead | | @aws-cdk/aws-secretsmanager | SecretAttributes.โ€‹secretArn | use `secretCompleteArn` or `secretPartialArn` instead. | +| @aws-cdk/aws-secretsmanager | SecretRotationApplication.โ€‹applicationId | only valid when deploying to the 'aws' partition. Use `applicationArnForPartition` instead. | +| @aws-cdk/aws-secretsmanager | SecretRotationApplication.โ€‹semanticVersion | only valid when deploying to the 'aws' partition. Use `semanticVersionForPartition` instead. | | @aws-cdk/aws-lambda | Code.โ€‹isInline | this value is ignored since inline is now determined based on the the `inlineCode` field of `CodeConfig` returned from `bind()`. | | @aws-cdk/aws-lambda | Code.โ€‹asset() | use `fromAsset` | | @aws-cdk/aws-lambda | Code.โ€‹bucket() | use `fromBucket` | @@ -188,6 +202,7 @@ | @aws-cdk/aws-lambda | Code.โ€‹inline() | use `fromInline` | | @aws-cdk/aws-lambda | Function.โ€‹addVersion() | This method will create an AWS::Lambda::Version resource which snapshots the AWS Lambda function *at the time of its creation* and it won't get updated when the function changes. Instead, use `this.currentVersion` to obtain a reference to a version resource that gets automatically recreated when the function configuration (or code) changes. | | @aws-cdk/aws-lambda | FunctionAttributes.โ€‹securityGroupId | use `securityGroup` instead | +| @aws-cdk/aws-lambda | FunctionOptions.โ€‹architectures | use `architecture` | | @aws-cdk/aws-lambda | FunctionOptions.โ€‹securityGroup | This property is deprecated, use securityGroups instead | | @aws-cdk/aws-lambda | LogRetention | use `LogRetention` from ' | | @aws-cdk/aws-lambda | LogRetentionProps | use `LogRetentionProps` from ' | @@ -472,10 +487,10 @@ | @aws-cdk/aws-apigateway | CfnStageV2Props.โ€‹routeSettings | moved to package aws-apigatewayv2 | | @aws-cdk/aws-apigateway | CfnStageV2Props.โ€‹stageVariables | moved to package aws-apigatewayv2 | | @aws-cdk/aws-apigateway | CfnStageV2Props.โ€‹tags | moved to package aws-apigatewayv2 | -| @aws-cdk/aws-apigateway | EmptyModel | You should use | -| @aws-cdk/aws-apigateway | EmptyModel.โ€‹modelId | You should use | -| @aws-cdk/aws-apigateway | ErrorModel | You should use | -| @aws-cdk/aws-apigateway | ErrorModel.โ€‹modelId | You should use | +| @aws-cdk/aws-apigateway | EmptyModel | You should use Model.EMPTY_MODEL | +| @aws-cdk/aws-apigateway | EmptyModel.โ€‹modelId | You should use Model.EMPTY_MODEL | +| @aws-cdk/aws-apigateway | ErrorModel | You should use Model.ERROR_MODEL | +| @aws-cdk/aws-apigateway | ErrorModel.โ€‹modelId | You should use Model.ERROR_MODEL | | @aws-cdk/aws-apigateway | IResource.โ€‹restApi | Throws an error if this Resource is not associated with an instance of `RestApi`. Use `api` instead. | | @aws-cdk/aws-apigateway | LambdaRestApiProps.โ€‹options | the `LambdaRestApiProps` now extends `RestApiProps`, so all options are just available here. Note that the options specified in `options` will be overridden by any props specified at the root level. | | @aws-cdk/aws-apigateway | Method.โ€‹restApi | Throws an error if this Resource is not associated with an instance of `RestApi`. Use `api` instead. | @@ -489,6 +504,7 @@ | @aws-cdk/aws-certificatemanager | CertificateProps.โ€‹validationDomains | use `validation` instead. | | @aws-cdk/aws-certificatemanager | CertificateProps.โ€‹validationMethod | use `validation` instead. | | @aws-cdk/aws-route53 | AddressRecordTarget | Use RecordTarget | +| @aws-cdk/custom-resources | AwsSdkCall.โ€‹outputPath | use outputPaths instead | | @aws-cdk/custom-resources | Provider.โ€‹bind() | use `provider.serviceToken` instead | | @aws-cdk/aws-cloudformation | CloudFormationCapabilities | use `core.CfnCapabilities` | | @aws-cdk/aws-cloudformation | CloudFormationCapabilities.โ€‹NONE | use `core.CfnCapabilities` | @@ -520,6 +536,8 @@ | @aws-cdk/aws-sns | NumericConditions.โ€‹whitelist | use `allowlist` | | @aws-cdk/aws-sns | StringConditions.โ€‹blacklist | use `denylist` | | @aws-cdk/aws-sns | StringConditions.โ€‹whitelist | use `allowlist` | +| @aws-cdk/aws-cognito | StandardAttributes.โ€‹emailVerified | this is not a standard attribute and was incorrectly added to the CDK. It is a Cognito built-in attribute and cannot be controlled as part of user pool creation. | +| @aws-cdk/aws-cognito | StandardAttributes.โ€‹phoneNumberVerified | this is not a standard attribute and was incorrectly added to the CDK. It is a Cognito built-in attribute and cannot be controlled as part of user pool creation. | | @aws-cdk/aws-elasticloadbalancingv2 | AddFixedResponseProps | Use `ApplicationListener.addAction` instead. | | @aws-cdk/aws-elasticloadbalancingv2 | AddRedirectResponseProps | Use `ApplicationListener.addAction` instead. | | @aws-cdk/aws-elasticloadbalancingv2 | AddRuleProps.โ€‹hostHeader | Use `conditions` instead. | @@ -573,6 +591,11 @@ | @aws-cdk/aws-elasticloadbalancingv2 | TargetGroupAttributes.โ€‹defaultPort | This property is unused and the wrong type. No need to use it. | | @aws-cdk/aws-elasticloadbalancingv2 | TargetGroupImportProps | Use TargetGroupAttributes instead | | @aws-cdk/aws-apigatewayv2 | IHttpApi.โ€‹httpApiId | use apiId instead | +| @aws-cdk/aws-appmesh | Protocol | not for use outside package | +| @aws-cdk/aws-appmesh | Protocol.โ€‹HTTP | not for use outside package | +| @aws-cdk/aws-appmesh | Protocol.โ€‹TCP | not for use outside package | +| @aws-cdk/aws-appmesh | Protocol.โ€‹HTTP2 | not for use outside package | +| @aws-cdk/aws-appmesh | Protocol.โ€‹GRPC | not for use outside package | | @aws-cdk/aws-dynamodb | ITable.โ€‹metricSystemErrors() | use `metricSystemErrorsForOperations` | | @aws-cdk/aws-dynamodb | Table.โ€‹grantListStreams() | Use {@link #grantTableListStreams} for more granular permission | | @aws-cdk/aws-dynamodb | Table.โ€‹metricSystemErrors() | use `metricSystemErrorsForOperations`. | @@ -594,6 +617,40 @@ | @aws-cdk/aws-rds | DatabaseInstanceEngine.โ€‹oracleSe() | instances can no longer be created with this engine. See https://forums.aws.amazon.com/ann.jspa?annID=7341 | | @aws-cdk/aws-rds | DatabaseInstanceEngine.โ€‹oracleSe1() | instances can no longer be created with this engine. See https://forums.aws.amazon.com/ann.jspa?annID=7341 | | @aws-cdk/aws-rds | DatabaseInstanceNewProps.โ€‹vpcPlacement | use `vpcSubnets` | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹0 | MariaDB 10.0 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹0_โ€‹17 | MariaDB 10.0 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹0_โ€‹24 | MariaDB 10.0 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹0_โ€‹28 | MariaDB 10.0 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹0_โ€‹31 | MariaDB 10.0 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹0_โ€‹32 | MariaDB 10.0 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹0_โ€‹34 | MariaDB 10.0 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹0_โ€‹35 | MariaDB 10.0 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹1 | MariaDB 10.1 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹1_โ€‹14 | MariaDB 10.1 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹1_โ€‹19 | MariaDB 10.1 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹1_โ€‹23 | MariaDB 10.1 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹1_โ€‹26 | MariaDB 10.1 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹1_โ€‹31 | MariaDB 10.1 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MariaDbEngineVersion.โ€‹VER_โ€‹10_โ€‹1_โ€‹34 | MariaDB 10.1 will reach end of life on May 18, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹5 | MySQL 5.5 will reach end of life on May 25, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹5_โ€‹46 | MySQL 5.5 will reach end of life on May 25, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹5_โ€‹53 | MySQL 5.5 will reach end of life on May 25, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹5_โ€‹57 | MySQL 5.5 will reach end of life on May 25, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹5_โ€‹59 | MySQL 5.5 will reach end of life on May 25, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹5_โ€‹61 | MySQL 5.5 will reach end of life on May 25, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹6 | MySQL 5.6 will reach end of life on August 3, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹6_โ€‹34 | MySQL 5.6 will reach end of life on August 3, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹6_โ€‹35 | MySQL 5.6 will reach end of life on August 3, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹6_โ€‹37 | MySQL 5.6 will reach end of life on August 3, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹6_โ€‹39 | MySQL 5.6 will reach end of life on August 3, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹6_โ€‹40 | MySQL 5.6 will reach end of life on August 3, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹6_โ€‹41 | MySQL 5.6 will reach end of life on August 3, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹6_โ€‹43 | MySQL 5.6 will reach end of life on August 3, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹6_โ€‹44 | MySQL 5.6 will reach end of life on August 3, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹6_โ€‹46 | MySQL 5.6 will reach end of life on August 3, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹6_โ€‹48 | MySQL 5.6 will reach end of life on August 3, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹6_โ€‹49 | MySQL 5.6 will reach end of life on August 3, 2021 | +| @aws-cdk/aws-rds | MysqlEngineVersion.โ€‹VER_โ€‹5_โ€‹6_โ€‹51 | MySQL 5.6 will reach end of life on August 3, 2021 | | @aws-cdk/aws-rds | OracleLegacyEngineVersion | instances can no longer be created with these engine versions. See https://forums.aws.amazon.com/ann.jspa?annID=7341 | | @aws-cdk/aws-rds | OracleLegacyEngineVersion.โ€‹VER_โ€‹11_โ€‹2 | instances can no longer be created with these engine versions. See https://forums.aws.amazon.com/ann.jspa?annID=7341 | | @aws-cdk/aws-rds | OracleLegacyEngineVersion.โ€‹VER_โ€‹11_โ€‹2_โ€‹0_โ€‹2_โ€‹V2 | instances can no longer be created with these engine versions. See https://forums.aws.amazon.com/ann.jspa?annID=7341 | @@ -641,6 +698,8 @@ | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹5_โ€‹21 | PostgreSQL 9.5 will reach end of life on February 16, 2021 | | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹5_โ€‹22 | PostgreSQL 9.5 will reach end of life on February 16, 2021 | | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹5_โ€‹23 | PostgreSQL 9.5 will reach end of life on February 16, 2021 | +| @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹5_โ€‹24 | PostgreSQL 9.5 will reach end of life on February 16, 2021 | +| @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹5_โ€‹25 | PostgreSQL 9.5 will reach end of life on February 16, 2021 | | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹5_โ€‹4 | PostgreSQL 9.5 will reach end of life on February 16, 2021 | | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹5_โ€‹6 | PostgreSQL 9.5 will reach end of life on February 16, 2021 | | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹5_โ€‹7 | PostgreSQL 9.5 will reach end of life on February 16, 2021 | @@ -657,12 +716,17 @@ | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹6_โ€‹18 | PostgreSQL 9.6 will reach end of life in November 2021 | | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹6_โ€‹19 | PostgreSQL 9.6 will reach end of life in November 2021 | | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹6_โ€‹2 | PostgreSQL 9.6 will reach end of life in November 2021 | +| @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹6_โ€‹20 | PostgreSQL 9.6 will reach end of life in November 2021 | +| @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹6_โ€‹21 | PostgreSQL 9.6 will reach end of life in November 2021 | +| @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹6_โ€‹22 | PostgreSQL 9.6 will reach end of life in November 2021 | +| @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹6_โ€‹23 | PostgreSQL 9.6 will reach end of life in November 2021 | | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹6_โ€‹3 | PostgreSQL 9.6 will reach end of life in November 2021 | | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹6_โ€‹5 | PostgreSQL 9.6 will reach end of life in November 2021 | | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹6_โ€‹6 | PostgreSQL 9.6 will reach end of life in November 2021 | | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹6_โ€‹8 | PostgreSQL 9.6 will reach end of life in November 2021 | | @aws-cdk/aws-rds | PostgresEngineVersion.โ€‹VER_โ€‹9_โ€‹6_โ€‹9 | PostgreSQL 9.6 will reach end of life in November 2021 | | @aws-cdk/aws-rds | SnapshotCredentials.โ€‹fromGeneratedPassword() | use `fromGeneratedSecret()` for new Clusters and Instances. Note that switching from `fromGeneratedPassword()` to `fromGeneratedSecret()` for already deployed Clusters or Instances will update their master password. | +| @aws-cdk/aws-rds | SqlServerEngineVersion.โ€‹VER_โ€‹15_โ€‹00_โ€‹4043_โ€‹23_โ€‹V1 | This version is erroneous. You might be looking for {@link SqlServerEngineVersion.VER_15_00_4073_23_V1}, instead. | | @aws-cdk/aws-autoscaling | BlockDevice.โ€‹mappingEnabled | use `BlockDeviceVolume.noDevice()` as the volume to supress a mapping. | | @aws-cdk/aws-autoscaling | CommonAutoScalingGroupProps.โ€‹notificationsTopic | use `notifications` | | @aws-cdk/aws-autoscaling | CommonAutoScalingGroupProps.โ€‹replacingUpdateMinSuccessfulInstancesPercent | Use `signals` instead | @@ -683,17 +747,23 @@ | @aws-cdk/aws-autoscaling | UpdateType.โ€‹REPLACING_โ€‹UPDATE | Use UpdatePolicy instead | | @aws-cdk/aws-autoscaling | UpdateType.โ€‹ROLLING_โ€‹UPDATE | Use UpdatePolicy instead | | @aws-cdk/aws-elasticloadbalancing | LoadBalancerListener.โ€‹sslCertificateId | use sslCertificateArn instead | +| @aws-cdk/aws-ecs | AddAutoScalingGroupCapacityOptions.โ€‹taskDrainTime | The lifecycle draining hook is not configured if using the EC2 Capacity Provider. Enable managed termination protection instead. | | @aws-cdk/aws-ecs | BaseService.โ€‹configureAwsVpcNetworking() | use configureAwsVpcNetworkingWithSecurityGroups instead. | -| @aws-cdk/aws-ecs | Ec2ServiceProps.โ€‹propagateTaskTagsFrom | Use `propagateTags` instead. | +| @aws-cdk/aws-ecs | BaseServiceOptions.โ€‹propagateTaskTagsFrom | Use `propagateTags` instead. | +| @aws-cdk/aws-ecs | Cluster.โ€‹addAutoScalingGroup() | Use {@link Cluster.addAsgCapacityProvider} instead. | +| @aws-cdk/aws-ecs | Cluster.โ€‹addCapacity() | Use {@link Cluster.addAsgCapacityProvider} instead. | +| @aws-cdk/aws-ecs | Cluster.โ€‹addCapacityProvider() | Use {@link enableFargateCapacityProviders} instead. | +| @aws-cdk/aws-ecs | ClusterProps.โ€‹capacityProviders | Use {@link ClusterProps.enableFargateCapacityProviders} instead. | | @aws-cdk/aws-ecs | Ec2ServiceProps.โ€‹securityGroup | use securityGroups instead. | | @aws-cdk/aws-ecs | EcsOptimizedAmi | see {@link EcsOptimizedImage#amazonLinux}, {@link EcsOptimizedImage#amazonLinux} and {@link EcsOptimizedImage#windows} | | @aws-cdk/aws-ecs | EcsOptimizedAmi.โ€‹getImage() | see {@link EcsOptimizedImage#amazonLinux}, {@link EcsOptimizedImage#amazonLinux} and {@link EcsOptimizedImage#windows} | | @aws-cdk/aws-ecs | EcsOptimizedAmiProps | see {@link EcsOptimizedImage} | +| @aws-cdk/aws-ecs | EcsOptimizedAmiProps.โ€‹cachedInContext | see {@link EcsOptimizedImage} | | @aws-cdk/aws-ecs | EcsOptimizedAmiProps.โ€‹generation | see {@link EcsOptimizedImage} | | @aws-cdk/aws-ecs | EcsOptimizedAmiProps.โ€‹hardwareType | see {@link EcsOptimizedImage} | | @aws-cdk/aws-ecs | EcsOptimizedAmiProps.โ€‹windowsVersion | see {@link EcsOptimizedImage} | -| @aws-cdk/aws-ecs | FargateServiceProps.โ€‹propagateTaskTagsFrom | Use `propagateTags` instead. | | @aws-cdk/aws-ecs | FargateServiceProps.โ€‹securityGroup | use securityGroups instead. | +| @aws-cdk/aws-ecs | SplunkLogDriverProps.โ€‹token | Use {@link SplunkLogDriverProps.secretToken} instead. | | @aws-cdk/aws-cloudfront | AliasConfiguration | see {@link CloudFrontWebDistributionProps#viewerCertificate} with {@link ViewerCertificate#acmCertificate} | | @aws-cdk/aws-cloudfront | AliasConfiguration.โ€‹acmCertRef | see {@link CloudFrontWebDistributionProps#viewerCertificate} with {@link ViewerCertificate#acmCertificate} | | @aws-cdk/aws-cloudfront | AliasConfiguration.โ€‹names | see {@link CloudFrontWebDistributionProps#viewerCertificate} with {@link ViewerCertificate#acmCertificate} | @@ -757,6 +827,8 @@ | @aws-cdk/aws-stepfunctions | Task.โ€‹next() | replaced by service integration specific classes (i.e. LambdaInvoke, SnsPublish) | | @aws-cdk/aws-stepfunctions | Task.โ€‹toStateJson() | replaced by service integration specific classes (i.e. LambdaInvoke, SnsPublish) | | @aws-cdk/aws-stepfunctions | Task.โ€‹whenBoundToGraph() | replaced by service integration specific classes (i.e. LambdaInvoke, SnsPublish) | +| @aws-cdk/aws-stepfunctions | TaskInput.โ€‹fromContextAt() | Use `fromJsonPathAt`. | +| @aws-cdk/aws-stepfunctions | TaskInput.โ€‹fromDataAt() | Use `fromJsonPathAt`. | | @aws-cdk/aws-stepfunctions | TaskProps | replaced by service integration specific classes (i.e. LambdaInvoke, SnsPublish) | | @aws-cdk/aws-stepfunctions | TaskProps.โ€‹task | replaced by service integration specific classes (i.e. LambdaInvoke, SnsPublish) | | @aws-cdk/aws-stepfunctions | TaskProps.โ€‹comment | replaced by service integration specific classes (i.e. LambdaInvoke, SnsPublish) | @@ -861,5 +933,193 @@ | @aws-cdk/aws-stepfunctions-tasks | StartExecutionProps.โ€‹input | use 'StepFunctionsStartExecution' | | @aws-cdk/aws-stepfunctions-tasks | StartExecutionProps.โ€‹integrationPattern | use 'StepFunctionsStartExecution' | | @aws-cdk/aws-stepfunctions-tasks | StartExecutionProps.โ€‹name | use 'StepFunctionsStartExecution' | +| @aws-cdk/pipelines | AddManualApprovalOptions | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AddManualApprovalOptions.โ€‹actionName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AddManualApprovalOptions.โ€‹runOrder | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AddStackOptions | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AddStackOptions.โ€‹executeRunOrder | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AddStackOptions.โ€‹runOrder | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AddStageOptions | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AddStageOptions.โ€‹extraRunOrderSpace | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AddStageOptions.โ€‹manualApprovals | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AdditionalArtifact | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AdditionalArtifact.โ€‹artifact | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AdditionalArtifact.โ€‹directory | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AssetPublishingCommand | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AssetPublishingCommand.โ€‹assetId | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AssetPublishingCommand.โ€‹assetManifestPath | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AssetPublishingCommand.โ€‹assetPublishingRoleArn | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AssetPublishingCommand.โ€‹assetSelector | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | AssetPublishingCommand.โ€‹assetType | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | BaseStageOptions | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | BaseStageOptions.โ€‹confirmBroadeningPermissions | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | BaseStageOptions.โ€‹securityNotificationTopic | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipeline | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipeline.โ€‹codePipeline | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipeline.โ€‹addApplicationStage() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipeline.โ€‹addStage() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipeline.โ€‹stackOutput() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipeline.โ€‹stage() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipeline.โ€‹validate() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹cloudAssemblyArtifact | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹assetBuildSpec | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹assetPreInstallCommands | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹cdkCliVersion | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹codePipeline | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹crossAccountKeys | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹dockerCredentials | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹enableKeyRotation | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹pipelineName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹selfMutating | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹selfMutationBuildSpec | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹singlePublisherPerType | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹sourceAction | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹subnetSelection | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹supportDockerAssets | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹synthAction | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkPipelineProps.โ€‹vpc | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStackActionFromArtifactOptions | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStackActionFromArtifactOptions.โ€‹stackName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStage | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStage.โ€‹addActions() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStage.โ€‹addApplication() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStage.โ€‹addManualApprovalAction() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStage.โ€‹addStackArtifactDeployment() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStage.โ€‹deploysStack() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStage.โ€‹nextSequentialRunOrder() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStageProps | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStageProps.โ€‹cloudAssemblyArtifact | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStageProps.โ€‹host | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStageProps.โ€‹pipelineStage | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStageProps.โ€‹stageName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStageProps.โ€‹confirmBroadeningPermissions | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | CdkStageProps.โ€‹securityNotificationTopic | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackAction | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackAction.โ€‹actionProperties | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackAction.โ€‹dependencyStackArtifactIds | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackAction.โ€‹executeRunOrder | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackAction.โ€‹prepareRunOrder | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackAction.โ€‹stackName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackAction.โ€‹stackArtifactId | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackAction.โ€‹fromStackArtifact() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackAction.โ€‹bind() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackAction.โ€‹onStateChange() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionOptions | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionOptions.โ€‹cloudAssemblyInput | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionOptions.โ€‹baseActionName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionOptions.โ€‹changeSetName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionOptions.โ€‹executeRunOrder | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionOptions.โ€‹output | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionOptions.โ€‹outputFileName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionOptions.โ€‹prepareRunOrder | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionProps | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionProps.โ€‹actionRole | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionProps.โ€‹stackName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionProps.โ€‹templatePath | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionProps.โ€‹cloudFormationExecutionRole | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionProps.โ€‹dependencyStackArtifactIds | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionProps.โ€‹region | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionProps.โ€‹stackArtifactId | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | DeployCdkStackActionProps.โ€‹templateConfigurationPath | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | FromStackArtifactOptions | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | FromStackArtifactOptions.โ€‹cloudAssemblyInput | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | FromStackArtifactOptions.โ€‹executeRunOrder | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | FromStackArtifactOptions.โ€‹output | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | FromStackArtifactOptions.โ€‹outputFileName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | FromStackArtifactOptions.โ€‹prepareRunOrder | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | IStageHost | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | IStageHost.โ€‹publishAsset() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | IStageHost.โ€‹stackOutputArtifact() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsAction | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsAction.โ€‹actionProperties | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsAction.โ€‹addPublishCommand() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsAction.โ€‹bind() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsAction.โ€‹onStateChange() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsActionProps | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsActionProps.โ€‹actionName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsActionProps.โ€‹assetType | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsActionProps.โ€‹cloudAssemblyInput | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsActionProps.โ€‹buildSpec | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsActionProps.โ€‹cdkCliVersion | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsActionProps.โ€‹createBuildspecFile | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsActionProps.โ€‹dependable | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsActionProps.โ€‹preInstallCommands | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsActionProps.โ€‹projectName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsActionProps.โ€‹role | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsActionProps.โ€‹subnetSelection | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | PublishAssetsActionProps.โ€‹vpc | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptAction | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptAction.โ€‹actionProperties | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptAction.โ€‹grantPrincipal | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptAction.โ€‹project | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptAction.โ€‹bind() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptAction.โ€‹onStateChange() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptActionProps | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptActionProps.โ€‹actionName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptActionProps.โ€‹commands | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptActionProps.โ€‹additionalArtifacts | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptActionProps.โ€‹bashOptions | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptActionProps.โ€‹environment | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptActionProps.โ€‹environmentVariables | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptActionProps.โ€‹rolePolicyStatements | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptActionProps.โ€‹runOrder | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptActionProps.โ€‹securityGroups | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptActionProps.โ€‹subnetSelection | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptActionProps.โ€‹useOutputs | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | ShellScriptActionProps.โ€‹vpc | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthAction | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthAction.โ€‹actionProperties | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthAction.โ€‹grantPrincipal | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthAction.โ€‹project | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthAction.โ€‹standardNpmSynth() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthAction.โ€‹standardYarnSynth() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthAction.โ€‹bind() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthAction.โ€‹onStateChange() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthActionProps | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthActionProps.โ€‹synthCommand | This class is part of the old API. Use the API based on the `CodePipeline` class instead | | @aws-cdk/pipelines | SimpleSynthActionProps.โ€‹buildCommand | Use `buildCommands` instead | +| @aws-cdk/pipelines | SimpleSynthActionProps.โ€‹buildCommands | This class is part of the old API. Use the API based on the `CodePipeline` class instead | | @aws-cdk/pipelines | SimpleSynthActionProps.โ€‹installCommand | Use `installCommands` instead | +| @aws-cdk/pipelines | SimpleSynthActionProps.โ€‹installCommands | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthActionProps.โ€‹testCommands | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions.โ€‹cloudAssemblyArtifact | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions.โ€‹sourceArtifact | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions.โ€‹actionName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions.โ€‹additionalArtifacts | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions.โ€‹buildSpec | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions.โ€‹copyEnvironmentVariables | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions.โ€‹environment | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions.โ€‹environmentVariables | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions.โ€‹projectName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions.โ€‹rolePolicyStatements | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions.โ€‹subdirectory | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions.โ€‹subnetSelection | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | SimpleSynthOptions.โ€‹vpc | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | StackOutput | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | StackOutput.โ€‹artifactFile | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | StackOutput.โ€‹outputName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | StandardNpmSynthOptions | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | StandardNpmSynthOptions.โ€‹buildCommand | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | StandardNpmSynthOptions.โ€‹installCommand | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | StandardNpmSynthOptions.โ€‹synthCommand | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | StandardNpmSynthOptions.โ€‹testCommands | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | StandardYarnSynthOptions | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | StandardYarnSynthOptions.โ€‹buildCommand | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | StandardYarnSynthOptions.โ€‹installCommand | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | StandardYarnSynthOptions.โ€‹synthCommand | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | StandardYarnSynthOptions.โ€‹testCommands | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | UpdatePipelineAction | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | UpdatePipelineAction.โ€‹actionProperties | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | UpdatePipelineAction.โ€‹bind() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | UpdatePipelineAction.โ€‹onStateChange() | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | UpdatePipelineActionProps | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | UpdatePipelineActionProps.โ€‹cloudAssemblyInput | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | UpdatePipelineActionProps.โ€‹pipelineStackHierarchicalId | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | UpdatePipelineActionProps.โ€‹buildSpec | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | UpdatePipelineActionProps.โ€‹cdkCliVersion | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | UpdatePipelineActionProps.โ€‹dockerCredentials | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | UpdatePipelineActionProps.โ€‹pipelineStackName | Use `pipelineStackHierarchicalId` instead. | +| @aws-cdk/pipelines | UpdatePipelineActionProps.โ€‹privileged | This class is part of the old API. Use the API based on the `CodePipeline` class instead | +| @aws-cdk/pipelines | UpdatePipelineActionProps.โ€‹projectName | This class is part of the old API. Use the API based on the `CodePipeline` class instead | diff --git a/deprecated_apis.txt b/deprecated_apis.txt new file mode 100644 index 0000000000000..cfda6c5068605 --- /dev/null +++ b/deprecated_apis.txt @@ -0,0 +1,1121 @@ +@aws-cdk/core.AppProps#runtimeInfo +@aws-cdk/core.Arn#parse +@aws-cdk/core.ArnComponents#sep +@aws-cdk/core.AssetHashType#BUNDLE +@aws-cdk/core.AssetStaging#sourceHash +@aws-cdk/core.AssetStaging#stagedPath +@aws-cdk/core.BundlingDockerImage +@aws-cdk/core.BundlingDockerImage#image +@aws-cdk/core.BundlingDockerImage#fromAsset +@aws-cdk/core.BundlingDockerImage#fromRegistry +@aws-cdk/core.BundlingDockerImage#cp +@aws-cdk/core.BundlingDockerImage#run +@aws-cdk/core.BundlingDockerImage#toJSON +@aws-cdk/core.CfnInclude +@aws-cdk/core.CfnInclude#template +@aws-cdk/core.CfnIncludeProps +@aws-cdk/core.CfnIncludeProps#template +@aws-cdk/core.ConstructNode#metadata +@aws-cdk/core.ConstructNode#uniqueId +@aws-cdk/core.ConstructNode#prepare +@aws-cdk/core.ConstructNode#synth +@aws-cdk/core.ConstructNode#addError +@aws-cdk/core.ConstructNode#addInfo +@aws-cdk/core.ConstructNode#addWarning +@aws-cdk/core.ConstructNode#applyAspect +@aws-cdk/core.CustomResourceProviderRuntime#NODEJS_12 +@aws-cdk/core.DefaultStackSynthesizerProps#fileAssetKeyArnExportName +@aws-cdk/core.DockerImageAssetSource#repositoryName +@aws-cdk/core.Duration#toISOString +@aws-cdk/core.FileAssetLocation#kmsKeyArn +@aws-cdk/core.FileAssetLocation#s3Url +@aws-cdk/core.ITemplateOptions#transform +@aws-cdk/core.Lazy#anyValue +@aws-cdk/core.Lazy#listValue +@aws-cdk/core.Lazy#numberValue +@aws-cdk/core.Lazy#stringValue +@aws-cdk/core.Size#pebibyte +@aws-cdk/core.Stack#parentStack +@aws-cdk/core.Stack#addDockerImageAsset +@aws-cdk/core.Stack#addFileAsset +@aws-cdk/core.Stack#parseArn +@aws-cdk/core.Stack#prepareCrossReference +@aws-cdk/core.Stack#reportMissingContext +@aws-cdk/core.SynthesisOptions +@aws-cdk/core.SynthesisOptions#outdir +@aws-cdk/core.SynthesisOptions#skipValidation +@aws-cdk/core.SynthesisOptions#validateOnSynthesis +@aws-cdk/core.Tag#add +@aws-cdk/core.Tag#remove +@aws-cdk/cloud-assembly-schema.ContainerImageAssetMetadataEntry#imageNameParameter +@aws-cdk/cloud-assembly-schema.Manifest#load +@aws-cdk/cloud-assembly-schema.Manifest#save +@aws-cdk/cx-api.AssemblyBuildOptions#runtimeInfo +@aws-cdk/cx-api.CloudAssembly#getStack +@aws-cdk/cx-api.CloudFormationStackArtifact#name +@aws-cdk/cx-api.MetadataEntry +@aws-cdk/cx-api.MissingContext +@aws-cdk/cx-api.MissingContext#key +@aws-cdk/cx-api.MissingContext#props +@aws-cdk/cx-api.MissingContext#provider +@aws-cdk/cx-api.RuntimeInfo +constructs.Construct#onValidate +constructs.Node#uniqueId +@aws-cdk/assets.CopyOptions +@aws-cdk/assets.CopyOptions#exclude +@aws-cdk/assets.CopyOptions#follow +@aws-cdk/assets.CopyOptions#ignoreMode +@aws-cdk/assets.FingerprintOptions +@aws-cdk/assets.FingerprintOptions#extraHash +@aws-cdk/assets.FollowMode +@aws-cdk/assets.FollowMode#NEVER +@aws-cdk/assets.FollowMode#ALWAYS +@aws-cdk/assets.FollowMode#EXTERNAL +@aws-cdk/assets.FollowMode#BLOCK_EXTERNAL +@aws-cdk/assets.IAsset +@aws-cdk/assets.IAsset#sourceHash +@aws-cdk/assets.Staging +@aws-cdk/assets.StagingProps +@aws-cdk/assets.StagingProps#sourcePath +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_ANDROID_JAVA8_24_4_1 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_ANDROID_JAVA8_26_1_1 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_BASE +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_DOCKER_17_09_0 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_DOCKER_18_09_0 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_DOTNET_CORE_1_1 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_DOTNET_CORE_2_0 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_DOTNET_CORE_2_1 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_GOLANG_1_10 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_GOLANG_1_11 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_NODEJS_10_1_0 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_NODEJS_10_14_1 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_NODEJS_6_3_1 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_NODEJS_8_11_0 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_OPEN_JDK_11 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_OPEN_JDK_8 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_OPEN_JDK_9 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_PHP_5_6 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_PHP_7_0 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_PHP_7_1 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_PYTHON_2_7_12 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_PYTHON_3_3_6 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_PYTHON_3_4_5 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_PYTHON_3_5_2 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_PYTHON_3_6_5 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_PYTHON_3_7_1 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_RUBY_2_2_5 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_RUBY_2_3_1 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_RUBY_2_5_1 +@aws-cdk/aws-codebuild.LinuxBuildImage#UBUNTU_14_04_RUBY_2_5_3 +@aws-cdk/aws-codebuild.WindowsBuildImage#WIN_SERVER_CORE_2016_BASE +@aws-cdk/aws-cloudwatch.CommonMetricOptions#dimensions +@aws-cdk/aws-cloudwatch.CreateAlarmOptions#period +@aws-cdk/aws-cloudwatch.CreateAlarmOptions#statistic +@aws-cdk/aws-cloudwatch.IMetric#toAlarmConfig +@aws-cdk/aws-cloudwatch.IMetric#toGraphConfig +@aws-cdk/aws-cloudwatch.MathExpression#toAlarmConfig +@aws-cdk/aws-cloudwatch.MathExpression#toGraphConfig +@aws-cdk/aws-cloudwatch.Metric#toAlarmConfig +@aws-cdk/aws-cloudwatch.Metric#toGraphConfig +@aws-cdk/aws-cloudwatch.MetricAlarmConfig +@aws-cdk/aws-cloudwatch.MetricAlarmConfig#metricName +@aws-cdk/aws-cloudwatch.MetricAlarmConfig#namespace +@aws-cdk/aws-cloudwatch.MetricAlarmConfig#period +@aws-cdk/aws-cloudwatch.MetricAlarmConfig#dimensions +@aws-cdk/aws-cloudwatch.MetricAlarmConfig#extendedStatistic +@aws-cdk/aws-cloudwatch.MetricAlarmConfig#statistic +@aws-cdk/aws-cloudwatch.MetricAlarmConfig#unit +@aws-cdk/aws-cloudwatch.MetricGraphConfig +@aws-cdk/aws-cloudwatch.MetricGraphConfig#metricName +@aws-cdk/aws-cloudwatch.MetricGraphConfig#namespace +@aws-cdk/aws-cloudwatch.MetricGraphConfig#period +@aws-cdk/aws-cloudwatch.MetricGraphConfig#renderingProperties +@aws-cdk/aws-cloudwatch.MetricGraphConfig#color +@aws-cdk/aws-cloudwatch.MetricGraphConfig#dimensions +@aws-cdk/aws-cloudwatch.MetricGraphConfig#label +@aws-cdk/aws-cloudwatch.MetricGraphConfig#statistic +@aws-cdk/aws-cloudwatch.MetricGraphConfig#unit +@aws-cdk/aws-cloudwatch.MetricRenderingProperties +@aws-cdk/aws-cloudwatch.MetricRenderingProperties#period +@aws-cdk/aws-cloudwatch.MetricRenderingProperties#color +@aws-cdk/aws-cloudwatch.MetricRenderingProperties#label +@aws-cdk/aws-cloudwatch.MetricRenderingProperties#stat +@aws-cdk/aws-iam.Anyone +@aws-cdk/aws-iam.IPrincipal#addToPolicy +@aws-cdk/aws-iam.RoleProps#externalId +@aws-cdk/aws-events.EventBus#grantPutEvents +@aws-cdk/aws-events.RuleTargetConfig#id +@aws-cdk/aws-ec2.ClientVpnAuthorizationRuleProps#clientVpnEndoint +@aws-cdk/aws-ec2.ClientVpnRouteProps#clientVpnEndoint +@aws-cdk/aws-ec2.InterfaceVpcEndpoint#securityGroupId +@aws-cdk/aws-ec2.InterfaceVpcEndpointAttributes#securityGroupId +@aws-cdk/aws-ec2.MachineImage#fromSSMParameter +@aws-cdk/aws-ec2.NatInstanceProps#allowAllTraffic +@aws-cdk/aws-ec2.SecurityGroup#securityGroupName +@aws-cdk/aws-ec2.SubnetSelection#subnetName +@aws-cdk/aws-ec2.SubnetType#ISOLATED +@aws-cdk/aws-ec2.SubnetType#PRIVATE +@aws-cdk/aws-ec2.Vpc#natDependencies +@aws-cdk/aws-ec2.Vpc#addDynamoDbEndpoint +@aws-cdk/aws-ec2.Vpc#addS3Endpoint +@aws-cdk/aws-ec2.VpcEndpointService#whitelistedPrincipals +@aws-cdk/aws-ec2.VpcEndpointServiceProps#vpcEndpointServiceName +@aws-cdk/aws-ec2.VpcEndpointServiceProps#whitelistedPrincipals +@aws-cdk/aws-ec2.WindowsVersion#WINDOWS_SERVER_2016_GERMAL_FULL_BASE +@aws-cdk/aws-ec2.WindowsVersion#WINDOWS_SERVER_2012_R2_SP1_PORTUGESE_BRAZIL_64BIT_CORE +@aws-cdk/aws-ec2.WindowsVersion#WINDOWS_SERVER_2016_PORTUGESE_PORTUGAL_FULL_BASE +@aws-cdk/aws-ec2.WindowsVersion#WINDOWS_SERVER_2012_R2_RTM_PORTUGESE_BRAZIL_64BIT_BASE +@aws-cdk/aws-ec2.WindowsVersion#WINDOWS_SERVER_2012_R2_RTM_PORTUGESE_PORTUGAL_64BIT_BASE +@aws-cdk/aws-ec2.WindowsVersion#WINDOWS_SERVER_2016_PORTUGESE_BRAZIL_FULL_BASE +@aws-cdk/aws-ec2.WindowsVersion#WINDOWS_SERVER_2012_SP2_PORTUGESE_BRAZIL_64BIT_BASE +@aws-cdk/aws-ec2.WindowsVersion#WINDOWS_SERVER_2012_RTM_PORTUGESE_BRAZIL_64BIT_BASE +@aws-cdk/aws-ec2.WindowsVersion#WINDOWS_SERVER_2008_R2_SP1_PORTUGESE_BRAZIL_64BIT_BASE +@aws-cdk/aws-ec2.WindowsVersion#WINDOWS_SERVER_2008_SP2_PORTUGESE_BRAZIL_32BIT_BASE +@aws-cdk/aws-ec2.WindowsVersion#WINDOWS_SERVER_2012_RTM_PORTUGESE_PORTUGAL_64BIT_BASE +@aws-cdk/aws-ec2.WindowsVersion#WINDOWS_SERVER_2019_PORTUGESE_BRAZIL_FULL_BASE +@aws-cdk/aws-ec2.WindowsVersion#WINDOWS_SERVER_2019_PORTUGESE_PORTUGAL_FULL_BASE +@aws-cdk/aws-kms.KeyProps#trustAccountIdentities +@aws-cdk/aws-s3-assets.Asset#s3Url +@aws-cdk/aws-s3-assets.Asset#sourceHash +@aws-cdk/aws-s3-assets.AssetOptions#sourceHash +@aws-cdk/aws-ecr-assets.DockerImageAsset#sourceHash +@aws-cdk/aws-ecr-assets.DockerImageAssetOptions#repositoryName +@aws-cdk/aws-ecr-assets.TarballImageAsset#sourceHash +@aws-cdk/aws-secretsmanager.AttachedSecretOptions +@aws-cdk/aws-secretsmanager.AttachedSecretOptions#target +@aws-cdk/aws-secretsmanager.AttachmentTargetType#INSTANCE +@aws-cdk/aws-secretsmanager.AttachmentTargetType#CLUSTER +@aws-cdk/aws-secretsmanager.Secret#fromSecretArn +@aws-cdk/aws-secretsmanager.Secret#fromSecretName +@aws-cdk/aws-secretsmanager.Secret#addTargetAttachment +@aws-cdk/aws-secretsmanager.SecretAttributes#secretArn +@aws-cdk/aws-secretsmanager.SecretRotationApplication#applicationId +@aws-cdk/aws-secretsmanager.SecretRotationApplication#semanticVersion +@aws-cdk/aws-lambda.Code#isInline +@aws-cdk/aws-lambda.Code#asset +@aws-cdk/aws-lambda.Code#bucket +@aws-cdk/aws-lambda.Code#cfnParameters +@aws-cdk/aws-lambda.Code#inline +@aws-cdk/aws-lambda.Function#addVersion +@aws-cdk/aws-lambda.FunctionAttributes#securityGroupId +@aws-cdk/aws-lambda.FunctionOptions#architectures +@aws-cdk/aws-lambda.FunctionOptions#securityGroup +@aws-cdk/aws-lambda.LogRetention +@aws-cdk/aws-lambda.LogRetentionProps +@aws-cdk/aws-lambda.Runtime#bundlingDockerImage +@aws-cdk/aws-apigateway.CfnApiMappingV2 +@aws-cdk/aws-apigateway.CfnApiMappingV2#CFN_RESOURCE_TYPE_NAME +@aws-cdk/aws-apigateway.CfnApiMappingV2#cfnProperties +@aws-cdk/aws-apigateway.CfnApiMappingV2#apiId +@aws-cdk/aws-apigateway.CfnApiMappingV2#domainName +@aws-cdk/aws-apigateway.CfnApiMappingV2#stage +@aws-cdk/aws-apigateway.CfnApiMappingV2#apiMappingKey +@aws-cdk/aws-apigateway.CfnApiMappingV2#inspect +@aws-cdk/aws-apigateway.CfnApiMappingV2#renderProperties +@aws-cdk/aws-apigateway.CfnApiMappingV2Props +@aws-cdk/aws-apigateway.CfnApiMappingV2Props#apiId +@aws-cdk/aws-apigateway.CfnApiMappingV2Props#domainName +@aws-cdk/aws-apigateway.CfnApiMappingV2Props#stage +@aws-cdk/aws-apigateway.CfnApiMappingV2Props#apiMappingKey +@aws-cdk/aws-apigateway.CfnApiV2 +@aws-cdk/aws-apigateway.CfnApiV2#CFN_RESOURCE_TYPE_NAME +@aws-cdk/aws-apigateway.CfnApiV2#cfnProperties +@aws-cdk/aws-apigateway.CfnApiV2#tags +@aws-cdk/aws-apigateway.CfnApiV2#body +@aws-cdk/aws-apigateway.CfnApiV2#apiKeySelectionExpression +@aws-cdk/aws-apigateway.CfnApiV2#basePath +@aws-cdk/aws-apigateway.CfnApiV2#bodyS3Location +@aws-cdk/aws-apigateway.CfnApiV2#corsConfiguration +@aws-cdk/aws-apigateway.CfnApiV2#credentialsArn +@aws-cdk/aws-apigateway.CfnApiV2#description +@aws-cdk/aws-apigateway.CfnApiV2#disableSchemaValidation +@aws-cdk/aws-apigateway.CfnApiV2#failOnWarnings +@aws-cdk/aws-apigateway.CfnApiV2#name +@aws-cdk/aws-apigateway.CfnApiV2#protocolType +@aws-cdk/aws-apigateway.CfnApiV2#routeKey +@aws-cdk/aws-apigateway.CfnApiV2#routeSelectionExpression +@aws-cdk/aws-apigateway.CfnApiV2#target +@aws-cdk/aws-apigateway.CfnApiV2#version +@aws-cdk/aws-apigateway.CfnApiV2#inspect +@aws-cdk/aws-apigateway.CfnApiV2#renderProperties +@aws-cdk/aws-apigateway.BodyS3LocationProperty +@aws-cdk/aws-apigateway.BodyS3LocationProperty#bucket +@aws-cdk/aws-apigateway.BodyS3LocationProperty#etag +@aws-cdk/aws-apigateway.BodyS3LocationProperty#key +@aws-cdk/aws-apigateway.BodyS3LocationProperty#version +@aws-cdk/aws-apigateway.CorsProperty +@aws-cdk/aws-apigateway.CorsProperty#allowCredentials +@aws-cdk/aws-apigateway.CorsProperty#allowHeaders +@aws-cdk/aws-apigateway.CorsProperty#allowMethods +@aws-cdk/aws-apigateway.CorsProperty#allowOrigins +@aws-cdk/aws-apigateway.CorsProperty#exposeHeaders +@aws-cdk/aws-apigateway.CorsProperty#maxAge +@aws-cdk/aws-apigateway.CfnApiV2Props +@aws-cdk/aws-apigateway.CfnApiV2Props#apiKeySelectionExpression +@aws-cdk/aws-apigateway.CfnApiV2Props#basePath +@aws-cdk/aws-apigateway.CfnApiV2Props#body +@aws-cdk/aws-apigateway.CfnApiV2Props#bodyS3Location +@aws-cdk/aws-apigateway.CfnApiV2Props#corsConfiguration +@aws-cdk/aws-apigateway.CfnApiV2Props#credentialsArn +@aws-cdk/aws-apigateway.CfnApiV2Props#description +@aws-cdk/aws-apigateway.CfnApiV2Props#disableSchemaValidation +@aws-cdk/aws-apigateway.CfnApiV2Props#failOnWarnings +@aws-cdk/aws-apigateway.CfnApiV2Props#name +@aws-cdk/aws-apigateway.CfnApiV2Props#protocolType +@aws-cdk/aws-apigateway.CfnApiV2Props#routeKey +@aws-cdk/aws-apigateway.CfnApiV2Props#routeSelectionExpression +@aws-cdk/aws-apigateway.CfnApiV2Props#tags +@aws-cdk/aws-apigateway.CfnApiV2Props#target +@aws-cdk/aws-apigateway.CfnApiV2Props#version +@aws-cdk/aws-apigateway.CfnAuthorizerV2 +@aws-cdk/aws-apigateway.CfnAuthorizerV2#CFN_RESOURCE_TYPE_NAME +@aws-cdk/aws-apigateway.CfnAuthorizerV2#cfnProperties +@aws-cdk/aws-apigateway.CfnAuthorizerV2#apiId +@aws-cdk/aws-apigateway.CfnAuthorizerV2#authorizerType +@aws-cdk/aws-apigateway.CfnAuthorizerV2#identitySource +@aws-cdk/aws-apigateway.CfnAuthorizerV2#name +@aws-cdk/aws-apigateway.CfnAuthorizerV2#authorizerCredentialsArn +@aws-cdk/aws-apigateway.CfnAuthorizerV2#authorizerResultTtlInSeconds +@aws-cdk/aws-apigateway.CfnAuthorizerV2#authorizerUri +@aws-cdk/aws-apigateway.CfnAuthorizerV2#identityValidationExpression +@aws-cdk/aws-apigateway.CfnAuthorizerV2#jwtConfiguration +@aws-cdk/aws-apigateway.CfnAuthorizerV2#inspect +@aws-cdk/aws-apigateway.CfnAuthorizerV2#renderProperties +@aws-cdk/aws-apigateway.JWTConfigurationProperty +@aws-cdk/aws-apigateway.JWTConfigurationProperty#audience +@aws-cdk/aws-apigateway.JWTConfigurationProperty#issuer +@aws-cdk/aws-apigateway.CfnAuthorizerV2Props +@aws-cdk/aws-apigateway.CfnAuthorizerV2Props#apiId +@aws-cdk/aws-apigateway.CfnAuthorizerV2Props#authorizerType +@aws-cdk/aws-apigateway.CfnAuthorizerV2Props#identitySource +@aws-cdk/aws-apigateway.CfnAuthorizerV2Props#name +@aws-cdk/aws-apigateway.CfnAuthorizerV2Props#authorizerCredentialsArn +@aws-cdk/aws-apigateway.CfnAuthorizerV2Props#authorizerResultTtlInSeconds +@aws-cdk/aws-apigateway.CfnAuthorizerV2Props#authorizerUri +@aws-cdk/aws-apigateway.CfnAuthorizerV2Props#identityValidationExpression +@aws-cdk/aws-apigateway.CfnAuthorizerV2Props#jwtConfiguration +@aws-cdk/aws-apigateway.CfnDeploymentV2 +@aws-cdk/aws-apigateway.CfnDeploymentV2#CFN_RESOURCE_TYPE_NAME +@aws-cdk/aws-apigateway.CfnDeploymentV2#cfnProperties +@aws-cdk/aws-apigateway.CfnDeploymentV2#apiId +@aws-cdk/aws-apigateway.CfnDeploymentV2#description +@aws-cdk/aws-apigateway.CfnDeploymentV2#stageName +@aws-cdk/aws-apigateway.CfnDeploymentV2#inspect +@aws-cdk/aws-apigateway.CfnDeploymentV2#renderProperties +@aws-cdk/aws-apigateway.CfnDeploymentV2Props +@aws-cdk/aws-apigateway.CfnDeploymentV2Props#apiId +@aws-cdk/aws-apigateway.CfnDeploymentV2Props#description +@aws-cdk/aws-apigateway.CfnDeploymentV2Props#stageName +@aws-cdk/aws-apigateway.CfnDomainNameV2 +@aws-cdk/aws-apigateway.CfnDomainNameV2#CFN_RESOURCE_TYPE_NAME +@aws-cdk/aws-apigateway.CfnDomainNameV2#attrRegionalDomainName +@aws-cdk/aws-apigateway.CfnDomainNameV2#attrRegionalHostedZoneId +@aws-cdk/aws-apigateway.CfnDomainNameV2#cfnProperties +@aws-cdk/aws-apigateway.CfnDomainNameV2#tags +@aws-cdk/aws-apigateway.CfnDomainNameV2#domainName +@aws-cdk/aws-apigateway.CfnDomainNameV2#domainNameConfigurations +@aws-cdk/aws-apigateway.CfnDomainNameV2#inspect +@aws-cdk/aws-apigateway.CfnDomainNameV2#renderProperties +@aws-cdk/aws-apigateway.DomainNameConfigurationProperty +@aws-cdk/aws-apigateway.DomainNameConfigurationProperty#certificateArn +@aws-cdk/aws-apigateway.DomainNameConfigurationProperty#certificateName +@aws-cdk/aws-apigateway.DomainNameConfigurationProperty#endpointType +@aws-cdk/aws-apigateway.CfnDomainNameV2Props +@aws-cdk/aws-apigateway.CfnDomainNameV2Props#domainName +@aws-cdk/aws-apigateway.CfnDomainNameV2Props#domainNameConfigurations +@aws-cdk/aws-apigateway.CfnDomainNameV2Props#tags +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2 +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2#CFN_RESOURCE_TYPE_NAME +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2#cfnProperties +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2#apiId +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2#integrationId +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2#integrationResponseKey +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2#responseParameters +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2#responseTemplates +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2#contentHandlingStrategy +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2#templateSelectionExpression +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2#inspect +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2#renderProperties +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2Props +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2Props#apiId +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2Props#integrationId +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2Props#integrationResponseKey +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2Props#contentHandlingStrategy +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2Props#responseParameters +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2Props#responseTemplates +@aws-cdk/aws-apigateway.CfnIntegrationResponseV2Props#templateSelectionExpression +@aws-cdk/aws-apigateway.CfnIntegrationV2 +@aws-cdk/aws-apigateway.CfnIntegrationV2#CFN_RESOURCE_TYPE_NAME +@aws-cdk/aws-apigateway.CfnIntegrationV2#cfnProperties +@aws-cdk/aws-apigateway.CfnIntegrationV2#apiId +@aws-cdk/aws-apigateway.CfnIntegrationV2#integrationType +@aws-cdk/aws-apigateway.CfnIntegrationV2#requestParameters +@aws-cdk/aws-apigateway.CfnIntegrationV2#requestTemplates +@aws-cdk/aws-apigateway.CfnIntegrationV2#connectionType +@aws-cdk/aws-apigateway.CfnIntegrationV2#contentHandlingStrategy +@aws-cdk/aws-apigateway.CfnIntegrationV2#credentialsArn +@aws-cdk/aws-apigateway.CfnIntegrationV2#description +@aws-cdk/aws-apigateway.CfnIntegrationV2#integrationMethod +@aws-cdk/aws-apigateway.CfnIntegrationV2#integrationUri +@aws-cdk/aws-apigateway.CfnIntegrationV2#passthroughBehavior +@aws-cdk/aws-apigateway.CfnIntegrationV2#payloadFormatVersion +@aws-cdk/aws-apigateway.CfnIntegrationV2#templateSelectionExpression +@aws-cdk/aws-apigateway.CfnIntegrationV2#timeoutInMillis +@aws-cdk/aws-apigateway.CfnIntegrationV2#inspect +@aws-cdk/aws-apigateway.CfnIntegrationV2#renderProperties +@aws-cdk/aws-apigateway.CfnIntegrationV2Props +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#apiId +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#integrationType +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#connectionType +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#contentHandlingStrategy +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#credentialsArn +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#description +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#integrationMethod +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#integrationUri +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#passthroughBehavior +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#payloadFormatVersion +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#requestParameters +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#requestTemplates +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#templateSelectionExpression +@aws-cdk/aws-apigateway.CfnIntegrationV2Props#timeoutInMillis +@aws-cdk/aws-apigateway.CfnModelV2 +@aws-cdk/aws-apigateway.CfnModelV2#CFN_RESOURCE_TYPE_NAME +@aws-cdk/aws-apigateway.CfnModelV2#cfnProperties +@aws-cdk/aws-apigateway.CfnModelV2#apiId +@aws-cdk/aws-apigateway.CfnModelV2#name +@aws-cdk/aws-apigateway.CfnModelV2#schema +@aws-cdk/aws-apigateway.CfnModelV2#contentType +@aws-cdk/aws-apigateway.CfnModelV2#description +@aws-cdk/aws-apigateway.CfnModelV2#inspect +@aws-cdk/aws-apigateway.CfnModelV2#renderProperties +@aws-cdk/aws-apigateway.CfnModelV2Props +@aws-cdk/aws-apigateway.CfnModelV2Props#apiId +@aws-cdk/aws-apigateway.CfnModelV2Props#name +@aws-cdk/aws-apigateway.CfnModelV2Props#schema +@aws-cdk/aws-apigateway.CfnModelV2Props#contentType +@aws-cdk/aws-apigateway.CfnModelV2Props#description +@aws-cdk/aws-apigateway.CfnRouteResponseV2 +@aws-cdk/aws-apigateway.CfnRouteResponseV2#CFN_RESOURCE_TYPE_NAME +@aws-cdk/aws-apigateway.CfnRouteResponseV2#cfnProperties +@aws-cdk/aws-apigateway.CfnRouteResponseV2#apiId +@aws-cdk/aws-apigateway.CfnRouteResponseV2#responseModels +@aws-cdk/aws-apigateway.CfnRouteResponseV2#responseParameters +@aws-cdk/aws-apigateway.CfnRouteResponseV2#routeId +@aws-cdk/aws-apigateway.CfnRouteResponseV2#routeResponseKey +@aws-cdk/aws-apigateway.CfnRouteResponseV2#modelSelectionExpression +@aws-cdk/aws-apigateway.CfnRouteResponseV2#inspect +@aws-cdk/aws-apigateway.CfnRouteResponseV2#renderProperties +@aws-cdk/aws-apigateway.ParameterConstraintsProperty +@aws-cdk/aws-apigateway.ParameterConstraintsProperty#required +@aws-cdk/aws-apigateway.CfnRouteResponseV2Props +@aws-cdk/aws-apigateway.CfnRouteResponseV2Props#apiId +@aws-cdk/aws-apigateway.CfnRouteResponseV2Props#routeId +@aws-cdk/aws-apigateway.CfnRouteResponseV2Props#routeResponseKey +@aws-cdk/aws-apigateway.CfnRouteResponseV2Props#modelSelectionExpression +@aws-cdk/aws-apigateway.CfnRouteResponseV2Props#responseModels +@aws-cdk/aws-apigateway.CfnRouteResponseV2Props#responseParameters +@aws-cdk/aws-apigateway.CfnRouteV2 +@aws-cdk/aws-apigateway.CfnRouteV2#CFN_RESOURCE_TYPE_NAME +@aws-cdk/aws-apigateway.CfnRouteV2#cfnProperties +@aws-cdk/aws-apigateway.CfnRouteV2#apiId +@aws-cdk/aws-apigateway.CfnRouteV2#requestModels +@aws-cdk/aws-apigateway.CfnRouteV2#requestParameters +@aws-cdk/aws-apigateway.CfnRouteV2#routeKey +@aws-cdk/aws-apigateway.CfnRouteV2#apiKeyRequired +@aws-cdk/aws-apigateway.CfnRouteV2#authorizationScopes +@aws-cdk/aws-apigateway.CfnRouteV2#authorizationType +@aws-cdk/aws-apigateway.CfnRouteV2#authorizerId +@aws-cdk/aws-apigateway.CfnRouteV2#modelSelectionExpression +@aws-cdk/aws-apigateway.CfnRouteV2#operationName +@aws-cdk/aws-apigateway.CfnRouteV2#routeResponseSelectionExpression +@aws-cdk/aws-apigateway.CfnRouteV2#target +@aws-cdk/aws-apigateway.CfnRouteV2#inspect +@aws-cdk/aws-apigateway.CfnRouteV2#renderProperties +@aws-cdk/aws-apigateway.ParameterConstraintsProperty +@aws-cdk/aws-apigateway.ParameterConstraintsProperty#required +@aws-cdk/aws-apigateway.CfnRouteV2Props +@aws-cdk/aws-apigateway.CfnRouteV2Props#apiId +@aws-cdk/aws-apigateway.CfnRouteV2Props#routeKey +@aws-cdk/aws-apigateway.CfnRouteV2Props#apiKeyRequired +@aws-cdk/aws-apigateway.CfnRouteV2Props#authorizationScopes +@aws-cdk/aws-apigateway.CfnRouteV2Props#authorizationType +@aws-cdk/aws-apigateway.CfnRouteV2Props#authorizerId +@aws-cdk/aws-apigateway.CfnRouteV2Props#modelSelectionExpression +@aws-cdk/aws-apigateway.CfnRouteV2Props#operationName +@aws-cdk/aws-apigateway.CfnRouteV2Props#requestModels +@aws-cdk/aws-apigateway.CfnRouteV2Props#requestParameters +@aws-cdk/aws-apigateway.CfnRouteV2Props#routeResponseSelectionExpression +@aws-cdk/aws-apigateway.CfnRouteV2Props#target +@aws-cdk/aws-apigateway.CfnStageV2 +@aws-cdk/aws-apigateway.CfnStageV2#CFN_RESOURCE_TYPE_NAME +@aws-cdk/aws-apigateway.CfnStageV2#cfnProperties +@aws-cdk/aws-apigateway.CfnStageV2#tags +@aws-cdk/aws-apigateway.CfnStageV2#apiId +@aws-cdk/aws-apigateway.CfnStageV2#routeSettings +@aws-cdk/aws-apigateway.CfnStageV2#stageName +@aws-cdk/aws-apigateway.CfnStageV2#stageVariables +@aws-cdk/aws-apigateway.CfnStageV2#accessLogSettings +@aws-cdk/aws-apigateway.CfnStageV2#autoDeploy +@aws-cdk/aws-apigateway.CfnStageV2#clientCertificateId +@aws-cdk/aws-apigateway.CfnStageV2#defaultRouteSettings +@aws-cdk/aws-apigateway.CfnStageV2#deploymentId +@aws-cdk/aws-apigateway.CfnStageV2#description +@aws-cdk/aws-apigateway.CfnStageV2#inspect +@aws-cdk/aws-apigateway.CfnStageV2#renderProperties +@aws-cdk/aws-apigateway.AccessLogSettingsProperty +@aws-cdk/aws-apigateway.AccessLogSettingsProperty#destinationArn +@aws-cdk/aws-apigateway.AccessLogSettingsProperty#format +@aws-cdk/aws-apigateway.RouteSettingsProperty +@aws-cdk/aws-apigateway.RouteSettingsProperty#dataTraceEnabled +@aws-cdk/aws-apigateway.RouteSettingsProperty#detailedMetricsEnabled +@aws-cdk/aws-apigateway.RouteSettingsProperty#loggingLevel +@aws-cdk/aws-apigateway.RouteSettingsProperty#throttlingBurstLimit +@aws-cdk/aws-apigateway.RouteSettingsProperty#throttlingRateLimit +@aws-cdk/aws-apigateway.CfnStageV2Props +@aws-cdk/aws-apigateway.CfnStageV2Props#apiId +@aws-cdk/aws-apigateway.CfnStageV2Props#stageName +@aws-cdk/aws-apigateway.CfnStageV2Props#accessLogSettings +@aws-cdk/aws-apigateway.CfnStageV2Props#autoDeploy +@aws-cdk/aws-apigateway.CfnStageV2Props#clientCertificateId +@aws-cdk/aws-apigateway.CfnStageV2Props#defaultRouteSettings +@aws-cdk/aws-apigateway.CfnStageV2Props#deploymentId +@aws-cdk/aws-apigateway.CfnStageV2Props#description +@aws-cdk/aws-apigateway.CfnStageV2Props#routeSettings +@aws-cdk/aws-apigateway.CfnStageV2Props#stageVariables +@aws-cdk/aws-apigateway.CfnStageV2Props#tags +@aws-cdk/aws-apigateway.EmptyModel +@aws-cdk/aws-apigateway.EmptyModel#modelId +@aws-cdk/aws-apigateway.ErrorModel +@aws-cdk/aws-apigateway.ErrorModel#modelId +@aws-cdk/aws-apigateway.IResource#restApi +@aws-cdk/aws-apigateway.LambdaRestApiProps#options +@aws-cdk/aws-apigateway.Method#restApi +@aws-cdk/aws-apigateway.Resource#restApi +@aws-cdk/aws-apigateway.ResourceBase#restApi +@aws-cdk/aws-apigateway.ResourceBase#url +@aws-cdk/aws-apigateway.RestApiBase#configureCloudWatchRole +@aws-cdk/aws-apigateway.RestApiBase#configureDeployment +@aws-cdk/aws-apigateway.RestApiOptions +@aws-cdk/aws-apigateway.UsagePlanProps#apiKey +@aws-cdk/aws-certificatemanager.CertificateProps#validationDomains +@aws-cdk/aws-certificatemanager.CertificateProps#validationMethod +@aws-cdk/aws-route53.AddressRecordTarget +@aws-cdk/custom-resources.AwsSdkCall#outputPath +@aws-cdk/custom-resources.Provider#bind +@aws-cdk/aws-cloudformation.CloudFormationCapabilities +@aws-cdk/aws-cloudformation.CloudFormationCapabilities#NONE +@aws-cdk/aws-cloudformation.CloudFormationCapabilities#ANONYMOUS_IAM +@aws-cdk/aws-cloudformation.CloudFormationCapabilities#NAMED_IAM +@aws-cdk/aws-cloudformation.CloudFormationCapabilities#AUTO_EXPAND +@aws-cdk/aws-cloudformation.CustomResource +@aws-cdk/aws-cloudformation.CustomResourceProps +@aws-cdk/aws-cloudformation.CustomResourceProps#provider +@aws-cdk/aws-cloudformation.CustomResourceProps#properties +@aws-cdk/aws-cloudformation.CustomResourceProps#removalPolicy +@aws-cdk/aws-cloudformation.CustomResourceProps#resourceType +@aws-cdk/aws-cloudformation.CustomResourceProvider +@aws-cdk/aws-cloudformation.CustomResourceProvider#serviceToken +@aws-cdk/aws-cloudformation.CustomResourceProvider#fromLambda +@aws-cdk/aws-cloudformation.CustomResourceProvider#fromTopic +@aws-cdk/aws-cloudformation.CustomResourceProvider#lambda +@aws-cdk/aws-cloudformation.CustomResourceProvider#topic +@aws-cdk/aws-cloudformation.CustomResourceProvider#bind +@aws-cdk/aws-cloudformation.CustomResourceProviderConfig +@aws-cdk/aws-cloudformation.CustomResourceProviderConfig#serviceToken +@aws-cdk/aws-cloudformation.ICustomResourceProvider +@aws-cdk/aws-cloudformation.ICustomResourceProvider#bind +@aws-cdk/aws-cloudformation.NestedStack +@aws-cdk/aws-cloudformation.NestedStackProps +@aws-cdk/aws-cloudformation.NestedStackProps#notifications +@aws-cdk/aws-cloudformation.NestedStackProps#parameters +@aws-cdk/aws-cloudformation.NestedStackProps#timeout +@aws-cdk/aws-sns.NumericConditions#whitelist +@aws-cdk/aws-sns.StringConditions#blacklist +@aws-cdk/aws-sns.StringConditions#whitelist +@aws-cdk/aws-cognito.StandardAttributes#emailVerified +@aws-cdk/aws-cognito.StandardAttributes#phoneNumberVerified +@aws-cdk/aws-elasticloadbalancingv2.AddFixedResponseProps +@aws-cdk/aws-elasticloadbalancingv2.AddRedirectResponseProps +@aws-cdk/aws-elasticloadbalancingv2.AddRuleProps#hostHeader +@aws-cdk/aws-elasticloadbalancingv2.AddRuleProps#pathPattern +@aws-cdk/aws-elasticloadbalancingv2.AddRuleProps#pathPatterns +@aws-cdk/aws-elasticloadbalancingv2.ApplicationListener#addCertificateArns +@aws-cdk/aws-elasticloadbalancingv2.ApplicationListener#addFixedResponse +@aws-cdk/aws-elasticloadbalancingv2.ApplicationListener#addRedirectResponse +@aws-cdk/aws-elasticloadbalancingv2.ApplicationListenerAttributes#securityGroupAllowsAllOutbound +@aws-cdk/aws-elasticloadbalancingv2.ApplicationListenerAttributes#securityGroupId +@aws-cdk/aws-elasticloadbalancingv2.ApplicationListenerCertificateProps#certificateArns +@aws-cdk/aws-elasticloadbalancingv2.ApplicationListenerRule#addFixedResponse +@aws-cdk/aws-elasticloadbalancingv2.ApplicationListenerRule#addRedirectResponse +@aws-cdk/aws-elasticloadbalancingv2.ApplicationListenerRule#addTargetGroup +@aws-cdk/aws-elasticloadbalancingv2.ApplicationListenerRule#setCondition +@aws-cdk/aws-elasticloadbalancingv2.ApplicationTargetGroup#import +@aws-cdk/aws-elasticloadbalancingv2.BaseApplicationListenerProps#certificateArns +@aws-cdk/aws-elasticloadbalancingv2.BaseApplicationListenerRuleProps#fixedResponse +@aws-cdk/aws-elasticloadbalancingv2.BaseApplicationListenerRuleProps#hostHeader +@aws-cdk/aws-elasticloadbalancingv2.BaseApplicationListenerRuleProps#pathPattern +@aws-cdk/aws-elasticloadbalancingv2.BaseApplicationListenerRuleProps#pathPatterns +@aws-cdk/aws-elasticloadbalancingv2.BaseApplicationListenerRuleProps#redirectResponse +@aws-cdk/aws-elasticloadbalancingv2.ContentType +@aws-cdk/aws-elasticloadbalancingv2.ContentType#TEXT_PLAIN +@aws-cdk/aws-elasticloadbalancingv2.ContentType#TEXT_CSS +@aws-cdk/aws-elasticloadbalancingv2.ContentType#TEXT_HTML +@aws-cdk/aws-elasticloadbalancingv2.ContentType#APPLICATION_JAVASCRIPT +@aws-cdk/aws-elasticloadbalancingv2.ContentType#APPLICATION_JSON +@aws-cdk/aws-elasticloadbalancingv2.FixedResponse +@aws-cdk/aws-elasticloadbalancingv2.FixedResponse#statusCode +@aws-cdk/aws-elasticloadbalancingv2.FixedResponse#contentType +@aws-cdk/aws-elasticloadbalancingv2.FixedResponse#messageBody +@aws-cdk/aws-elasticloadbalancingv2.IApplicationListener#addCertificateArns +@aws-cdk/aws-elasticloadbalancingv2.INetworkListenerCertificateProps +@aws-cdk/aws-elasticloadbalancingv2.InstanceTarget +@aws-cdk/aws-elasticloadbalancingv2.InstanceTarget#attachToApplicationTargetGroup +@aws-cdk/aws-elasticloadbalancingv2.InstanceTarget#attachToNetworkTargetGroup +@aws-cdk/aws-elasticloadbalancingv2.IpTarget +@aws-cdk/aws-elasticloadbalancingv2.IpTarget#attachToApplicationTargetGroup +@aws-cdk/aws-elasticloadbalancingv2.IpTarget#attachToNetworkTargetGroup +@aws-cdk/aws-elasticloadbalancingv2.NetworkLoadBalancer#metricHealthyHostCount +@aws-cdk/aws-elasticloadbalancingv2.NetworkLoadBalancer#metricUnHealthyHostCount +@aws-cdk/aws-elasticloadbalancingv2.NetworkTargetGroup#import +@aws-cdk/aws-elasticloadbalancingv2.RedirectResponse +@aws-cdk/aws-elasticloadbalancingv2.RedirectResponse#statusCode +@aws-cdk/aws-elasticloadbalancingv2.RedirectResponse#host +@aws-cdk/aws-elasticloadbalancingv2.RedirectResponse#path +@aws-cdk/aws-elasticloadbalancingv2.RedirectResponse#port +@aws-cdk/aws-elasticloadbalancingv2.RedirectResponse#protocol +@aws-cdk/aws-elasticloadbalancingv2.RedirectResponse#query +@aws-cdk/aws-elasticloadbalancingv2.TargetGroupAttributes#defaultPort +@aws-cdk/aws-elasticloadbalancingv2.TargetGroupImportProps +@aws-cdk/aws-apigatewayv2.IHttpApi#httpApiId +@aws-cdk/aws-appmesh.Protocol +@aws-cdk/aws-appmesh.Protocol#HTTP +@aws-cdk/aws-appmesh.Protocol#TCP +@aws-cdk/aws-appmesh.Protocol#HTTP2 +@aws-cdk/aws-appmesh.Protocol#GRPC +@aws-cdk/aws-dynamodb.ITable#metricSystemErrors +@aws-cdk/aws-dynamodb.Table#grantListStreams +@aws-cdk/aws-dynamodb.Table#metricSystemErrors +@aws-cdk/aws-dynamodb.TableOptions#serverSideEncryption +@aws-cdk/aws-rds.Credentials#fromUsername +@aws-cdk/aws-rds.CredentialsFromUsernameOptions +@aws-cdk/aws-rds.CredentialsFromUsernameOptions#password +@aws-cdk/aws-rds.DatabaseInstanceEngine#MARIADB +@aws-cdk/aws-rds.DatabaseInstanceEngine#MYSQL +@aws-cdk/aws-rds.DatabaseInstanceEngine#ORACLE_EE +@aws-cdk/aws-rds.DatabaseInstanceEngine#ORACLE_SE +@aws-cdk/aws-rds.DatabaseInstanceEngine#ORACLE_SE1 +@aws-cdk/aws-rds.DatabaseInstanceEngine#ORACLE_SE2 +@aws-cdk/aws-rds.DatabaseInstanceEngine#POSTGRES +@aws-cdk/aws-rds.DatabaseInstanceEngine#SQL_SERVER_EE +@aws-cdk/aws-rds.DatabaseInstanceEngine#SQL_SERVER_EX +@aws-cdk/aws-rds.DatabaseInstanceEngine#SQL_SERVER_SE +@aws-cdk/aws-rds.DatabaseInstanceEngine#SQL_SERVER_WEB +@aws-cdk/aws-rds.DatabaseInstanceEngine#oracleSe +@aws-cdk/aws-rds.DatabaseInstanceEngine#oracleSe1 +@aws-cdk/aws-rds.DatabaseInstanceNewProps#vpcPlacement +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_0 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_0_17 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_0_24 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_0_28 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_0_31 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_0_32 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_0_34 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_0_35 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_1 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_1_14 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_1_19 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_1_23 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_1_26 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_1_31 +@aws-cdk/aws-rds.MariaDbEngineVersion#VER_10_1_34 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_5 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_5_46 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_5_53 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_5_57 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_5_59 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_5_61 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_6 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_6_34 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_6_35 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_6_37 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_6_39 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_6_40 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_6_41 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_6_43 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_6_44 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_6_46 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_6_48 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_6_49 +@aws-cdk/aws-rds.MysqlEngineVersion#VER_5_6_51 +@aws-cdk/aws-rds.OracleLegacyEngineVersion +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_2_V2 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V1 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V10 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V11 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V12 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V13 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V14 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V15 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V16 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V17 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V18 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V19 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V20 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V21 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V22 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V23 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V24 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V25 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V3 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V4 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V5 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V6 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V7 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V8 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#VER_11_2_0_4_V9 +@aws-cdk/aws-rds.OracleLegacyEngineVersion#oracleLegacyFullVersion +@aws-cdk/aws-rds.OracleLegacyEngineVersion#oracleLegacyMajorVersion +@aws-cdk/aws-rds.OracleSe1InstanceEngineProps +@aws-cdk/aws-rds.OracleSe1InstanceEngineProps#version +@aws-cdk/aws-rds.OracleSeInstanceEngineProps +@aws-cdk/aws-rds.OracleSeInstanceEngineProps#version +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_10 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_12 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_13 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_14 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_15 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_16 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_18 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_19 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_2 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_20 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_21 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_22 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_23 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_24 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_25 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_4 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_6 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_7 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_5_9 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_1 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_10 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_11 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_12 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_14 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_15 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_16 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_17 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_18 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_19 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_2 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_20 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_21 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_22 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_23 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_3 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_5 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_6 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_8 +@aws-cdk/aws-rds.PostgresEngineVersion#VER_9_6_9 +@aws-cdk/aws-rds.SnapshotCredentials#fromGeneratedPassword +@aws-cdk/aws-rds.SqlServerEngineVersion#VER_15_00_4043_23_V1 +@aws-cdk/aws-autoscaling.BlockDevice#mappingEnabled +@aws-cdk/aws-autoscaling.CommonAutoScalingGroupProps#notificationsTopic +@aws-cdk/aws-autoscaling.CommonAutoScalingGroupProps#replacingUpdateMinSuccessfulInstancesPercent +@aws-cdk/aws-autoscaling.CommonAutoScalingGroupProps#resourceSignalCount +@aws-cdk/aws-autoscaling.CommonAutoScalingGroupProps#resourceSignalTimeout +@aws-cdk/aws-autoscaling.CommonAutoScalingGroupProps#rollingUpdateConfiguration +@aws-cdk/aws-autoscaling.CommonAutoScalingGroupProps#updateType +@aws-cdk/aws-autoscaling.RequestCountScalingProps#targetRequestsPerSecond +@aws-cdk/aws-autoscaling.RollingUpdateConfiguration +@aws-cdk/aws-autoscaling.RollingUpdateConfiguration#maxBatchSize +@aws-cdk/aws-autoscaling.RollingUpdateConfiguration#minInstancesInService +@aws-cdk/aws-autoscaling.RollingUpdateConfiguration#minSuccessfulInstancesPercent +@aws-cdk/aws-autoscaling.RollingUpdateConfiguration#pauseTime +@aws-cdk/aws-autoscaling.RollingUpdateConfiguration#suspendProcesses +@aws-cdk/aws-autoscaling.RollingUpdateConfiguration#waitOnResourceSignals +@aws-cdk/aws-autoscaling.UpdateType +@aws-cdk/aws-autoscaling.UpdateType#NONE +@aws-cdk/aws-autoscaling.UpdateType#REPLACING_UPDATE +@aws-cdk/aws-autoscaling.UpdateType#ROLLING_UPDATE +@aws-cdk/aws-elasticloadbalancing.LoadBalancerListener#sslCertificateId +@aws-cdk/aws-ecs.AddAutoScalingGroupCapacityOptions#taskDrainTime +@aws-cdk/aws-ecs.BaseService#configureAwsVpcNetworking +@aws-cdk/aws-ecs.BaseServiceOptions#propagateTaskTagsFrom +@aws-cdk/aws-ecs.Cluster#addAutoScalingGroup +@aws-cdk/aws-ecs.Cluster#addCapacity +@aws-cdk/aws-ecs.Cluster#addCapacityProvider +@aws-cdk/aws-ecs.ClusterProps#capacityProviders +@aws-cdk/aws-ecs.Ec2ServiceProps#securityGroup +@aws-cdk/aws-ecs.EcsOptimizedAmi +@aws-cdk/aws-ecs.EcsOptimizedAmi#getImage +@aws-cdk/aws-ecs.EcsOptimizedAmiProps +@aws-cdk/aws-ecs.EcsOptimizedAmiProps#cachedInContext +@aws-cdk/aws-ecs.EcsOptimizedAmiProps#generation +@aws-cdk/aws-ecs.EcsOptimizedAmiProps#hardwareType +@aws-cdk/aws-ecs.EcsOptimizedAmiProps#windowsVersion +@aws-cdk/aws-ecs.FargateServiceProps#securityGroup +@aws-cdk/aws-ecs.SplunkLogDriverProps#token +@aws-cdk/aws-cloudfront.AliasConfiguration +@aws-cdk/aws-cloudfront.AliasConfiguration#acmCertRef +@aws-cdk/aws-cloudfront.AliasConfiguration#names +@aws-cdk/aws-cloudfront.AliasConfiguration#securityPolicy +@aws-cdk/aws-cloudfront.AliasConfiguration#sslMethod +@aws-cdk/aws-cloudfront.Behavior#trustedSigners +@aws-cdk/aws-cloudfront.CloudFrontWebDistribution#domainName +@aws-cdk/aws-cloudfront.CloudFrontWebDistributionProps#aliasConfiguration +@aws-cdk/aws-cloudfront.GeoRestriction#blacklist +@aws-cdk/aws-cloudfront.GeoRestriction#whitelist +@aws-cdk/aws-cloudfront.IDistribution#domainName +@aws-cdk/aws-cloudfront.SourceConfiguration#originHeaders +@aws-cdk/aws-cloudfront.SourceConfiguration#originPath +@aws-cdk/aws-cloudtrail.Trail#onCloudTrailEvent +@aws-cdk/aws-cloudtrail.TrailProps#kmsKey +@aws-cdk/aws-codepipeline-actions.BitBucketSourceAction +@aws-cdk/aws-codepipeline-actions.BitBucketSourceAction#actionProperties +@aws-cdk/aws-codepipeline-actions.BitBucketSourceAction#bind +@aws-cdk/aws-codepipeline-actions.BitBucketSourceAction#onStateChange +@aws-cdk/aws-codepipeline-actions.BitBucketSourceActionProps +@aws-cdk/aws-codepipeline-actions.CloudFormationCreateReplaceChangeSetActionProps#capabilities +@aws-cdk/aws-codepipeline-actions.CloudFormationCreateUpdateStackActionProps#capabilities +@aws-cdk/aws-codepipeline-actions.CloudFormationDeleteStackActionProps#capabilities +@aws-cdk/aws-events-targets.EcsTask#securityGroup +@aws-cdk/aws-events-targets.EcsTaskProps#securityGroup +@aws-cdk/aws-stepfunctions.Context +@aws-cdk/aws-stepfunctions.Context#entireContext +@aws-cdk/aws-stepfunctions.Context#taskToken +@aws-cdk/aws-stepfunctions.Context#numberAt +@aws-cdk/aws-stepfunctions.Context#stringAt +@aws-cdk/aws-stepfunctions.Data +@aws-cdk/aws-stepfunctions.Data#entirePayload +@aws-cdk/aws-stepfunctions.Data#isJsonPathString +@aws-cdk/aws-stepfunctions.Data#listAt +@aws-cdk/aws-stepfunctions.Data#numberAt +@aws-cdk/aws-stepfunctions.Data#stringAt +@aws-cdk/aws-stepfunctions.IStepFunctionsTask +@aws-cdk/aws-stepfunctions.IStepFunctionsTask#bind +@aws-cdk/aws-stepfunctions.StepFunctionsTaskConfig +@aws-cdk/aws-stepfunctions.StepFunctionsTaskConfig#resourceArn +@aws-cdk/aws-stepfunctions.StepFunctionsTaskConfig#heartbeat +@aws-cdk/aws-stepfunctions.StepFunctionsTaskConfig#metricDimensions +@aws-cdk/aws-stepfunctions.StepFunctionsTaskConfig#metricPrefixPlural +@aws-cdk/aws-stepfunctions.StepFunctionsTaskConfig#metricPrefixSingular +@aws-cdk/aws-stepfunctions.StepFunctionsTaskConfig#parameters +@aws-cdk/aws-stepfunctions.StepFunctionsTaskConfig#policyStatements +@aws-cdk/aws-stepfunctions.Task +@aws-cdk/aws-stepfunctions.Task#endStates +@aws-cdk/aws-stepfunctions.Task#addCatch +@aws-cdk/aws-stepfunctions.Task#addRetry +@aws-cdk/aws-stepfunctions.Task#metric +@aws-cdk/aws-stepfunctions.Task#metricFailed +@aws-cdk/aws-stepfunctions.Task#metricHeartbeatTimedOut +@aws-cdk/aws-stepfunctions.Task#metricRunTime +@aws-cdk/aws-stepfunctions.Task#metricScheduled +@aws-cdk/aws-stepfunctions.Task#metricScheduleTime +@aws-cdk/aws-stepfunctions.Task#metricStarted +@aws-cdk/aws-stepfunctions.Task#metricSucceeded +@aws-cdk/aws-stepfunctions.Task#metricTime +@aws-cdk/aws-stepfunctions.Task#metricTimedOut +@aws-cdk/aws-stepfunctions.Task#next +@aws-cdk/aws-stepfunctions.Task#toStateJson +@aws-cdk/aws-stepfunctions.Task#whenBoundToGraph +@aws-cdk/aws-stepfunctions.TaskInput#fromContextAt +@aws-cdk/aws-stepfunctions.TaskInput#fromDataAt +@aws-cdk/aws-stepfunctions.TaskProps +@aws-cdk/aws-stepfunctions.TaskProps#task +@aws-cdk/aws-stepfunctions.TaskProps#comment +@aws-cdk/aws-stepfunctions.TaskProps#inputPath +@aws-cdk/aws-stepfunctions.TaskProps#outputPath +@aws-cdk/aws-stepfunctions.TaskProps#parameters +@aws-cdk/aws-stepfunctions.TaskProps#resultPath +@aws-cdk/aws-stepfunctions.TaskProps#timeout +@aws-cdk/aws-ecs-patterns.ApplicationLoadBalancedServiceBase#desiredCount +@aws-cdk/aws-ecs-patterns.ApplicationMultipleTargetGroupsServiceBase#desiredCount +@aws-cdk/aws-ecs-patterns.NetworkLoadBalancedServiceBase#desiredCount +@aws-cdk/aws-ecs-patterns.NetworkMultipleTargetGroupsServiceBase#desiredCount +@aws-cdk/aws-ecs-patterns.QueueProcessingServiceBase#desiredCount +@aws-cdk/aws-ecs-patterns.QueueProcessingServiceBaseProps#desiredTaskCount +@aws-cdk/aws-eks.NodegroupOptions#instanceType +@aws-cdk/aws-eks.ServiceAccount#addToPolicy +@aws-cdk/aws-s3-deployment.Expires +@aws-cdk/aws-s3-deployment.Expires#value +@aws-cdk/aws-s3-deployment.Expires#after +@aws-cdk/aws-s3-deployment.Expires#atDate +@aws-cdk/aws-s3-deployment.Expires#atTimestamp +@aws-cdk/aws-s3-deployment.Expires#fromString +@aws-cdk/aws-ses.WhiteListReceiptFilter +@aws-cdk/aws-ses.WhiteListReceiptFilterProps +@aws-cdk/aws-stepfunctions-tasks.EcsRunTaskBase +@aws-cdk/aws-stepfunctions-tasks.EcsRunTaskBase#connections +@aws-cdk/aws-stepfunctions-tasks.EcsRunTaskBase#bind +@aws-cdk/aws-stepfunctions-tasks.EcsRunTaskBase#configureAwsVpcNetworking +@aws-cdk/aws-stepfunctions-tasks.EcsRunTaskBaseProps +@aws-cdk/aws-stepfunctions-tasks.EcsRunTaskBaseProps#parameters +@aws-cdk/aws-stepfunctions-tasks.InvocationType +@aws-cdk/aws-stepfunctions-tasks.InvocationType#REQUEST_RESPONSE +@aws-cdk/aws-stepfunctions-tasks.InvocationType#EVENT +@aws-cdk/aws-stepfunctions-tasks.InvocationType#DRY_RUN +@aws-cdk/aws-stepfunctions-tasks.InvokeActivity +@aws-cdk/aws-stepfunctions-tasks.InvokeActivity#bind +@aws-cdk/aws-stepfunctions-tasks.InvokeActivityProps +@aws-cdk/aws-stepfunctions-tasks.InvokeActivityProps#heartbeat +@aws-cdk/aws-stepfunctions-tasks.InvokeFunction +@aws-cdk/aws-stepfunctions-tasks.InvokeFunction#bind +@aws-cdk/aws-stepfunctions-tasks.InvokeFunctionProps +@aws-cdk/aws-stepfunctions-tasks.InvokeFunctionProps#payload +@aws-cdk/aws-stepfunctions-tasks.PublishToTopic +@aws-cdk/aws-stepfunctions-tasks.PublishToTopic#bind +@aws-cdk/aws-stepfunctions-tasks.PublishToTopicProps +@aws-cdk/aws-stepfunctions-tasks.PublishToTopicProps#message +@aws-cdk/aws-stepfunctions-tasks.PublishToTopicProps#integrationPattern +@aws-cdk/aws-stepfunctions-tasks.PublishToTopicProps#messagePerSubscriptionType +@aws-cdk/aws-stepfunctions-tasks.PublishToTopicProps#subject +@aws-cdk/aws-stepfunctions-tasks.RunBatchJob +@aws-cdk/aws-stepfunctions-tasks.RunBatchJob#bind +@aws-cdk/aws-stepfunctions-tasks.RunBatchJobProps +@aws-cdk/aws-stepfunctions-tasks.RunBatchJobProps#jobDefinitionArn +@aws-cdk/aws-stepfunctions-tasks.RunBatchJobProps#jobName +@aws-cdk/aws-stepfunctions-tasks.RunBatchJobProps#jobQueueArn +@aws-cdk/aws-stepfunctions-tasks.RunBatchJobProps#arraySize +@aws-cdk/aws-stepfunctions-tasks.RunBatchJobProps#attempts +@aws-cdk/aws-stepfunctions-tasks.RunBatchJobProps#containerOverrides +@aws-cdk/aws-stepfunctions-tasks.RunBatchJobProps#dependsOn +@aws-cdk/aws-stepfunctions-tasks.RunBatchJobProps#integrationPattern +@aws-cdk/aws-stepfunctions-tasks.RunBatchJobProps#payload +@aws-cdk/aws-stepfunctions-tasks.RunBatchJobProps#timeout +@aws-cdk/aws-stepfunctions-tasks.RunEcsEc2Task +@aws-cdk/aws-stepfunctions-tasks.RunEcsEc2TaskProps +@aws-cdk/aws-stepfunctions-tasks.RunEcsEc2TaskProps#placementConstraints +@aws-cdk/aws-stepfunctions-tasks.RunEcsEc2TaskProps#placementStrategies +@aws-cdk/aws-stepfunctions-tasks.RunEcsEc2TaskProps#securityGroup +@aws-cdk/aws-stepfunctions-tasks.RunEcsEc2TaskProps#subnets +@aws-cdk/aws-stepfunctions-tasks.RunEcsFargateTask +@aws-cdk/aws-stepfunctions-tasks.RunEcsFargateTaskProps +@aws-cdk/aws-stepfunctions-tasks.RunEcsFargateTaskProps#assignPublicIp +@aws-cdk/aws-stepfunctions-tasks.RunEcsFargateTaskProps#platformVersion +@aws-cdk/aws-stepfunctions-tasks.RunEcsFargateTaskProps#securityGroup +@aws-cdk/aws-stepfunctions-tasks.RunEcsFargateTaskProps#subnets +@aws-cdk/aws-stepfunctions-tasks.RunGlueJobTask +@aws-cdk/aws-stepfunctions-tasks.RunGlueJobTask#bind +@aws-cdk/aws-stepfunctions-tasks.RunGlueJobTaskProps +@aws-cdk/aws-stepfunctions-tasks.RunGlueJobTaskProps#arguments +@aws-cdk/aws-stepfunctions-tasks.RunGlueJobTaskProps#integrationPattern +@aws-cdk/aws-stepfunctions-tasks.RunGlueJobTaskProps#notifyDelayAfter +@aws-cdk/aws-stepfunctions-tasks.RunGlueJobTaskProps#securityConfiguration +@aws-cdk/aws-stepfunctions-tasks.RunGlueJobTaskProps#timeout +@aws-cdk/aws-stepfunctions-tasks.RunLambdaTask +@aws-cdk/aws-stepfunctions-tasks.RunLambdaTask#bind +@aws-cdk/aws-stepfunctions-tasks.RunLambdaTaskProps +@aws-cdk/aws-stepfunctions-tasks.RunLambdaTaskProps#clientContext +@aws-cdk/aws-stepfunctions-tasks.RunLambdaTaskProps#integrationPattern +@aws-cdk/aws-stepfunctions-tasks.RunLambdaTaskProps#invocationType +@aws-cdk/aws-stepfunctions-tasks.RunLambdaTaskProps#payload +@aws-cdk/aws-stepfunctions-tasks.RunLambdaTaskProps#qualifier +@aws-cdk/aws-stepfunctions-tasks.SendToQueue +@aws-cdk/aws-stepfunctions-tasks.SendToQueue#bind +@aws-cdk/aws-stepfunctions-tasks.SendToQueueProps +@aws-cdk/aws-stepfunctions-tasks.SendToQueueProps#messageBody +@aws-cdk/aws-stepfunctions-tasks.SendToQueueProps#delay +@aws-cdk/aws-stepfunctions-tasks.SendToQueueProps#integrationPattern +@aws-cdk/aws-stepfunctions-tasks.SendToQueueProps#messageDeduplicationId +@aws-cdk/aws-stepfunctions-tasks.SendToQueueProps#messageGroupId +@aws-cdk/aws-stepfunctions-tasks.StartExecution +@aws-cdk/aws-stepfunctions-tasks.StartExecution#bind +@aws-cdk/aws-stepfunctions-tasks.StartExecutionProps +@aws-cdk/aws-stepfunctions-tasks.StartExecutionProps#input +@aws-cdk/aws-stepfunctions-tasks.StartExecutionProps#integrationPattern +@aws-cdk/aws-stepfunctions-tasks.StartExecutionProps#name +@aws-cdk/pipelines.AddManualApprovalOptions +@aws-cdk/pipelines.AddManualApprovalOptions#actionName +@aws-cdk/pipelines.AddManualApprovalOptions#runOrder +@aws-cdk/pipelines.AddStackOptions +@aws-cdk/pipelines.AddStackOptions#executeRunOrder +@aws-cdk/pipelines.AddStackOptions#runOrder +@aws-cdk/pipelines.AddStageOptions +@aws-cdk/pipelines.AddStageOptions#extraRunOrderSpace +@aws-cdk/pipelines.AddStageOptions#manualApprovals +@aws-cdk/pipelines.AdditionalArtifact +@aws-cdk/pipelines.AdditionalArtifact#artifact +@aws-cdk/pipelines.AdditionalArtifact#directory +@aws-cdk/pipelines.AssetPublishingCommand +@aws-cdk/pipelines.AssetPublishingCommand#assetId +@aws-cdk/pipelines.AssetPublishingCommand#assetManifestPath +@aws-cdk/pipelines.AssetPublishingCommand#assetPublishingRoleArn +@aws-cdk/pipelines.AssetPublishingCommand#assetSelector +@aws-cdk/pipelines.AssetPublishingCommand#assetType +@aws-cdk/pipelines.BaseStageOptions +@aws-cdk/pipelines.BaseStageOptions#confirmBroadeningPermissions +@aws-cdk/pipelines.BaseStageOptions#securityNotificationTopic +@aws-cdk/pipelines.CdkPipeline +@aws-cdk/pipelines.CdkPipeline#codePipeline +@aws-cdk/pipelines.CdkPipeline#addApplicationStage +@aws-cdk/pipelines.CdkPipeline#addStage +@aws-cdk/pipelines.CdkPipeline#stackOutput +@aws-cdk/pipelines.CdkPipeline#stage +@aws-cdk/pipelines.CdkPipeline#validate +@aws-cdk/pipelines.CdkPipelineProps +@aws-cdk/pipelines.CdkPipelineProps#cloudAssemblyArtifact +@aws-cdk/pipelines.CdkPipelineProps#assetBuildSpec +@aws-cdk/pipelines.CdkPipelineProps#assetPreInstallCommands +@aws-cdk/pipelines.CdkPipelineProps#cdkCliVersion +@aws-cdk/pipelines.CdkPipelineProps#codePipeline +@aws-cdk/pipelines.CdkPipelineProps#crossAccountKeys +@aws-cdk/pipelines.CdkPipelineProps#dockerCredentials +@aws-cdk/pipelines.CdkPipelineProps#enableKeyRotation +@aws-cdk/pipelines.CdkPipelineProps#pipelineName +@aws-cdk/pipelines.CdkPipelineProps#selfMutating +@aws-cdk/pipelines.CdkPipelineProps#selfMutationBuildSpec +@aws-cdk/pipelines.CdkPipelineProps#singlePublisherPerType +@aws-cdk/pipelines.CdkPipelineProps#sourceAction +@aws-cdk/pipelines.CdkPipelineProps#subnetSelection +@aws-cdk/pipelines.CdkPipelineProps#supportDockerAssets +@aws-cdk/pipelines.CdkPipelineProps#synthAction +@aws-cdk/pipelines.CdkPipelineProps#vpc +@aws-cdk/pipelines.CdkStackActionFromArtifactOptions +@aws-cdk/pipelines.CdkStackActionFromArtifactOptions#stackName +@aws-cdk/pipelines.CdkStage +@aws-cdk/pipelines.CdkStage#addActions +@aws-cdk/pipelines.CdkStage#addApplication +@aws-cdk/pipelines.CdkStage#addManualApprovalAction +@aws-cdk/pipelines.CdkStage#addStackArtifactDeployment +@aws-cdk/pipelines.CdkStage#deploysStack +@aws-cdk/pipelines.CdkStage#nextSequentialRunOrder +@aws-cdk/pipelines.CdkStageProps +@aws-cdk/pipelines.CdkStageProps#cloudAssemblyArtifact +@aws-cdk/pipelines.CdkStageProps#host +@aws-cdk/pipelines.CdkStageProps#pipelineStage +@aws-cdk/pipelines.CdkStageProps#stageName +@aws-cdk/pipelines.CdkStageProps#confirmBroadeningPermissions +@aws-cdk/pipelines.CdkStageProps#securityNotificationTopic +@aws-cdk/pipelines.DeployCdkStackAction +@aws-cdk/pipelines.DeployCdkStackAction#actionProperties +@aws-cdk/pipelines.DeployCdkStackAction#dependencyStackArtifactIds +@aws-cdk/pipelines.DeployCdkStackAction#executeRunOrder +@aws-cdk/pipelines.DeployCdkStackAction#prepareRunOrder +@aws-cdk/pipelines.DeployCdkStackAction#stackName +@aws-cdk/pipelines.DeployCdkStackAction#stackArtifactId +@aws-cdk/pipelines.DeployCdkStackAction#fromStackArtifact +@aws-cdk/pipelines.DeployCdkStackAction#bind +@aws-cdk/pipelines.DeployCdkStackAction#onStateChange +@aws-cdk/pipelines.DeployCdkStackActionOptions +@aws-cdk/pipelines.DeployCdkStackActionOptions#cloudAssemblyInput +@aws-cdk/pipelines.DeployCdkStackActionOptions#baseActionName +@aws-cdk/pipelines.DeployCdkStackActionOptions#changeSetName +@aws-cdk/pipelines.DeployCdkStackActionOptions#executeRunOrder +@aws-cdk/pipelines.DeployCdkStackActionOptions#output +@aws-cdk/pipelines.DeployCdkStackActionOptions#outputFileName +@aws-cdk/pipelines.DeployCdkStackActionOptions#prepareRunOrder +@aws-cdk/pipelines.DeployCdkStackActionProps +@aws-cdk/pipelines.DeployCdkStackActionProps#actionRole +@aws-cdk/pipelines.DeployCdkStackActionProps#stackName +@aws-cdk/pipelines.DeployCdkStackActionProps#templatePath +@aws-cdk/pipelines.DeployCdkStackActionProps#cloudFormationExecutionRole +@aws-cdk/pipelines.DeployCdkStackActionProps#dependencyStackArtifactIds +@aws-cdk/pipelines.DeployCdkStackActionProps#region +@aws-cdk/pipelines.DeployCdkStackActionProps#stackArtifactId +@aws-cdk/pipelines.DeployCdkStackActionProps#templateConfigurationPath +@aws-cdk/pipelines.FromStackArtifactOptions +@aws-cdk/pipelines.FromStackArtifactOptions#cloudAssemblyInput +@aws-cdk/pipelines.FromStackArtifactOptions#executeRunOrder +@aws-cdk/pipelines.FromStackArtifactOptions#output +@aws-cdk/pipelines.FromStackArtifactOptions#outputFileName +@aws-cdk/pipelines.FromStackArtifactOptions#prepareRunOrder +@aws-cdk/pipelines.IStageHost +@aws-cdk/pipelines.IStageHost#publishAsset +@aws-cdk/pipelines.IStageHost#stackOutputArtifact +@aws-cdk/pipelines.PublishAssetsAction +@aws-cdk/pipelines.PublishAssetsAction#actionProperties +@aws-cdk/pipelines.PublishAssetsAction#addPublishCommand +@aws-cdk/pipelines.PublishAssetsAction#bind +@aws-cdk/pipelines.PublishAssetsAction#onStateChange +@aws-cdk/pipelines.PublishAssetsActionProps +@aws-cdk/pipelines.PublishAssetsActionProps#actionName +@aws-cdk/pipelines.PublishAssetsActionProps#assetType +@aws-cdk/pipelines.PublishAssetsActionProps#cloudAssemblyInput +@aws-cdk/pipelines.PublishAssetsActionProps#buildSpec +@aws-cdk/pipelines.PublishAssetsActionProps#cdkCliVersion +@aws-cdk/pipelines.PublishAssetsActionProps#createBuildspecFile +@aws-cdk/pipelines.PublishAssetsActionProps#dependable +@aws-cdk/pipelines.PublishAssetsActionProps#preInstallCommands +@aws-cdk/pipelines.PublishAssetsActionProps#projectName +@aws-cdk/pipelines.PublishAssetsActionProps#role +@aws-cdk/pipelines.PublishAssetsActionProps#subnetSelection +@aws-cdk/pipelines.PublishAssetsActionProps#vpc +@aws-cdk/pipelines.ShellScriptAction +@aws-cdk/pipelines.ShellScriptAction#actionProperties +@aws-cdk/pipelines.ShellScriptAction#grantPrincipal +@aws-cdk/pipelines.ShellScriptAction#project +@aws-cdk/pipelines.ShellScriptAction#bind +@aws-cdk/pipelines.ShellScriptAction#onStateChange +@aws-cdk/pipelines.ShellScriptActionProps +@aws-cdk/pipelines.ShellScriptActionProps#actionName +@aws-cdk/pipelines.ShellScriptActionProps#commands +@aws-cdk/pipelines.ShellScriptActionProps#additionalArtifacts +@aws-cdk/pipelines.ShellScriptActionProps#bashOptions +@aws-cdk/pipelines.ShellScriptActionProps#environment +@aws-cdk/pipelines.ShellScriptActionProps#environmentVariables +@aws-cdk/pipelines.ShellScriptActionProps#rolePolicyStatements +@aws-cdk/pipelines.ShellScriptActionProps#runOrder +@aws-cdk/pipelines.ShellScriptActionProps#securityGroups +@aws-cdk/pipelines.ShellScriptActionProps#subnetSelection +@aws-cdk/pipelines.ShellScriptActionProps#useOutputs +@aws-cdk/pipelines.ShellScriptActionProps#vpc +@aws-cdk/pipelines.SimpleSynthAction +@aws-cdk/pipelines.SimpleSynthAction#actionProperties +@aws-cdk/pipelines.SimpleSynthAction#grantPrincipal +@aws-cdk/pipelines.SimpleSynthAction#project +@aws-cdk/pipelines.SimpleSynthAction#standardNpmSynth +@aws-cdk/pipelines.SimpleSynthAction#standardYarnSynth +@aws-cdk/pipelines.SimpleSynthAction#bind +@aws-cdk/pipelines.SimpleSynthAction#onStateChange +@aws-cdk/pipelines.SimpleSynthActionProps +@aws-cdk/pipelines.SimpleSynthActionProps#synthCommand +@aws-cdk/pipelines.SimpleSynthActionProps#buildCommand +@aws-cdk/pipelines.SimpleSynthActionProps#buildCommands +@aws-cdk/pipelines.SimpleSynthActionProps#installCommand +@aws-cdk/pipelines.SimpleSynthActionProps#installCommands +@aws-cdk/pipelines.SimpleSynthActionProps#testCommands +@aws-cdk/pipelines.SimpleSynthOptions +@aws-cdk/pipelines.SimpleSynthOptions#cloudAssemblyArtifact +@aws-cdk/pipelines.SimpleSynthOptions#sourceArtifact +@aws-cdk/pipelines.SimpleSynthOptions#actionName +@aws-cdk/pipelines.SimpleSynthOptions#additionalArtifacts +@aws-cdk/pipelines.SimpleSynthOptions#buildSpec +@aws-cdk/pipelines.SimpleSynthOptions#copyEnvironmentVariables +@aws-cdk/pipelines.SimpleSynthOptions#environment +@aws-cdk/pipelines.SimpleSynthOptions#environmentVariables +@aws-cdk/pipelines.SimpleSynthOptions#projectName +@aws-cdk/pipelines.SimpleSynthOptions#rolePolicyStatements +@aws-cdk/pipelines.SimpleSynthOptions#subdirectory +@aws-cdk/pipelines.SimpleSynthOptions#subnetSelection +@aws-cdk/pipelines.SimpleSynthOptions#vpc +@aws-cdk/pipelines.StackOutput +@aws-cdk/pipelines.StackOutput#artifactFile +@aws-cdk/pipelines.StackOutput#outputName +@aws-cdk/pipelines.StandardNpmSynthOptions +@aws-cdk/pipelines.StandardNpmSynthOptions#buildCommand +@aws-cdk/pipelines.StandardNpmSynthOptions#installCommand +@aws-cdk/pipelines.StandardNpmSynthOptions#synthCommand +@aws-cdk/pipelines.StandardNpmSynthOptions#testCommands +@aws-cdk/pipelines.StandardYarnSynthOptions +@aws-cdk/pipelines.StandardYarnSynthOptions#buildCommand +@aws-cdk/pipelines.StandardYarnSynthOptions#installCommand +@aws-cdk/pipelines.StandardYarnSynthOptions#synthCommand +@aws-cdk/pipelines.StandardYarnSynthOptions#testCommands +@aws-cdk/pipelines.UpdatePipelineAction +@aws-cdk/pipelines.UpdatePipelineAction#actionProperties +@aws-cdk/pipelines.UpdatePipelineAction#bind +@aws-cdk/pipelines.UpdatePipelineAction#onStateChange +@aws-cdk/pipelines.UpdatePipelineActionProps +@aws-cdk/pipelines.UpdatePipelineActionProps#cloudAssemblyInput +@aws-cdk/pipelines.UpdatePipelineActionProps#pipelineStackHierarchicalId +@aws-cdk/pipelines.UpdatePipelineActionProps#buildSpec +@aws-cdk/pipelines.UpdatePipelineActionProps#cdkCliVersion +@aws-cdk/pipelines.UpdatePipelineActionProps#dockerCredentials +@aws-cdk/pipelines.UpdatePipelineActionProps#pipelineStackName +@aws-cdk/pipelines.UpdatePipelineActionProps#privileged +@aws-cdk/pipelines.UpdatePipelineActionProps#projectName diff --git a/scripts/list-deprecated-apis.js b/scripts/list-deprecated-apis.js index 284022b4825e1..a4596ebdf1a69 100755 --- a/scripts/list-deprecated-apis.js +++ b/scripts/list-deprecated-apis.js @@ -3,51 +3,78 @@ const path = require('path'); const jsiiReflect = require('jsii-reflect'); -async function main() { +class MarkdownPrinter { + printHeader() { + process.stdout.write(`# List of deprecated APIs in v1\n`); + process.stdout.write('\n'); + process.stdout.write(`| Module | API Element | Message |\n`); + process.stdout.write(`|--------|-------------|---------|\n`); + } + + printIfDeprecated(mod, name, el) { + try { + if (el.docs.deprecated) { + // Add zero-width spaces after . and _ to allow for line breaking long identifiers + // (WindowsVersion.WINDOWS_SERVER_2012_RTM_CHINESE_TRADITIONAL_HONG_KONG_SAR_64BIT_BASE is a fun one...) + // For consistency with the original format, replace the '#' separators with '.' + const apiName = name.replace('#', '.').replace(/(\.|_)/g, '$1\u200B'); + + // Some deprecation reasons start with '- ' for misguided reasons. Get rid of it, and also get rid of newlines. + const reason = el.docs.deprecationReason.replace(/^-/, '').replace(/\n/g, ' ').trim(); + + process.stdout.write(`| ${mod} | ${apiName} | ${reason} |\n`); + } + } catch (e) { + console.error(`While processing ${mod}.${name}:`, e); + } + } +} + +/** For use as input to the --strip-deprecated argument in jsii */ +class StripDeprecatedPrinter { + printHeader() { } + + printIfDeprecated(mod, name, el) { + try { + if (el.docs.deprecated) { + // Remove the method parens + process.stdout.write(`${mod}.${name.replace(/\(\)$/, '')}\n`); + } + } catch (e) { + console.error(`While processing ${mod}.${name}:`, e); + } + } +} + +async function main(printer) { const typesystem = new jsiiReflect.TypeSystem(); // Decdk depends on everything, so that's a perfect directory to load as closure await typesystem.loadNpmDependencies(path.resolve(__dirname, '..', 'packages', 'decdk'), { validate: false }); - process.stdout.write(`# List of deprecated APIs in v1\n`); - process.stdout.write('\n'); - process.stdout.write(`| Module | API Element | Message |\n`); - process.stdout.write(`|--------|-------------|---------|\n`); + printer.printHeader(); for (const assembly of typesystem.assemblies) { for (const type of assembly.types) { - printIfDeprecated(assembly.fqn, type.name, type); + printer.printIfDeprecated(assembly.fqn, type.name, type); if (type.isEnumType()) { - type.members.forEach(e => printIfDeprecated(assembly.fqn, `${type.name}.${e.name}`, e)); + type.members.forEach(e => printer.printIfDeprecated(assembly.fqn, `${type.name}#${e.name}`, e)); } if (type.isInterfaceType() || type.isClassType() || type.isDataType()) { - type.ownProperties.forEach(p => printIfDeprecated(assembly.fqn, `${type.name}.${p.name}`, p)); + type.ownProperties.forEach(p => printer.printIfDeprecated(assembly.fqn, `${type.name}#${p.name}`, p)); type.ownMethods.forEach(method => { - printIfDeprecated(assembly.fqn, `${type.name}.${method.name}()`, method); - method.parameters.forEach(p => printIfDeprecated(assembly.fqn, `${type.name}.${method.name}(): ${p.name}`, p)); + printer.printIfDeprecated(assembly.fqn, `${type.name}#${method.name}()`, method); + method.parameters.forEach(p => printer.printIfDeprecated(assembly.fqn, `${type.name}#${method.name}(): ${p.name}`, p)); }); } } } } -function printIfDeprecated(mod, name, el) { - try { - if (el.docs.deprecated) { - // Add zero-width spaces after . and _ to allow for line breaking long identifiers - // (WindowsVersion.WINDOWS_SERVER_2012_RTM_CHINESE_TRADITIONAL_HONG_KONG_SAR_64BIT_BASE is a fun one...) - const apiName = name.replace(/(\.|_)/g, '$1\u200B'); - - // Some deprecation reasons start with '- ' for misguided reasons. Get rid of it, and also get rid of newlines. - const reason = el.docs.deprecationReason.replace(/^-/, '').replace(/\n/g, ' ').trim(); - - process.stdout.write(`| ${mod} | ${apiName} | ${reason} |\n`); - } - } catch (e) { - console.error(`While processing ${mod}.${name}:`, e); - } -} +const printer = (process.argv.length > 2 && process.argv[2] === '--plain') + ? new StripDeprecatedPrinter() + : new MarkdownPrinter(); -main().catch(e => console.error(e)); +main(printer).catch(e => console.error(e)); From 7640130b9f033ea950941ef8de46343869e523f5 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Wed, 27 Oct 2021 13:42:20 +0100 Subject: [PATCH 055/148] chore(assertions): minor documentation tweaks (#17138) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/assertions/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/assertions/README.md b/packages/@aws-cdk/assertions/README.md index 47a27cbbd2513..3c97f387d8398 100644 --- a/packages/@aws-cdk/assertions/README.md +++ b/packages/@aws-cdk/assertions/README.md @@ -45,9 +45,11 @@ template. ```ts const expected = { Resources: { - Type: 'Foo::Bar', - Properties: { - Baz: 'Qux', + BarLogicalId: { + Type: 'Foo::Bar', + Properties: { + Baz: 'Qux', + }, }, }, }; @@ -62,7 +64,7 @@ to change this. Snapshot testing is a common technique to store a snapshot of the output and compare it during future changes. Since CloudFormation templates are human readable, -they are a good target for รฅรŸsnapshot testing. +they are a good target for snapshot testing. The `toJSON()` method on the `Template` can be used to produce a well formatted JSON of the CloudFormation template that can be used as a snapshot. From ca02187cba79e04d84b097bfb6838ac746a1a065 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 27 Oct 2021 15:36:00 +0200 Subject: [PATCH 056/148] chore(events): make examples compile (#17157) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-events/README.md | 45 +++++++++++++------ .../aws-events/rosetta/basic.ts-fixture | 12 +++++ .../aws-events/rosetta/default.ts-fixture | 20 +++++++++ 3 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 packages/@aws-cdk/aws-events/rosetta/basic.ts-fixture create mode 100644 packages/@aws-cdk/aws-events/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-events/README.md b/packages/@aws-cdk/aws-events/README.md index 0288407ee094f..13bd483ca54cb 100644 --- a/packages/@aws-cdk/aws-events/README.md +++ b/packages/@aws-cdk/aws-events/README.md @@ -59,6 +59,9 @@ For example, to define an rule that triggers a CodeBuild project build when a commit is pushed to the "master" branch of a CodeCommit repository: ```ts +declare const repo: codecommit.Repository; +declare const project: codebuild.Project; + const onCommitRule = repo.onCommit('OnCommit', { target: new targets.CodeBuildProject(project), branches: ['master'] @@ -73,6 +76,9 @@ topic target which formats a human-readable message for the commit. For example, this adds an SNS topic as a target: ```ts +declare const onCommitRule: events.Rule; +declare const topic: sns.Topic; + onCommitRule.addTarget(new targets.SnsTopic(topic, { message: events.RuleTargetInput.fromText( `A commit was pushed to the repository ${codecommit.ReferenceEvent.repositoryName} on branch ${codecommit.ReferenceEvent.referenceName}` @@ -83,6 +89,9 @@ onCommitRule.addTarget(new targets.SnsTopic(topic, { Or using an Object: ```ts +declare const onCommitRule: events.Rule; +declare const topic: sns.Topic; + onCommitRule.addTarget(new targets.SnsTopic(topic, { message: events.RuleTargetInput.fromObject( { @@ -99,10 +108,15 @@ Rate must be specified in minutes, hours or days. The following example runs a task every day at 4am: -```ts +```ts fixture=basic import { Rule, Schedule } from '@aws-cdk/aws-events'; import { EcsTask } from '@aws-cdk/aws-events-targets'; -... +import { Cluster, TaskDefinition } from '@aws-cdk/aws-ecs'; +import { Role } from '@aws-cdk/aws-iam'; + +declare const cluster: Cluster; +declare const taskDefinition: TaskDefinition; +declare const role: Role; const ecsTaskTarget = new EcsTask({ cluster, taskDefinition, role }); @@ -115,8 +129,12 @@ new Rule(this, 'ScheduleRule', { If you want to specify Fargate platform version, set `platformVersion` in EcsTask's props like the following example: ```ts +declare const cluster: ecs.Cluster; +declare const taskDefinition: ecs.TaskDefinition; +declare const role: iam.Role; + const platformVersion = ecs.FargatePlatformVersion.VERSION1_4; -const ecsTaskTarget = new EcsTask({ cluster, taskDefinition, role, platformVersion }); +const ecsTaskTarget = new targets.EcsTask({ cluster, taskDefinition, role, platformVersion }); ``` ## Event Targets @@ -140,7 +158,7 @@ The following targets are supported: It's possible to have the source of the event and a target in separate AWS accounts and regions: -```ts +```ts nofixture import { App, Stack } from '@aws-cdk/core'; import * as codebuild from '@aws-cdk/aws-codebuild'; import * as codecommit from '@aws-cdk/aws-codecommit'; @@ -148,9 +166,12 @@ import * as targets from '@aws-cdk/aws-events-targets'; const app = new App(); +const account1 = '11111111111'; +const account2 = '22222222222'; + const stack1 = new Stack(app, 'Stack1', { env: { account: account1, region: 'us-west-1' } }); const repo = new codecommit.Repository(stack1, 'Repository', { - // ... + repositoryName: 'myrepository', }); const stack2 = new Stack(app, 'Stack2', { env: { account: account2, region: 'us-east-1' } }); @@ -179,11 +200,7 @@ For more information, see the It is possible to archive all or some events sent to an event bus. It is then possible to [replay these events](https://aws.amazon.com/blogs/aws/new-archive-and-replay-events-with-amazon-eventbridge/). ```ts -import * as cdk from '@aws-cdk/core'; - -const stack = new stack(); - -const bus = new EventBus(stack, 'bus', { +const bus = new events.EventBus(this, 'bus', { eventBusName: 'MyCustomEventBus' }); @@ -191,9 +208,9 @@ bus.archive('MyArchive', { archiveName: 'MyCustomEventBusArchive', description: 'MyCustomerEventBus Archive', eventPattern: { - account: [stack.account], + account: [Stack.of(this).account], }, - retention: cdk.Duration.days(365), + retention: Duration.days(365), }); ``` @@ -205,7 +222,9 @@ or `EventBus.fromEventBusName` factory method. Then, you can use the `grantPutEventsTo` method to grant `event:PutEvents` to the eventBus. ```ts -const eventBus = EventBus.fromEventBusArn(this, 'ImportedEventBus', 'arn:aws:events:us-east-1:111111111:event-bus/my-event-bus'); +declare const lambdaFunction: lambda.Function; + +const eventBus = events.EventBus.fromEventBusArn(this, 'ImportedEventBus', 'arn:aws:events:us-east-1:111111111:event-bus/my-event-bus'); // now you can just call methods on the eventbus eventBus.grantPutEventsTo(lambdaFunction); diff --git a/packages/@aws-cdk/aws-events/rosetta/basic.ts-fixture b/packages/@aws-cdk/aws-events/rosetta/basic.ts-fixture new file mode 100644 index 0000000000000..0cc6d1104d521 --- /dev/null +++ b/packages/@aws-cdk/aws-events/rosetta/basic.ts-fixture @@ -0,0 +1,12 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { Stack, Duration } from '@aws-cdk/core'; + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} + diff --git a/packages/@aws-cdk/aws-events/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-events/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..7cb7c6f81aec6 --- /dev/null +++ b/packages/@aws-cdk/aws-events/rosetta/default.ts-fixture @@ -0,0 +1,20 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { Stack, Duration } from '@aws-cdk/core'; +import * as events from '@aws-cdk/aws-events'; +import * as targets from '@aws-cdk/aws-events-targets'; +import * as codecommit from '@aws-cdk/aws-codecommit'; +import * as codebuild from '@aws-cdk/aws-codebuild'; +import * as sns from '@aws-cdk/aws-sns'; +import * as ecs from '@aws-cdk/aws-ecs'; +import * as iam from '@aws-cdk/aws-iam'; +import * as lambda from '@aws-cdk/aws-lambda'; + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} + From 80369ff69e34a457cd7b27caf71d243d6579c727 Mon Sep 17 00:00:00 2001 From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com> Date: Wed, 27 Oct 2021 10:27:07 -0400 Subject: [PATCH 057/148] docs(logs): make examples compile (#17168) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-logs/README.md | 54 ++++++++++--------- .../aws-logs/rosetta/default.ts-fixture | 15 ++++++ 2 files changed, 44 insertions(+), 25 deletions(-) create mode 100644 packages/@aws-cdk/aws-logs/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-logs/README.md b/packages/@aws-cdk/aws-logs/README.md index 497526ca6ec60..1fcd323ca621c 100644 --- a/packages/@aws-cdk/aws-logs/README.md +++ b/packages/@aws-cdk/aws-logs/README.md @@ -61,7 +61,7 @@ Here's a simple example of creating an encrypted Log Group using a KMS CMK. ```ts import * as kms from '@aws-cdk/aws-kms'; -new LogGroup(this, 'LogGroup', { +new logs.LogGroup(this, 'LogGroup', { encryptionKey: new kms.Key(this, 'Key'), }); ``` @@ -83,13 +83,14 @@ Create a `SubscriptionFilter`, initialize it with an appropriate `Pattern` (see below) and supply the intended destination: ```ts -const fn = new lambda.Function(this, 'Lambda', { ... }); -const logGroup = new LogGroup(this, 'LogGroup', { ... }); +import * as destinations from '@aws-cdk/aws-logs-destinations'; +declare const fn: lambda.Function; +declare const logGroup: logs.LogGroup; -new SubscriptionFilter(this, 'Subscription', { - logGroup, - destination: new LogsDestinations.LambdaDestination(fn), - filterPattern: FilterPattern.allTerms("ERROR", "MainThread") +new logs.SubscriptionFilter(this, 'Subscription', { + logGroup, + destination: new destinations.LambdaDestination(fn), + filterPattern: logs.FilterPattern.allTerms("ERROR", "MainThread"), }); ``` @@ -114,6 +115,7 @@ A very simple MetricFilter can be created by using the `logGroup.extractMetric() helper function: ```ts +declare const logGroup: logs.LogGroup; logGroup.extractMetric('$.jsonField', 'Namespace', 'MetricName'); ``` @@ -127,11 +129,12 @@ You can expose a metric on a metric filter by calling the `MetricFilter.metric() This has a default of `statistic = 'avg'` if the statistic is not set in the `props`. ```ts -const mf = new MetricFilter(this, 'MetricFilter', { +declare const logGroup: logs.LogGroup; +const mf = new logs.MetricFilter(this, 'MetricFilter', { logGroup, metricNamespace: 'MyApp', metricName: 'Latency', - filterPattern: FilterPattern.exists('$.latency'), + filterPattern: logs.FilterPattern.exists('$.latency'), metricValue: '$.latency', }); @@ -139,7 +142,7 @@ const mf = new MetricFilter(this, 'MetricFilter', { const metric = mf.metric(); //you can use the metric to create a new alarm -new Alarm(this, 'alarm from metric filter', { +new cloudwatch.Alarm(this, 'alarm from metric filter', { metric, threshold: 100, evaluationPeriods: 2, @@ -175,7 +178,7 @@ line. (substrings) appear in the log event. * `FilterPattern.anyTerm(term, term, ...)`: matches if all of the given terms (substrings) appear in the log event. -* `FilterPattern.anyGroup([term, term, ...], [term, term, ...], ...)`: matches if +* `FilterPattern.anyTermGroup([term, term, ...], [term, term, ...], ...)`: matches if all of the terms in any of the groups (specified as arrays) matches. This is an OR match. @@ -184,14 +187,14 @@ Examples: ```ts // Search for lines that contain both "ERROR" and "MainThread" -const pattern1 = FilterPattern.allTerms('ERROR', 'MainThread'); +const pattern1 = logs.FilterPattern.allTerms('ERROR', 'MainThread'); // Search for lines that either contain both "ERROR" and "MainThread", or // both "WARN" and "Deadlock". -const pattern2 = FilterPattern.anyGroup( - ['ERROR', 'MainThread'], - ['WARN', 'Deadlock'], - ); +const pattern2 = logs.FilterPattern.anyTermGroup( + ['ERROR', 'MainThread'], + ['WARN', 'Deadlock'], +); ``` ## JSON Patterns @@ -235,12 +238,13 @@ Example: // Search for all events where the component field is equal to // "HttpServer" and either error is true or the latency is higher // than 1000. -const pattern = FilterPattern.all( - FilterPattern.stringValue('$.component', '=', 'HttpServer'), - FilterPattern.any( - FilterPattern.booleanValue('$.error', true), - FilterPattern.numberValue('$.latency', '>', 1000) - )); +const pattern = logs.FilterPattern.all( + logs.FilterPattern.stringValue('$.component', '=', 'HttpServer'), + logs.FilterPattern.any( + logs.FilterPattern.booleanValue('$.error', true), + logs.FilterPattern.numberValue('$.latency', '>', 1000), + ), +); ``` ## Space-delimited table patterns @@ -274,9 +278,9 @@ Example: ```ts // Search for all events where the component is "HttpServer" and the // result code is not equal to 200. -const pattern = FilterPattern.spaceDelimited('time', 'component', '...', 'result_code', 'latency') - .whereString('component', '=', 'HttpServer') - .whereNumber('result_code', '!=', 200); +const pattern = logs.FilterPattern.spaceDelimited('time', 'component', '...', 'result_code', 'latency') + .whereString('component', '=', 'HttpServer') + .whereNumber('result_code', '!=', 200); ``` ## Notes diff --git a/packages/@aws-cdk/aws-logs/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-logs/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..27c338ce30a32 --- /dev/null +++ b/packages/@aws-cdk/aws-logs/rosetta/default.ts-fixture @@ -0,0 +1,15 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { Stack } from '@aws-cdk/core'; +import * as logs from '@aws-cdk/aws-logs'; +import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; +import * as lambda from '@aws-cdk/aws-lambda'; + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} + From 312c2b614a73ea3176564a1de43a15f0992972d6 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 27 Oct 2021 17:19:55 +0200 Subject: [PATCH 058/148] docs: note that `App`s `outdir` property should not be used (#16670) If this property is passed it has to agree with the CLI's `--output` flag. If this property is not passed, it will default to the CLI's `--output` flag. In either case, it's better to just use `--output` and not pass this property at all; the property only has value inside tests. I tried to add validation (by using `Annotations.of(app).addWarning()` but they are useless anyway: in the CX protocol, metadata can only be attached to `StackArtifacts`, so metadata attached to the `App` will not be rendered. Adding a full framework feature to move metadata to a different place feels like too much risk and work for this small note, so turned it into a documentation fix. Fixes #3717. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/core/lib/app.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/@aws-cdk/core/lib/app.ts b/packages/@aws-cdk/core/lib/app.ts index 6719995d2b837..09ad1a3f81b79 100644 --- a/packages/@aws-cdk/core/lib/app.ts +++ b/packages/@aws-cdk/core/lib/app.ts @@ -25,6 +25,12 @@ export interface AppProps { /** * The output directory into which to emit synthesized artifacts. * + * You should never need to set this value. By default, the value you pass to + * the CLI's `--output` flag will be used, and if you change it to a different + * directory the CLI will fail to pick up the generated Cloud Assembly. + * + * This property is intended for internal and testing use. + * * @default - If this value is _not_ set, considers the environment variable `CDK_OUTDIR`. * If `CDK_OUTDIR` is not defined, uses a temp directory. */ From deccdebc43b4ff79c53ffa5a4171ef5a78f944c4 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 27 Oct 2021 18:12:33 +0200 Subject: [PATCH 059/148] chore(ec2): make examples (mostly) compile (#17183) There is one error left, jsii-rosetta doesn't support array indexing yet (`array[5]`). That's easy enough to add, so we're going to add that to Rosetta. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-ec2/README.md | 245 ++++++++++++------ .../@aws-cdk/aws-ec2/lib/security-group.ts | 2 +- packages/@aws-cdk/aws-ec2/lib/user-data.ts | 6 +- packages/@aws-cdk/aws-ec2/lib/volume.ts | 5 +- packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts | 2 + .../aws-ec2/rosetta/client-vpn.ts-fixture | 2 +- .../@aws-cdk/aws-ec2/rosetta/conns.ts-fixture | 26 -- .../aws-ec2/rosetta/default.ts-fixture | 8 +- 8 files changed, 177 insertions(+), 119 deletions(-) delete mode 100644 packages/@aws-cdk/aws-ec2/rosetta/conns.ts-fixture diff --git a/packages/@aws-cdk/aws-ec2/README.md b/packages/@aws-cdk/aws-ec2/README.md index f450e29dfcf20..ca30cc28fe9bd 100644 --- a/packages/@aws-cdk/aws-ec2/README.md +++ b/packages/@aws-cdk/aws-ec2/README.md @@ -93,17 +93,21 @@ must specify the environment where the stack will be deployed. You can gain full control over the availability zones selection strategy by overriding the Stack's [`get availabilityZones()`](https://github.com/aws/aws-cdk/blob/master/packages/@aws-cdk/core/lib/stack.ts) method: -```ts +```text +// This example is only available in TypeScript + class MyStack extends Stack { + constructor(scope: Construct, id: string, props?: StackProps) { + super(scope, id, props); + + // ... + } + get availabilityZones(): string[] { return ['us-west-2a', 'us-west-2b']; } - constructor(scope: Construct, id: string, props?: StackProps) { - super(scope, id, props); - ... - } } ``` @@ -121,11 +125,13 @@ The example below will place the endpoint into two AZs (`us-east-1a` and `us-eas in Isolated subnets: ```ts -new InterfaceVpcEndpoint(stack, 'VPC Endpoint', { +declare const vpc: ec2.Vpc; + +new ec2.InterfaceVpcEndpoint(this, 'VPC Endpoint', { vpc, - service: new InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443), + service: new ec2.InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443), subnets: { - subnetType: SubnetType.ISOLATED, + subnetType: ec2.SubnetType.ISOLATED, availabilityZones: ['us-east-1a', 'us-east-1c'] } }); @@ -134,9 +140,13 @@ new InterfaceVpcEndpoint(stack, 'VPC Endpoint', { You can also specify specific subnet objects for granular control: ```ts -new InterfaceVpcEndpoint(stack, 'VPC Endpoint', { +declare const vpc: ec2.Vpc; +declare const subnet1: ec2.Subnet; +declare const subnet2: ec2.Subnet; + +new ec2.InterfaceVpcEndpoint(this, 'VPC Endpoint', { vpc, - service: new InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443), + service: new ec2.InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443), subnets: { subnets: [subnet1, subnet2] } @@ -193,14 +203,16 @@ gets routed, pass `allowAllTraffic: false` and access the `NatInstanceProvider.connections` member after having passed it to the VPC: ```ts -const provider = NatProvider.instance({ - instanceType: /* ... */, +declare const instanceType: ec2.InstanceType; + +const provider = ec2.NatProvider.instance({ + instanceType, allowAllTraffic: false, }); -new Vpc(stack, 'TheVPC', { +new ec2.Vpc(this, 'TheVPC', { natGatewayProvider: provider, }); -provider.connections.allowFrom(Peer.ipv4('1.2.3.4/8'), Port.tcp(80)); +provider.connections.allowFrom(ec2.Peer.ipv4('1.2.3.4/8'), ec2.Port.tcp(80)); ``` ### Advanced Subnet Configuration @@ -284,6 +296,8 @@ DatabaseSubnet3 |`ISOLATED`|`10.0.6.32/28`|#3|Only routes within the VPC If you need access to the internet gateway, you can get its ID like so: ```ts +declare const vpc: ec2.Vpc; + const igwId = vpc.internetGatewayId; ``` @@ -305,18 +319,19 @@ Internet Gateway created for the public subnet - perhaps for routing a VPN connection - you can do so like this: ```ts -const vpc = ec2.Vpc(this, "VPC", { +const vpc = new ec2.Vpc(this, "VPC", { subnetConfiguration: [{ - subnetType: SubnetType.PUBLIC, + subnetType: ec2.SubnetType.PUBLIC, name: 'Public', },{ - subnetType: SubnetType.ISOLATED, + subnetType: ec2.SubnetType.ISOLATED, name: 'Isolated', }] -}) -(vpc.isolatedSubnets[0] as Subnet).addRoute("StaticRoute", { - routerId: vpc.internetGatewayId, - routerType: RouterType.GATEWAY, +}); + +(vpc.isolatedSubnets[0] as ec2.Subnet).addRoute("StaticRoute", { + routerId: vpc.internetGatewayId!, + routerType: ec2.RouterType.GATEWAY, destinationCidrBlock: "8.8.8.8/32", }) ``` @@ -412,7 +427,7 @@ following limitations: Using `Vpc.fromVpcAttributes()` looks like this: ```ts -const vpc = ec2.Vpc.fromVpcAttributes(stack, 'VPC', { +const vpc = ec2.Vpc.fromVpcAttributes(this, 'VPC', { vpcId: 'vpc-1234', availabilityZones: ['us-east-1a', 'us-east-1b'], @@ -423,7 +438,7 @@ const vpc = ec2.Vpc.fromVpcAttributes(stack, 'VPC', { privateSubnetIds: Fn.importListValue('PrivateSubnetIds', 2), // OR: split an imported string to a list of known length - isolatedSubnetIds: Fn.split(',', ssm.StringParameter.valueForStringParameter(stack, `MyParameter`), 2), + isolatedSubnetIds: Fn.split(',', ssm.StringParameter.valueForStringParameter(this, `MyParameter`), 2), }); ``` @@ -457,7 +472,11 @@ have security groups, you have to add an **Egress** rule to one Security Group, and an **Ingress** rule to the other. The connections object will automatically take care of this for you: -```ts fixture=conns +```ts +declare const loadBalancer: elbv2.ApplicationLoadBalancer; +declare const appFleet: autoscaling.AutoScalingGroup; +declare const dbFleet: autoscaling.AutoScalingGroup; + // Allow connections from anywhere loadBalancer.connections.allowFromAnyIpv4(ec2.Port.tcp(443), 'Allow inbound HTTPS'); @@ -472,7 +491,10 @@ appFleet.connections.allowTo(dbFleet, ec2.Port.tcp(443), 'App can call database' There are various classes that implement the connection peer part: -```ts fixture=conns +```ts +declare const appFleet: autoscaling.AutoScalingGroup; +declare const dbFleet: autoscaling.AutoScalingGroup; + // Simple connection peers let peer = ec2.Peer.ipv4('10.0.0.0/16'); peer = ec2.Peer.anyIpv4(); @@ -484,7 +506,11 @@ appFleet.connections.allowTo(peer, ec2.Port.tcp(443), 'Allow outbound HTTPS'); Any object that has a security group can itself be used as a connection peer: -```ts fixture=conns +```ts +declare const fleet1: autoscaling.AutoScalingGroup; +declare const fleet2: autoscaling.AutoScalingGroup; +declare const appFleet: autoscaling.AutoScalingGroup; + // These automatically create appropriate ingress and egress rules in both security groups fleet1.connections.allowTo(fleet2, ec2.Port.tcp(80), 'Allow between fleets'); @@ -518,7 +544,11 @@ If the object you're calling the peering method on has a default port associated For example: -```ts fixture=conns +```ts +declare const listener: elbv2.ApplicationListener; +declare const appFleet: autoscaling.AutoScalingGroup; +declare const rdsDatabase: rds.DatabaseCluster; + // Port implicit in listener listener.connections.allowDefaultPortFromAnyIpv4('Allow public'); @@ -637,9 +667,11 @@ By default, CDK will place a VPC endpoint in one subnet per AZ. If you wish to o use the `subnets` parameter as follows: ```ts -new InterfaceVpcEndpoint(stack, 'VPC Endpoint', { +declare const vpc: ec2.Vpc; + +new ec2.InterfaceVpcEndpoint(this, 'VPC Endpoint', { vpc, - service: new InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443), + service: new ec2.InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443), // Choose which availability zones to place the VPC endpoint in, based on // available AZs subnets: { @@ -654,9 +686,11 @@ AZs an endpoint service is available in, and will ensure the VPC endpoint is not These AZs will be stored in cdk.context.json. ```ts -new InterfaceVpcEndpoint(stack, 'VPC Endpoint', { +declare const vpc: ec2.Vpc; + +new ec2.InterfaceVpcEndpoint(this, 'VPC Endpoint', { vpc, - service: new InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443), + service: new ec2.InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443), // Choose which availability zones to place the VPC endpoint in, based on // available AZs lookupSupportedAzs: true @@ -668,7 +702,12 @@ create VPC endpoints without having to configure name, ports, etc. For example, use in your VPC: ``` ts -new InterfaceVpcEndpoint(stack, 'VPC Endpoint', { vpc, service: InterfaceVpcEndpointAwsService.KEYSPACES }); +declare const vpc: ec2.Vpc; + +new ec2.InterfaceVpcEndpoint(this, 'VPC Endpoint', { + vpc, + service: ec2.InterfaceVpcEndpointAwsService.KEYSPACES, +}); ``` #### Security groups for interface VPC endpoints @@ -678,7 +717,9 @@ automatically allowed from the VPC CIDR. Use the `connections` object to allow traffic to flow to the endpoint: -```ts fixture=conns +```ts +declare const myEndpoint: ec2.InterfaceVpcEndpoint; + myEndpoint.connections.allowDefaultPortFromAnyIpv4(); ``` @@ -689,10 +730,13 @@ Alternatively, existing security groups can be used by specifying the `securityG A VPC endpoint service enables you to expose a Network Load Balancer(s) as a provider service to consumers, who connect to your service over a VPC endpoint. You can restrict access to your service via allowed principals (anything that extends ArnPrincipal), and require that new connections be manually accepted. ```ts -new VpcEndpointService(this, 'EndpointService', { +declare const networkLoadBalancer1: elbv2.NetworkLoadBalancer; +declare const networkLoadBalancer2: elbv2.NetworkLoadBalancer; + +new ec2.VpcEndpointService(this, 'EndpointService', { vpcEndpointServiceLoadBalancers: [networkLoadBalancer1, networkLoadBalancer2], acceptanceRequired: true, - allowedPrincipals: [new ArnPrincipal('arn:aws:iam::123456789012:root')] + allowedPrincipals: [new iam.ArnPrincipal('arn:aws:iam::123456789012:root')] }); ``` @@ -700,9 +744,11 @@ Endpoint services support private DNS, which makes it easier for clients to conn You can enable private DNS on an endpoint service like so: ```ts -import { VpcEndpointServiceDomainName } from '@aws-cdk/aws-route53'; +import { HostedZone, VpcEndpointServiceDomainName } from '@aws-cdk/aws-route53'; +declare const zone: HostedZone; +declare const vpces: ec2.VpcEndpointService; -new VpcEndpointServiceDomainName(stack, 'EndpointDomain', { +new VpcEndpointServiceDomainName(this, 'EndpointDomain', { endpointService: vpces, domainName: 'my-stuff.aws-cdk.dev', publicHostedZone: zone, @@ -796,7 +842,15 @@ For the full set of capabilities of this system, see the documentation for Here is an example of applying some configuration to an instance: ```ts +declare const vpc: ec2.Vpc; +declare const instanceType: ec2.InstanceType; +declare const machineImage: ec2.IMachineImage; + new ec2.Instance(this, 'Instance', { + vpc, + instanceType, + machineImage, + // Showing the most complex setup, if you have simpler requirements // you can use `CloudFormationInit.fromElements()`. init: ec2.CloudFormationInit.fromConfigSets({ @@ -812,9 +866,9 @@ new ec2.Instance(this, 'Instance', { config: new ec2.InitConfig([ // Create a JSON file from tokens (can also create other files) ec2.InitFile.fromObject('/etc/stack.json', { - stackId: stack.stackId, - stackName: stack.stackName, - region: stack.region, + stackId: Stack.of(this).stackId, + stackName: Stack.of(this).stackName, + region: Stack.of(this).region, }), // Create a group and user @@ -834,10 +888,10 @@ new ec2.Instance(this, 'Instance', { timeout: Duration.minutes(30), // Optional, whether to include the --url argument when running cfn-init and cfn-signal commands (false by default) - includeUrl: true + includeUrl: true, // Optional, whether to include the --role argument when running cfn-init and cfn-signal commands (false by default) - includeRole: true + includeRole: true, }, }); ``` @@ -849,11 +903,13 @@ config writes a config file for nginx, extracts an archive to the root directory restarts nginx so that it picks up the new config and files: ```ts +declare const myBucket: s3.Bucket; + const handle = new ec2.InitServiceRestartHandle(); ec2.CloudFormationInit.fromElements( ec2.InitFile.fromString('/etc/nginx/nginx.conf', '...', { serviceRestartHandles: [handle] }), - ec2.InitSource.fromBucket('/var/www/html', myBucket, 'html.zip', { serviceRestartHandles: [handle] }), + ec2.InitSource.fromS3Object('/var/www/html', myBucket, 'html.zip', { serviceRestartHandles: [handle] }), ec2.InitService.enable('nginx', { serviceRestartHandle: handle, }) @@ -887,16 +943,16 @@ with the command `aws ec2-instance-connect send-ssh-public-key` to provide your EBS volume for the bastion host can be encrypted like: -```ts - const host = new ec2.BastionHostLinux(stack, 'BastionHost', { - vpc, - blockDevices: [{ - deviceName: 'EBSBastionHost', - volume: BlockDeviceVolume.ebs(10, { - encrypted: true, - }), - }], - }); +```ts fixture=with-vpc +const host = new ec2.BastionHostLinux(this, 'BastionHost', { + vpc, + blockDevices: [{ + deviceName: 'EBSBastionHost', + volume: ec2.BlockDeviceVolume.ebs(10, { + encrypted: true, + }), + }], +}); ``` ### Block Devices @@ -906,8 +962,17 @@ root device (`/dev/sda1`) size to 50 GiB, and adds another EBS-backed device map size: ```ts +declare const vpc: ec2.Vpc; +declare const instanceType: ec2.InstanceType; +declare const machineImage: ec2.IMachineImage; + new ec2.Instance(this, 'Instance', { + vpc, + instanceType, + machineImage, + // ... + blockDevices: [ { deviceName: '/dev/sda1', @@ -931,15 +996,12 @@ A notable restriction is that a Volume can only be attached to instances in the The following demonstrates how to create a 500 GiB encrypted Volume in the `us-west-2a` availability zone, and give a role the ability to attach that Volume to a specific instance: ```ts -const instance = new ec2.Instance(this, 'Instance', { - // ... -}); -const role = new iam.Role(stack, 'SomeRole', { - assumedBy: new iam.AccountRootPrincipal(), -}); +declare const instance: ec2.Instance; +declare const role: iam.Role; + const volume = new ec2.Volume(this, 'Volume', { availabilityZone: 'us-west-2a', - size: cdk.Size.gibibytes(500), + size: Size.gibibytes(500), encrypted: true, }); @@ -952,12 +1014,8 @@ If you need to grant an instance the ability to attach/detach an EBS volume to/f will lead to an unresolvable circular reference between the instance role and the instance. In this case, use `grantAttachVolumeByResourceTag` and `grantDetachVolumeByResourceTag` as follows: ```ts -const instance = new ec2.Instance(this, 'Instance', { - // ... -}); -const volume = new ec2.Volume(this, 'Volume', { - // ... -}); +declare const instance: ec2.Instance; +declare const volume: ec2.Volume; const attachGrant = volume.grantAttachVolumeByResourceTag(instance.grantPrincipal, [instance]); const detachGrant = volume.grantDetachVolumeByResourceTag(instance.grantPrincipal, [instance]); @@ -973,12 +1031,9 @@ to attach and detach your Volumes to/from instances, and how to format them for The following is a sample skeleton of EC2 UserData that can be used to attach a Volume to the Linux instance that it is running on: ```ts -const volume = new ec2.Volume(this, 'Volume', { - // ... -}); -const instance = new ec2.Instance(this, 'Instance', { - // ... -}); +declare const instance: ec2.Instance; +declare const volume: ec2.Volume; + volume.grantAttachVolumeByResourceTag(instance.grantPrincipal, [instance]); const targetDevice = '/dev/xvdz'; instance.userData.addCommands( @@ -1005,9 +1060,18 @@ To do this for a single `Instance`, you can use the `requireImdsv2` property. The example below demonstrates IMDSv2 being required on a single `Instance`: ```ts +declare const vpc: ec2.Vpc; +declare const instanceType: ec2.InstanceType; +declare const machineImage: ec2.IMachineImage; + new ec2.Instance(this, 'Instance', { - requireImdsv2: true, + vpc, + instanceType, + machineImage, + // ... + + requireImdsv2: true, }); ``` @@ -1018,7 +1082,7 @@ The following example demonstrates how to use the `InstanceRequireImdsv2Aspect` ```ts const aspect = new ec2.InstanceRequireImdsv2Aspect(); -Aspects.of(stack).add(aspect); +Aspects.of(this).add(aspect); ``` ## VPC Flow Logs @@ -1030,6 +1094,8 @@ By default a flow log will be created with CloudWatch Logs as the destination. You can create a flow log like this: ```ts +declare const vpc: ec2.Vpc; + new ec2.FlowLog(this, 'FlowLog', { resourceType: ec2.FlowLogResourceType.fromVpc(vpc) }) @@ -1066,6 +1132,8 @@ If you want to customize any of the destination resources you can provide your o *CloudWatch Logs* ```ts +declare const vpc: ec2.Vpc; + const logGroup = new logs.LogGroup(this, 'MyCustomLogGroup'); const role = new iam.Role(this, 'MyCustomRole', { @@ -1081,6 +1149,7 @@ new ec2.FlowLog(this, 'FlowLog', { *S3* ```ts +declare const vpc: ec2.Vpc; const bucket = new s3.Bucket(this, 'MyCustomBucket'); @@ -1103,10 +1172,14 @@ User data enables you to run a script when your instances start up. In order to A user data could be configured to run a script found in an asset through the following: ```ts -const asset = new Asset(this, 'Asset', {path: path.join(__dirname, 'configure.sh')}); -const instance = new ec2.Instance(this, 'Instance', { - // ... - }); +import { Asset } from '@aws-cdk/aws-s3-assets'; + +declare const instance: ec2.Instance; + +const asset = new Asset(this, 'Asset', { + path: './configure.sh' +}); + const localPath = instance.userData.addS3DownloadCommand({ bucket:asset.bucket, bucketKey:asset.s3ObjectKey, @@ -1116,7 +1189,7 @@ instance.userData.addExecuteFileCommand({ filePath:localPath, arguments: '--verbose -y' }); -asset.grantRead( instance.role ); +asset.grantRead(instance.role); ``` ### Multipart user data @@ -1152,7 +1225,7 @@ multipartUserData.addPart(ec2.MultipartBody.fromUserData(bootHookConf, 'text/clo // Execute the rest of setup multipartUserData.addPart(ec2.MultipartBody.fromUserData(setupCommands)); -new ec2.LaunchTemplate(stack, '', { +new ec2.LaunchTemplate(this, '', { userData: multipartUserData, blockDevices: [ // Block device configuration rest @@ -1172,7 +1245,7 @@ method on `MultipartUserData` with the `makeDefault` argument set to `true`: ```ts const multipartUserData = new ec2.MultipartUserData(); const commandsUserData = ec2.UserData.forLinux(); -multipartUserData.addUserDataPart(commandsUserData, MultipartBody.SHELL_SCRIPT, true); +multipartUserData.addUserDataPart(commandsUserData, ec2.MultipartBody.SHELL_SCRIPT, true); // Adding commands to the multipartUserData adds them to commandsUserData, and vice-versa. multipartUserData.addCommands('touch /root/multi.txt'); @@ -1193,14 +1266,14 @@ Importing an existing subnet looks like this: ```ts // Supply all properties -const subnet = Subnet.fromSubnetAttributes(this, 'SubnetFromAttributes', { +const subnet1 = ec2.Subnet.fromSubnetAttributes(this, 'SubnetFromAttributes', { subnetId: 's-1234', availabilityZone: 'pub-az-4465', routeTableId: 'rt-145' }); // Supply only subnet id -const subnet = Subnet.fromSubnetId(this, 'SubnetFromId', 's-1234'); +const subnet2 = ec2.Subnet.fromSubnetId(this, 'SubnetFromId', 's-1234'); ``` ## Launch Templates @@ -1214,10 +1287,10 @@ an instance. For information on Launch Templates please see the The following demonstrates how to create a launch template with an Amazon Machine Image, and security group. ```ts -const vpc = new ec2.Vpc(...); -// ... +declare const vpc: ec2.Vpc; + const template = new ec2.LaunchTemplate(this, 'LaunchTemplate', { - machineImage: new ec2.AmazonMachineImage(), + machineImage: ec2.MachineImage.latestAmazonLinux(), securityGroup: new ec2.SecurityGroup(this, 'LaunchTemplateSG', { vpc: vpc, }), diff --git a/packages/@aws-cdk/aws-ec2/lib/security-group.ts b/packages/@aws-cdk/aws-ec2/lib/security-group.ts index 2c01da7aef943..54695f2d17b71 100644 --- a/packages/@aws-cdk/aws-ec2/lib/security-group.ts +++ b/packages/@aws-cdk/aws-ec2/lib/security-group.ts @@ -308,7 +308,7 @@ export interface SecurityGroupImportOptions { * you would import it like this: * * ```ts - * const securityGroup = SecurityGroup.fromSecurityGroupId(this, 'SG', 'sg-12345', { + * const securityGroup = ec2.SecurityGroup.fromSecurityGroupId(this, 'SG', 'sg-12345', { * mutable: false * }); * ``` diff --git a/packages/@aws-cdk/aws-ec2/lib/user-data.ts b/packages/@aws-cdk/aws-ec2/lib/user-data.ts index 14b94d2d2ad4a..1e92eb888e6f8 100644 --- a/packages/@aws-cdk/aws-ec2/lib/user-data.ts +++ b/packages/@aws-cdk/aws-ec2/lib/user-data.ts @@ -489,7 +489,11 @@ export class MultipartUserData extends UserData { * If `makeDefault` is false, then this is the same as calling: * * ```ts - * multiPart.addPart(MultipartBody.fromUserData(userData, contentType)); + * declare const multiPart: ec2.MultipartUserData; + * declare const userData: ec2.UserData; + * declare const contentType: string; + * + * multiPart.addPart(ec2.MultipartBody.fromUserData(userData, contentType)); * ``` * * An undefined `makeDefault` defaults to either: diff --git a/packages/@aws-cdk/aws-ec2/lib/volume.ts b/packages/@aws-cdk/aws-ec2/lib/volume.ts index a25ca459b7c63..87e92b3f5006a 100644 --- a/packages/@aws-cdk/aws-ec2/lib/volume.ts +++ b/packages/@aws-cdk/aws-ec2/lib/volume.ts @@ -19,7 +19,7 @@ export interface BlockDevice { /** * The device name exposed to the EC2 instance * - * @example '/dev/sdh', 'xvdh' + * For example, a value like `/dev/sdh`, `xvdh`. * * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/device_naming.html */ @@ -28,8 +28,7 @@ export interface BlockDevice { /** * Defines the block device volume, to be either an Amazon EBS volume or an ephemeral instance store volume * - * @example BlockDeviceVolume.ebs(15), BlockDeviceVolume.ephemeral(0) - * + * For example, a value like `BlockDeviceVolume.ebs(15)`, `BlockDeviceVolume.ephemeral(0)`. */ readonly volume: BlockDeviceVolume; diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts index de64072868391..3282da410d09a 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts @@ -121,6 +121,8 @@ export interface GatewayVpcEndpointOptions { * @default - All subnets in the VPC * @example * + * declare const vpc: ec2.Vpc; + * * vpc.addGatewayEndpoint('DynamoDbEndpoint', { * service: ec2.GatewayVpcEndpointAwsService.DYNAMODB, * // Add only to ISOLATED subnets diff --git a/packages/@aws-cdk/aws-ec2/rosetta/client-vpn.ts-fixture b/packages/@aws-cdk/aws-ec2/rosetta/client-vpn.ts-fixture index 4886d590211df..34c83a31ced35 100644 --- a/packages/@aws-cdk/aws-ec2/rosetta/client-vpn.ts-fixture +++ b/packages/@aws-cdk/aws-ec2/rosetta/client-vpn.ts-fixture @@ -9,7 +9,7 @@ class Fixture extends Stack { const vpc = new ec2.Vpc(this, 'VPC'); const samlProvider = new iam.SamlProvider(this, 'Provider', { - metadataDocument: SamlMetadataDocument.fromXml('xml'), + metadataDocument: iam.SamlMetadataDocument.fromXml('xml'), }) /// here diff --git a/packages/@aws-cdk/aws-ec2/rosetta/conns.ts-fixture b/packages/@aws-cdk/aws-ec2/rosetta/conns.ts-fixture deleted file mode 100644 index f29d9a1816a6e..0000000000000 --- a/packages/@aws-cdk/aws-ec2/rosetta/conns.ts-fixture +++ /dev/null @@ -1,26 +0,0 @@ -// Fixture with fake connectables -import { Construct, Stack } from '@aws-cdk/core'; -import ec2 = require('@aws-cdk/aws-ec2'); - -class Fixture extends Stack { - constructor(scope: Construct, id: string) { - super(scope, id); - - const vpc = new ec2.Vpc(this, 'VPC'); - - const loadBalancer = new FakeConnectable(); - const appFleet = new FakeConnectable(); - const dbFleet = new FakeConnectable(); - const rdsDatabase = new FakeConnectable(); - const fleet1 = new FakeConnectable(); - const fleet2 = new FakeConnectable(); - const listener = new FakeConnectable(); - const myEndpoint = new FakeConnectable(); - - /// here - } -} - -class FakeConnectable implements ec2.IConnectable { - public readonly connections = new ec2.Connections({ securityGroups: [] }); -} diff --git a/packages/@aws-cdk/aws-ec2/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-ec2/rosetta/default.ts-fixture index d4ecd7e92a6f1..df2d29f125b46 100644 --- a/packages/@aws-cdk/aws-ec2/rosetta/default.ts-fixture +++ b/packages/@aws-cdk/aws-ec2/rosetta/default.ts-fixture @@ -1,7 +1,13 @@ // Fixture with packages imported, but nothing else -import { Construct, Stack } from '@aws-cdk/core'; +import { Aspects, Construct, Duration, Fn, Size, Stack, StackProps } from '@aws-cdk/core'; import ec2 = require('@aws-cdk/aws-ec2'); +import s3 = require('@aws-cdk/aws-s3'); import iam = require('@aws-cdk/aws-iam'); +import logs = require('@aws-cdk/aws-logs'); +import ssm = require('@aws-cdk/aws-ssm'); +import autoscaling = require('@aws-cdk/aws-autoscaling'); +import elbv2 = require('@aws-cdk/aws-elasticloadbalancingv2'); +import rds = require('@aws-cdk/aws-rds'); class Fixture extends Stack { constructor(scope: Construct, id: string) { From 6aa86d590d5e06c64677161d970eb39a77f8fd99 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 27 Oct 2021 19:04:44 +0200 Subject: [PATCH 060/148] chore(elbv2): make examples compile (#17162) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-elasticloadbalancingv2/README.md | 131 +++++++++++------- .../rosetta/default.ts-fixture | 17 +++ 2 files changed, 100 insertions(+), 48 deletions(-) create mode 100644 packages/@aws-cdk/aws-elasticloadbalancingv2/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/README.md b/packages/@aws-cdk/aws-elasticloadbalancingv2/README.md index f3d23b5e827cf..34755353fb202 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/README.md +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/README.md @@ -26,13 +26,10 @@ You define an application load balancer by creating an instance of and adding Targets to the Listener: ```ts -import * as ec2 from '@aws-cdk/aws-ec2'; -import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2'; import { AutoScalingGroup } from '@aws-cdk/aws-autoscaling'; +declare const asg: AutoScalingGroup; -// ... - -const vpc = new ec2.Vpc(...); +declare const vpc: ec2.Vpc; // Create the load balancer in a VPC. 'internetFacing' is 'false' // by default, which creates an internal load balancer. @@ -54,7 +51,6 @@ const listener = lb.addListener('Listener', { // Create an AutoScaling group and add it as a load balancing // target to the listener. -const asg = new AutoScalingGroup(...); listener.addTargets('ApplicationFleet', { port: 8080, targets: [asg] @@ -68,14 +64,16 @@ One (or more) security groups can be associated with the load balancer; if a security group isn't provided, one will be automatically created. ```ts -const securityGroup1 = new ec2.SecurityGroup(stack, 'SecurityGroup1', { vpc }); +declare const vpc: ec2.Vpc; + +const securityGroup1 = new ec2.SecurityGroup(this, 'SecurityGroup1', { vpc }); const lb = new elbv2.ApplicationLoadBalancer(this, 'LB', { vpc, internetFacing: true, securityGroup: securityGroup1, // Optional - will be automatically created otherwise }); -const securityGroup2 = new ec2.SecurityGroup(stack, 'SecurityGroup2', { vpc }); +const securityGroup2 = new ec2.SecurityGroup(this, 'SecurityGroup2', { vpc }); lb.addSecurityGroup(securityGroup2); ``` @@ -87,11 +85,14 @@ AutoScalingGroup only if the requested host in the request is either for `example.com/ok` or `example.com/path`: ```ts +declare const listener: elbv2.ApplicationListener; +declare const asg: autoscaling.AutoScalingGroup; + listener.addTargets('Example.Com Fleet', { priority: 10, conditions: [ - ListenerCondition.hostHeaders(['example.com']), - ListenerCondition.pathPatterns(['/ok', '/path']), + elbv2.ListenerCondition.hostHeaders(['example.com']), + elbv2.ListenerCondition.pathPatterns(['/ok', '/path']), ], port: 8080, targets: [asg] @@ -149,12 +150,14 @@ Balancer that the other two convenience methods don't: Here's an example of serving a fixed response at the `/ok` URL: ```ts +declare const listener: elbv2.ApplicationListener; + listener.addAction('Fixed', { priority: 10, conditions: [ - ListenerCondition.pathPatterns(['/ok']), + elbv2.ListenerCondition.pathPatterns(['/ok']), ], - action: ListenerAction.fixedResponse(200, { + action: elbv2.ListenerAction.fixedResponse(200, { contentType: elbv2.ContentType.TEXT_PLAIN, messageBody: 'OK', }) @@ -164,12 +167,21 @@ listener.addAction('Fixed', { Here's an example of using OIDC authentication before forwarding to a TargetGroup: ```ts +declare const listener: elbv2.ApplicationListener; +declare const myTargetGroup: elbv2.ApplicationTargetGroup; + listener.addAction('DefaultAction', { - action: ListenerAction.authenticateOidc({ + action: elbv2.ListenerAction.authenticateOidc({ authorizationEndpoint: 'https://example.com/openid', // Other OIDC properties here - // ... - next: ListenerAction.forward([myTargetGroup]), + clientId: '...', + clientSecret: SecretValue.secretsManager('...'), + issuer: '...', + tokenEndpoint: '...', + userInfoEndpoint: '...', + + // Next + next: elbv2.ListenerAction.forward([myTargetGroup]), }), }); ``` @@ -177,6 +189,8 @@ listener.addAction('DefaultAction', { If you just want to redirect all incoming traffic on one port to another port, you can use the following code: ```ts +declare const lb: elbv2.ApplicationLoadBalancer; + lb.addRedirect({ sourceProtocol: elbv2.ApplicationProtocol.HTTPS, sourcePort: 8443, @@ -196,9 +210,8 @@ Network Load Balancers are defined in a similar way to Application Load Balancers: ```ts -import * as ec2 from '@aws-cdk/aws-ec2'; -import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2'; -import * as autoscaling from '@aws-cdk/aws-autoscaling'; +declare const vpc: ec2.Vpc; +declare const asg: autoscaling.AutoScalingGroup; // Create the load balancer in a VPC. 'internetFacing' is 'false' // by default, which creates an internal load balancer. @@ -243,6 +256,10 @@ and add it to the listener by calling `addTargetGroups` instead of `addTargets`. `addTargets()` will always return the Target Group it just created for you: ```ts +declare const listener: elbv2.NetworkListener; +declare const asg1: autoscaling.AutoScalingGroup; +declare const asg2: autoscaling.AutoScalingGroup; + const group = listener.addTargets('AppFleet', { port: 443, targets: [asg1], @@ -258,19 +275,21 @@ By default, an Application Load Balancer routes each request independently to a Application Load Balancers support both duration-based cookies (`lb_cookie`) and application-based cookies (`app_cookie`). The key to managing sticky sessions is determining how long your load balancer should consistently route the user's request to the same target. Sticky sessions are enabled at the target group level. You can use a combination of duration-based stickiness, application-based stickiness, and no stickiness across all of your target groups. ```ts +declare const vpc: ec2.Vpc; + // Target group with duration-based stickiness with load-balancer generated cookie -const tg1 = new elbv2.ApplicationTargetGroup(stack, 'TG1', { +const tg1 = new elbv2.ApplicationTargetGroup(this, 'TG1', { targetType: elbv2.TargetType.INSTANCE, port: 80, - stickinessCookieDuration: cdk.Duration.minutes(5), + stickinessCookieDuration: Duration.minutes(5), vpc, }); // Target group with application-based stickiness -const tg2 = new elbv2.ApplicationTargetGroup(stack, 'TG2', { +const tg2 = new elbv2.ApplicationTargetGroup(this, 'TG2', { targetType: elbv2.TargetType.INSTANCE, port: 80, - stickinessCookieDuration: cdk.Duration.minutes(5), + stickinessCookieDuration: Duration.minutes(5), stickinessCookieName: 'MyDeliciousCookie', vpc, }); @@ -283,7 +302,9 @@ For more information see: https://docs.aws.amazon.com/elasticloadbalancing/lates By default, Application Load Balancers send requests to targets using HTTP/1.1. You can use the [protocol version](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html#target-group-protocol-version) to send requests to targets using HTTP/2 or gRPC. ```ts -const tg = new elbv2.ApplicationTargetGroup(stack, 'TG', { +declare const vpc: ec2.Vpc; + +const tg = new elbv2.ApplicationTargetGroup(this, 'TG', { targetType: elbv2.TargetType.IP, port: 50051, protocol: elbv2.ApplicationProtocol.HTTP, @@ -303,11 +324,10 @@ To use a Lambda Function as a target, use the integration class in the ```ts import * as lambda from '@aws-cdk/aws-lambda'; -import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2'; import * as targets from '@aws-cdk/aws-elasticloadbalancingv2-targets'; -const lambdaFunction = new lambda.Function(...); -const lb = new elbv2.ApplicationLoadBalancer(...); +declare const lambdaFunction: lambda.Function; +declare const lb: elbv2.ApplicationLoadBalancer; const listener = lb.addListener('Listener', { port: 80 }); listener.addTargets('Targets', { @@ -329,11 +349,12 @@ To use a single application load balancer as a target for the network load balan `@aws-cdk/aws-elasticloadbalancingv2-targets` package: ```ts -import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2'; import * as targets from '@aws-cdk/aws-elasticloadbalancingv2-targets'; import * as ecs from '@aws-cdk/aws-ecs'; import * as patterns from '@aws-cdk/aws-ecs-patterns'; +declare const vpc: ec2.Vpc; + const task = new ecs.FargateTaskDefinition(this, 'Task', { cpu: 256, memoryLimitMiB: 512 }); task.addContainer('nginx', { image: ecs.ContainerImage.fromRegistry('public.ecr.aws/nginx/nginx:latest'), @@ -369,12 +390,15 @@ Only the network load balancer is allowed to add the application load balancer a Health checks are configured upon creation of a target group: ```ts +declare const listener: elbv2.ApplicationListener; +declare const asg: autoscaling.AutoScalingGroup; + listener.addTargets('AppFleet', { port: 8080, targets: [asg], healthCheck: { path: '/ping', - interval: cdk.Duration.minutes(1), + interval: Duration.minutes(1), } }); ``` @@ -388,15 +412,19 @@ you're routing traffic to, the security group already allows the traffic. If not, you will have to configure the security groups appropriately: ```ts +declare const lb: elbv2.ApplicationLoadBalancer; +declare const listener: elbv2.ApplicationListener; +declare const asg: autoscaling.AutoScalingGroup; + listener.addTargets('AppFleet', { port: 8080, targets: [asg], healthCheck: { - port: 8088, + port: '8088', } }); -listener.connections.allowFrom(lb, ec2.Port.tcp(8088)); +asg.connections.allowFrom(lb, ec2.Port.tcp(8088)); ``` ## Using a Load Balancer from a different Stack @@ -424,12 +452,15 @@ call functions on the load balancer and should return metadata about the load balancing target: ```ts -public attachToApplicationTargetGroup(targetGroup: ApplicationTargetGroup): LoadBalancerTargetProps { - targetGroup.registerConnectable(...); - return { - targetType: TargetType.Instance | TargetType.Ip - targetJson: { id: ..., port: ... }, - }; +class MyTarget implements elbv2.IApplicationLoadBalancerTarget { + public attachToApplicationTargetGroup(targetGroup: elbv2.ApplicationTargetGroup): elbv2.LoadBalancerTargetProps { + // If we need to add security group rules + // targetGroup.registerConnectable(...); + return { + targetType: elbv2.TargetType.IP, + targetJson: { id: '1.2.3.4', port: 8080 }, + }; + } } ``` @@ -445,12 +476,16 @@ group rules. If your load balancer target requires that the TargetGroup has been associated with a LoadBalancer before registration can happen (such as is the case for ECS Services for example), take a resource dependency on -`targetGroup.loadBalancerDependency()` as follows: +`targetGroup.loadBalancerAttached` as follows: ```ts +declare const resource: Resource; +declare const targetGroup: elbv2.ApplicationTargetGroup; + // Make sure that the listener has been created, and so the TargetGroup // has been associated with the LoadBalancer, before 'resource' is created. -resourced.addDependency(targetGroup.loadBalancerDependency()); + +Node.of(resource).addDependency(targetGroup.loadBalancerAttached); ``` ## Looking up Load Balancers and Listeners @@ -478,15 +513,15 @@ provide more specific criteria. **Look up a Application Load Balancer by ARN** ```ts -const loadBalancer = ApplicationLoadBalancer.fromLookup(stack, 'ALB', { - loadBalancerArn: YOUR_ALB_ARN, +const loadBalancer = elbv2.ApplicationLoadBalancer.fromLookup(this, 'ALB', { + loadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-2:123456789012:loadbalancer/app/my-load-balancer/1234567890123456', }); ``` **Look up an Application Load Balancer by tags** ```ts -const loadBalancer = ApplicationLoadBalancer.fromLookup(stack, 'ALB', { +const loadBalancer = elbv2.ApplicationLoadBalancer.fromLookup(this, 'ALB', { loadBalancerTags: { // Finds a load balancer matching all tags. some: 'tag', @@ -512,9 +547,9 @@ criteria. **Look up a Listener by associated Load Balancer, Port, and Protocol** ```ts -const listener = ApplicationListener.fromLookup(stack, 'ALBListener', { - loadBalancerArn: YOUR_ALB_ARN, - listenerProtocol: ApplicationProtocol.HTTPS, +const listener = elbv2.ApplicationListener.fromLookup(this, 'ALBListener', { + loadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-2:123456789012:loadbalancer/app/my-load-balancer/1234567890123456', + listenerProtocol: elbv2.ApplicationProtocol.HTTPS, listenerPort: 443, }); ``` @@ -522,11 +557,11 @@ const listener = ApplicationListener.fromLookup(stack, 'ALBListener', { **Look up a Listener by associated Load Balancer Tag, Port, and Protocol** ```ts -const listener = ApplicationListener.fromLookup(stack, 'ALBListener', { +const listener = elbv2.ApplicationListener.fromLookup(this, 'ALBListener', { loadBalancerTags: { Cluster: 'MyClusterName', }, - listenerProtocol: ApplicationProtocol.HTTPS, + listenerProtocol: elbv2.ApplicationProtocol.HTTPS, listenerPort: 443, }); ``` @@ -534,11 +569,11 @@ const listener = ApplicationListener.fromLookup(stack, 'ALBListener', { **Look up a Network Listener by associated Load Balancer Tag, Port, and Protocol** ```ts -const listener = NetworkListener.fromLookup(stack, 'ALBListener', { +const listener = elbv2.NetworkListener.fromLookup(this, 'ALBListener', { loadBalancerTags: { Cluster: 'MyClusterName', }, - listenerProtocol: Protocol.TCP, + listenerProtocol: elbv2.Protocol.TCP, listenerPort: 12345, }); ``` diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-elasticloadbalancingv2/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..8a21c6ec4d9a6 --- /dev/null +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/rosetta/default.ts-fixture @@ -0,0 +1,17 @@ +// Fixture with packages imported, but nothing else +import { Construct, Node } from 'constructs'; +import { CfnOutput, Stack, Duration, Resource, SecretValue } from '@aws-cdk/core'; +import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as autoscaling from '@aws-cdk/aws-autoscaling'; + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} + + + From d298696a7d8978296a34294484cea80f91ebe880 Mon Sep 17 00:00:00 2001 From: James Lakin Date: Wed, 27 Oct 2021 18:55:18 +0100 Subject: [PATCH 061/148] feat(core): Docker tags can be prefixed (#17028) This adds a container image equivalent of the `bucketPrefix` option for file assets. CDK assets works very well to make deploying applications easy, but I often find the contents of the S3 bucket and ECR repo to be a mess of alphabetti spaghetti over time. These options should help to provide some context in future cleanup operations. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../stack-synthesizers/default-synthesizer.ts | 19 +++++++++++++-- .../new-style-synthesis.test.ts | 24 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts b/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts index aae69e36ef24e..d8e1f8818abc4 100644 --- a/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts +++ b/packages/@aws-cdk/core/lib/stack-synthesizers/default-synthesizer.ts @@ -168,11 +168,20 @@ export interface DefaultStackSynthesizerProps { /** * bucketPrefix to use while storing S3 Assets * - * * @default - DefaultStackSynthesizer.DEFAULT_FILE_ASSET_PREFIX */ readonly bucketPrefix?: string; + /** + * A prefix to use while tagging and uploading Docker images to ECR. + * + * This does not add any separators - the source hash will be appended to + * this string directly. + * + * @default - DefaultStackSynthesizer.DEFAULT_DOCKER_ASSET_PREFIX + */ + readonly dockerTagPrefix?: string; + /** * Bootstrap stack version SSM parameter. * @@ -242,6 +251,10 @@ export class DefaultStackSynthesizer extends StackSynthesizer { * Default file asset prefix */ public static readonly DEFAULT_FILE_ASSET_PREFIX = ''; + /** + * Default Docker asset prefix + */ + public static readonly DEFAULT_DOCKER_ASSET_PREFIX = ''; /** * Default bootstrap stack version SSM parameter. @@ -258,6 +271,7 @@ export class DefaultStackSynthesizer extends StackSynthesizer { private lookupRoleArn?: string; private qualifier?: string; private bucketPrefix?: string; + private dockerTagPrefix?: string; private bootstrapStackVersionSsmParameter?: string; private readonly files: NonNullable = {}; @@ -319,6 +333,7 @@ export class DefaultStackSynthesizer extends StackSynthesizer { this.imageAssetPublishingRoleArn = specialize(this.props.imageAssetPublishingRoleArn ?? DefaultStackSynthesizer.DEFAULT_IMAGE_ASSET_PUBLISHING_ROLE_ARN); this.lookupRoleArn = specialize(this.props.lookupRoleArn ?? DefaultStackSynthesizer.DEFAULT_LOOKUP_ROLE_ARN); this.bucketPrefix = specialize(this.props.bucketPrefix ?? DefaultStackSynthesizer.DEFAULT_FILE_ASSET_PREFIX); + this.dockerTagPrefix = specialize(this.props.dockerTagPrefix ?? DefaultStackSynthesizer.DEFAULT_DOCKER_ASSET_PREFIX); this.bootstrapStackVersionSsmParameter = replaceAll( this.props.bootstrapStackVersionSsmParameter ?? DefaultStackSynthesizer.DEFAULT_BOOTSTRAP_STACK_VERSION_SSM_PARAMETER, '${Qualifier}', @@ -372,7 +387,7 @@ export class DefaultStackSynthesizer extends StackSynthesizer { assertBound(this.repositoryName); validateDockerImageAssetSource(asset); - const imageTag = asset.sourceHash; + const imageTag = this.dockerTagPrefix + asset.sourceHash; // Add to manifest this.dockerImages[asset.sourceHash] = { diff --git a/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts b/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts index 3a8d8c1e60b31..80303a4bbcf22 100644 --- a/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts +++ b/packages/@aws-cdk/core/test/stack-synthesis/new-style-synthesis.test.ts @@ -337,6 +337,30 @@ describe('new style synthesis', () => { }); + test('synthesis with dockerPrefix', () => { + // GIVEN + const myapp = new App(); + + // WHEN + const mystack = new Stack(myapp, 'mystack-dockerPrefix', { + synthesizer: new DefaultStackSynthesizer({ + dockerTagPrefix: 'test-prefix-', + }), + }); + + mystack.synthesizer.addDockerImageAsset({ + directoryName: 'some-folder', + sourceHash: 'docker-asset-hash', + }); + + const asm = myapp.synth(); + + // THEN + const manifest = readAssetManifest(getAssetManifest(asm)); + const imageTag = manifest.dockerImages?.['docker-asset-hash']?.destinations?.['current_account-current_region'].imageTag; + expect(imageTag).toEqual('test-prefix-docker-asset-hash'); + }); + test('cannot use same synthesizer for multiple stacks', () => { // GIVEN const synthesizer = new DefaultStackSynthesizer(); From e5095b2cbda7422bd6e67aab6ad949294b0b8ef2 Mon Sep 17 00:00:00 2001 From: niku <10890+niku@users.noreply.github.com> Date: Thu, 28 Oct 2021 03:48:30 +0900 Subject: [PATCH 062/148] chore(cx-api): return type of futureFlagDefault is incorrect (#17026) If invalid flag were given to futureFlagDefault, it returns `undefined`. As you see in changed files, I don't modify production codes. I only fix return type of the `futureFlagDefault` and add a test to describe when it runs into. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/cx-api/lib/features.ts | 2 +- packages/@aws-cdk/cx-api/test/features.test.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/cx-api/lib/features.ts b/packages/@aws-cdk/cx-api/lib/features.ts index 986be7f4e136b..37c9aace0ce86 100644 --- a/packages/@aws-cdk/cx-api/lib/features.ts +++ b/packages/@aws-cdk/cx-api/lib/features.ts @@ -220,6 +220,6 @@ const FUTURE_FLAGS_DEFAULTS: { [key: string]: boolean } = { [CLOUDFRONT_DEFAULT_SECURITY_POLICY_TLS_V1_2_2021]: false, }; -export function futureFlagDefault(flag: string): boolean { +export function futureFlagDefault(flag: string): boolean | undefined { return FUTURE_FLAGS_DEFAULTS[flag]; } diff --git a/packages/@aws-cdk/cx-api/test/features.test.ts b/packages/@aws-cdk/cx-api/test/features.test.ts index 2aaa774b7b1c5..afc9c0838d7da 100644 --- a/packages/@aws-cdk/cx-api/test/features.test.ts +++ b/packages/@aws-cdk/cx-api/test/features.test.ts @@ -7,6 +7,10 @@ test('all future flags have defaults configured', () => { }); }); +test('futureFlagDefault returns undefined if non existent flag was given', () => { + expect(feats.futureFlagDefault('non-existent-flag')).toEqual(undefined); +}); + testLegacyBehavior('FUTURE_FLAGS_EXPIRED must be empty in CDKv1', Object, () => { expect(feats.FUTURE_FLAGS_EXPIRED.length).toEqual(0); }); From 354686b189377dd1daae7ba616e8fb62488d9855 Mon Sep 17 00:00:00 2001 From: "Michael R. Torres" <6692889+micrictor@users.noreply.github.com> Date: Wed, 27 Oct 2021 12:40:55 -0700 Subject: [PATCH 063/148] fix(custom-resources): invalid service name leads to unhelpful error message (#16718) fix(custom-resources): improve AwsSdkCall service error Makes the error that occurs when an invalid service name is supplied more explicit. Closes #7312 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/aws-custom-resource/runtime/index.ts | 3 ++ .../aws-custom-resource-provider.test.ts | 33 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts b/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts index a805fc8c2bf4d..e88b441637cfc 100644 --- a/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts +++ b/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts @@ -176,6 +176,9 @@ export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent } + if (!Object.prototype.hasOwnProperty.call(AWS, call.service)) { + throw Error(`Service ${call.service} does not exist in AWS SDK version ${AWS.VERSION}.`); + } const awsService = new (AWS as any)[call.service]({ apiVersion: call.apiVersion, region: call.region, diff --git a/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource-provider.test.ts b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource-provider.test.ts index 8a4786a138468..aa8a9589d1fdb 100644 --- a/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource-provider.test.ts +++ b/packages/@aws-cdk/custom-resources/test/aws-custom-resource/aws-custom-resource-provider.test.ts @@ -467,3 +467,36 @@ test('installs the latest SDK', async () => { // clean up aws-sdk install await fs.remove(tmpPath); }); + +test('invalid service name throws explicit error', async () => { + const publishFake = sinon.fake.resolves({}); + + AWS.mock('SNS', 'publish', publishFake); + + const event: AWSLambda.CloudFormationCustomResourceCreateEvent = { + ...eventCommon, + RequestType: 'Create', + ResourceProperties: { + ServiceToken: 'token', + Create: JSON.stringify({ + service: 'thisisnotarealservice', + action: 'publish', + parameters: { + Message: 'message', + TopicArn: 'topic', + }, + physicalResourceId: PhysicalResourceId.of('id'), + } as AwsSdkCall), + }, + }; + + const request = createRequest(body => + body.Status === 'FAILED' && + body.Reason!.startsWith('Service thisisnotarealservice does not exist'), + ); + + await handler(event, {} as AWSLambda.Context); + + expect(request.isDone()).toBeTruthy(); +}); + From 322cf10ef3257b9d20d898882a14de91110a0033 Mon Sep 17 00:00:00 2001 From: Jonathan Goldwasser Date: Wed, 27 Oct 2021 22:32:54 +0200 Subject: [PATCH 064/148] feat(cli): deployment progress shows stack name (#16604) Allows to filter logs based on stack name, gives more context when looking at a log line in a log file. Useful in CI when multiple stacks are deployed in a run. (similar to lerna adding the package name) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../cloudformation/stack-activity-monitor.ts | 5 ++- .../test/api/stack-activity-monitor.test.ts | 42 +++++++++---------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts b/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts index 73075a41fee27..e956e63e3704c 100644 --- a/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts +++ b/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts @@ -523,8 +523,9 @@ export class HistoryActivityPrinter extends ActivityPrinterBase { this.stream.write( util.format( - ' %s%s | %s | %s | %s %s%s%s\n', - (progress !== false ? ` ${this.progress()} | ` : ''), + '%s | %s%s | %s | %s | %s %s%s%s\n', + e.StackName, + (progress !== false ? `${this.progress()} | ` : ''), new Date(e.Timestamp).toLocaleTimeString(), color(padRight(STATUS_WIDTH, (e.ResourceStatus || '').substr(0, STATUS_WIDTH))), // pad left and trim padRight(this.props.resourceTypeColumnWidth, e.ResourceType || ''), diff --git a/packages/aws-cdk/test/api/stack-activity-monitor.test.ts b/packages/aws-cdk/test/api/stack-activity-monitor.test.ts index c76ddda1ceb00..b793acda8b68b 100644 --- a/packages/aws-cdk/test/api/stack-activity-monitor.test.ts +++ b/packages/aws-cdk/test/api/stack-activity-monitor.test.ts @@ -27,12 +27,12 @@ test('prints 0/4 progress report, when addActivity is called with an "IN_PROGRES ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', - StackName: '', + StackName: 'stack-name', }, }); }); - expect(output[0].trim()).toStrictEqual(`0/4 | ${HUMAN_TIME} | ${reset('IN_PROGRESS ')} | AWS::CloudFormation::Stack | ${reset(bold('stack1'))}`); + expect(output[0].trim()).toStrictEqual(`stack-name | 0/4 | ${HUMAN_TIME} | ${reset('IN_PROGRESS ')} | AWS::CloudFormation::Stack | ${reset(bold('stack1'))}`); }); test('prints 1/4 progress report, when addActivity is called with an "UPDATE_COMPLETE" ResourceStatus', () => { @@ -51,12 +51,12 @@ test('prints 1/4 progress report, when addActivity is called with an "UPDATE_COM ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', - StackName: '', + StackName: 'stack-name', }, }); }); - expect(output[0].trim()).toStrictEqual(`1/4 | ${HUMAN_TIME} | ${green('UPDATE_COMPLETE ')} | AWS::CloudFormation::Stack | ${green(bold('stack1'))}`); + expect(output[0].trim()).toStrictEqual(`stack-name | 1/4 | ${HUMAN_TIME} | ${green('UPDATE_COMPLETE ')} | AWS::CloudFormation::Stack | ${green(bold('stack1'))}`); }); test('prints 1/4 progress report, when addActivity is called with an "UPDATE_COMPLETE_CLEAN_IN_PROGRESS" ResourceStatus', () => { @@ -75,12 +75,12 @@ test('prints 1/4 progress report, when addActivity is called with an "UPDATE_COM ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', - StackName: '', + StackName: 'stack-name', }, }); }); - expect(output[0].trim()).toStrictEqual(`1/4 | ${HUMAN_TIME} | ${green('UPDATE_COMPLETE_CLEA')} | AWS::CloudFormation::Stack | ${green(bold('stack1'))}`); + expect(output[0].trim()).toStrictEqual(`stack-name | 1/4 | ${HUMAN_TIME} | ${green('UPDATE_COMPLETE_CLEA')} | AWS::CloudFormation::Stack | ${green(bold('stack1'))}`); }); @@ -100,12 +100,12 @@ test('prints 1/4 progress report, when addActivity is called with an "ROLLBACK_C ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', - StackName: '', + StackName: 'stack-name', }, }); }); - expect(output[0].trim()).toStrictEqual(`1/4 | ${HUMAN_TIME} | ${yellow('ROLLBACK_COMPLETE_CL')} | AWS::CloudFormation::Stack | ${yellow(bold('stack1'))}`); + expect(output[0].trim()).toStrictEqual(`stack-name | 1/4 | ${HUMAN_TIME} | ${yellow('ROLLBACK_COMPLETE_CL')} | AWS::CloudFormation::Stack | ${yellow(bold('stack1'))}`); }); test('prints 0/4 progress report, when addActivity is called with an "UPDATE_FAILED" ResourceStatus', () => { @@ -124,12 +124,12 @@ test('prints 0/4 progress report, when addActivity is called with an "UPDATE_FAI ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', - StackName: '', + StackName: 'stack-name', }, }); }); - expect(output[0].trim()).toStrictEqual(`0/4 | ${HUMAN_TIME} | ${red('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${red(bold('stack1'))}`); + expect(output[0].trim()).toStrictEqual(`stack-name | 0/4 | ${HUMAN_TIME} | ${red('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${red(bold('stack1'))}`); }); @@ -149,7 +149,7 @@ test('does not print "Failed Resources:" list, when all deployments are successf ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', - StackName: '', + StackName: 'stack-name', }, }); historyActivityPrinter.addActivity({ @@ -160,7 +160,7 @@ test('does not print "Failed Resources:" list, when all deployments are successf ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', - StackName: '', + StackName: 'stack-name', }, }); historyActivityPrinter.addActivity({ @@ -171,16 +171,16 @@ test('does not print "Failed Resources:" list, when all deployments are successf ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', - StackName: '', + StackName: 'stack-name', }, }); historyActivityPrinter.stop(); }); expect(output.length).toStrictEqual(3); - expect(output[0].trim()).toStrictEqual(`0/2 | ${HUMAN_TIME} | ${reset('IN_PROGRESS ')} | AWS::CloudFormation::Stack | ${reset(bold('stack1'))}`); - expect(output[1].trim()).toStrictEqual(`1/2 | ${HUMAN_TIME} | ${green('UPDATE_COMPLETE ')} | AWS::CloudFormation::Stack | ${green(bold('stack1'))}`); - expect(output[2].trim()).toStrictEqual(`2/2 | ${HUMAN_TIME} | ${green('UPDATE_COMPLETE ')} | AWS::CloudFormation::Stack | ${green(bold('stack2'))}`); + expect(output[0].trim()).toStrictEqual(`stack-name | 0/2 | ${HUMAN_TIME} | ${reset('IN_PROGRESS ')} | AWS::CloudFormation::Stack | ${reset(bold('stack1'))}`); + expect(output[1].trim()).toStrictEqual(`stack-name | 1/2 | ${HUMAN_TIME} | ${green('UPDATE_COMPLETE ')} | AWS::CloudFormation::Stack | ${green(bold('stack1'))}`); + expect(output[2].trim()).toStrictEqual(`stack-name | 2/2 | ${HUMAN_TIME} | ${green('UPDATE_COMPLETE ')} | AWS::CloudFormation::Stack | ${green(bold('stack2'))}`); }); test('prints "Failed Resources:" list, when at least one deployment fails', () => { @@ -199,7 +199,7 @@ test('prints "Failed Resources:" list, when at least one deployment fails', () = ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', - StackName: '', + StackName: 'stack-name', }, }); historyActivityPrinter.addActivity({ @@ -210,15 +210,15 @@ test('prints "Failed Resources:" list, when at least one deployment fails', () = ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', - StackName: '', + StackName: 'stack-name', }, }); historyActivityPrinter.stop(); }); expect(output.length).toStrictEqual(4); - expect(output[0].trim()).toStrictEqual(`0/2 | ${HUMAN_TIME} | ${reset('IN_PROGRESS ')} | AWS::CloudFormation::Stack | ${reset(bold('stack1'))}`); - expect(output[1].trim()).toStrictEqual(`0/2 | ${HUMAN_TIME} | ${red('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${red(bold('stack1'))}`); + expect(output[0].trim()).toStrictEqual(`stack-name | 0/2 | ${HUMAN_TIME} | ${reset('IN_PROGRESS ')} | AWS::CloudFormation::Stack | ${reset(bold('stack1'))}`); + expect(output[1].trim()).toStrictEqual(`stack-name | 0/2 | ${HUMAN_TIME} | ${red('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${red(bold('stack1'))}`); expect(output[2].trim()).toStrictEqual('Failed resources:'); - expect(output[3].trim()).toStrictEqual(`${HUMAN_TIME} | ${red('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${red(bold('stack1'))}`); + expect(output[3].trim()).toStrictEqual(`stack-name | ${HUMAN_TIME} | ${red('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${red(bold('stack1'))}`); }); From 3cfe8a2df9edfb3133e470eb8f2274efcc2adda1 Mon Sep 17 00:00:00 2001 From: vincent-turato <39069200+vincent-turato@users.noreply.github.com> Date: Wed, 27 Oct 2021 14:24:25 -0700 Subject: [PATCH 065/148] feat(cloudtrail): selector for management event exclusions (#16546) Closes: #16273 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts | 24 ++++++++ .../aws-cloudtrail/test/cloudtrail.test.ts | 55 ++++++++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts b/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts index 245c60600c08e..12cf079c5279e 100644 --- a/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts +++ b/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts @@ -334,6 +334,7 @@ export class Trail extends Resource { values: dataResourceValues, }], includeManagementEvents: options.includeManagementEvents, + excludeManagementEventSources: options.excludeManagementEventSources, readWriteType: options.readWriteType, }); } @@ -424,6 +425,28 @@ export interface AddEventSelectorOptions { * @default true */ readonly includeManagementEvents?: boolean; + + /** + * An optional list of service event sources from which you do not want management events to be logged on your trail. + * + * @default [] + */ + readonly excludeManagementEventSources?: ManagementEventSources[]; +} + +/** + * Types of management event sources that can be excluded + */ +export enum ManagementEventSources { + /** + * AWS Key Management Service (AWS KMS) events + */ + KMS = 'kms.amazonaws.com', + + /** + * Data API events + */ + RDS_DATA_API = 'rdsdata.amazonaws.com', } /** @@ -457,6 +480,7 @@ export enum DataResourceType { interface EventSelector { readonly includeManagementEvents?: boolean; + readonly excludeManagementEventSources?: string[]; readonly readWriteType?: ReadWriteType; readonly dataResources?: EventSelectorData[]; } diff --git a/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts b/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts index 9e17345368785..c00f01d43acc4 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts +++ b/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts @@ -7,7 +7,7 @@ import { LogGroup, RetentionDays } from '@aws-cdk/aws-logs'; import * as s3 from '@aws-cdk/aws-s3'; import * as sns from '@aws-cdk/aws-sns'; import { Stack } from '@aws-cdk/core'; -import { ReadWriteType, Trail } from '../lib'; +import { ManagementEventSources, ReadWriteType, Trail } from '../lib'; const ExpectedBucketPolicyProperties = { PolicyDocument: { @@ -446,6 +446,59 @@ describe('cloudtrail', () => { }); }); + test('exclude management events', () => { + const stack = getTestStack(); + const bucket = new s3.Bucket(stack, 'testBucket', { bucketName: 'test-bucket' }); + const cloudTrail = new Trail(stack, 'MyAmazingCloudTrail'); + cloudTrail.addS3EventSelector([{ bucket }], { + excludeManagementEventSources: [ + ManagementEventSources.KMS, + ManagementEventSources.RDS_DATA_API, + ], + }); + cloudTrail.addS3EventSelector([{ bucket }], { + excludeManagementEventSources: [], + }); + + expect(stack).toHaveResourceLike('AWS::CloudTrail::Trail', { + EventSelectors: [ + { + DataResources: [{ + Type: 'AWS::S3::Object', + Values: [{ + 'Fn::Join': [ + '', + [ + { 'Fn::GetAtt': ['testBucketDF4D7D1A', 'Arn'] }, + '/', + ], + ], + }], + }], + ExcludeManagementEventSources: [ + 'kms.amazonaws.com', + 'rdsdata.amazonaws.com', + ], + }, + { + DataResources: [{ + Type: 'AWS::S3::Object', + Values: [{ + 'Fn::Join': [ + '', + [ + { 'Fn::GetAtt': ['testBucketDF4D7D1A', 'Arn'] }, + '/', + ], + ], + }], + }], + ExcludeManagementEventSources: [], + }, + ], + }); + }); + test('for Lambda function data event', () => { const stack = getTestStack(); const lambdaFunction = new lambda.Function(stack, 'LambdaFunction', { From dbb3f25904403bfc020a081e94270f5c16a7606f Mon Sep 17 00:00:00 2001 From: Alban Esc Date: Wed, 27 Oct 2021 15:16:33 -0700 Subject: [PATCH 066/148] feat(events): DLQ support for EventBus target (#16383) Closes #15954. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-events-targets/README.md | 22 +++++- .../aws-events-targets/lib/event-bus.ts | 35 ++++++--- .../test/event-bus/event-rule-target.test.ts | 78 ++++++++++++++++++- .../event-bus/integ.event-bus.expected.json | 54 ++++++++++++- .../test/event-bus/integ.event-bus.ts | 7 ++ 5 files changed, 184 insertions(+), 12 deletions(-) diff --git a/packages/@aws-cdk/aws-events-targets/README.md b/packages/@aws-cdk/aws-events-targets/README.md index 76d25eab83dd3..1282cee012c5e 100644 --- a/packages/@aws-cdk/aws-events-targets/README.md +++ b/packages/@aws-cdk/aws-events-targets/README.md @@ -28,7 +28,7 @@ Currently supported are: * Put a record to a Kinesis stream * [Log an event into a LogGroup](#log-an-event-into-a-loggroup) * Put a record to a Kinesis Data Firehose stream -* Put an event on an EventBridge bus +* [Put an event on an EventBridge bus](#put-an-event-on-an-eventbridge-bus) See the README of the `@aws-cdk/aws-events` library for more information on EventBridge. @@ -266,3 +266,23 @@ rule.addTarget( } ), ) ``` + +## Put an event on an EventBridge bus + +Use the `EventBus` target to route event to a different EventBus. + +The code snippet below creates the scheduled event rule that route events to an imported event bus. + +```ts +const rule = new events.Rule(this, 'Rule', { + schedule: events.Schedule.expression('rate(1 minute)'), +}); + +rule.addTarget(new targets.EventBus( + events.EventBus.fromEventBusArn( + this, + 'External', + `arn:aws:events:eu-west-1:999999999999:event-bus/test-bus`, + ), +)); +``` diff --git a/packages/@aws-cdk/aws-events-targets/lib/event-bus.ts b/packages/@aws-cdk/aws-events-targets/lib/event-bus.ts index 8237b8cdd7993..7026273ef5330 100644 --- a/packages/@aws-cdk/aws-events-targets/lib/event-bus.ts +++ b/packages/@aws-cdk/aws-events-targets/lib/event-bus.ts @@ -1,9 +1,12 @@ import * as events from '@aws-cdk/aws-events'; import * as iam from '@aws-cdk/aws-iam'; -import { singletonEventRole } from './util'; +import * as sqs from '@aws-cdk/aws-sqs'; +import { singletonEventRole, addToDeadLetterQueueResourcePolicy } from './util'; /** * Configuration properties of an Event Bus event + * + * Cannot extend TargetBaseProps. Retry policy is not supported for Event bus targets. */ export interface EventBusProps { /** @@ -12,25 +15,39 @@ export interface EventBusProps { * @default a new role is created. */ readonly role?: iam.IRole; + + /** + * The SQS queue to be used as deadLetterQueue. + * Check out the [considerations for using a dead-letter queue](https://docs.aws.amazon.com/eventbridge/latest/userguide/rule-dlq.html#dlq-considerations). + * + * The events not successfully delivered are automatically retried for a specified period of time, + * depending on the retry policy of the target. + * If an event is not delivered before all retry attempts are exhausted, it will be sent to the dead letter queue. + * + * @default - no dead-letter queue + */ + readonly deadLetterQueue?: sqs.IQueue; } /** * Notify an existing Event Bus of an event */ export class EventBus implements events.IRuleTarget { - private readonly role?: iam.IRole; - - constructor(private readonly eventBus: events.IEventBus, props: EventBusProps = {}) { - this.role = props.role; - } + constructor(private readonly eventBus: events.IEventBus, private readonly props: EventBusProps = {}) { } bind(rule: events.IRule, _id?: string): events.RuleTargetConfig { - if (this.role) { - this.role.addToPrincipalPolicy(this.putEventStatement()); + if (this.props.role) { + this.props.role.addToPrincipalPolicy(this.putEventStatement()); } - const role = this.role ?? singletonEventRole(rule, [this.putEventStatement()]); + const role = this.props.role ?? singletonEventRole(rule, [this.putEventStatement()]); + + if (this.props.deadLetterQueue) { + addToDeadLetterQueueResourcePolicy(rule, this.props.deadLetterQueue); + } + return { arn: this.eventBus.eventBusArn, + deadLetterConfig: this.props.deadLetterQueue ? { arn: this.props.deadLetterQueue?.queueArn } : undefined, role, }; } diff --git a/packages/@aws-cdk/aws-events-targets/test/event-bus/event-rule-target.test.ts b/packages/@aws-cdk/aws-events-targets/test/event-bus/event-rule-target.test.ts index 8d188f1550e8b..a6552a10d7a57 100644 --- a/packages/@aws-cdk/aws-events-targets/test/event-bus/event-rule-target.test.ts +++ b/packages/@aws-cdk/aws-events-targets/test/event-bus/event-rule-target.test.ts @@ -1,6 +1,7 @@ import '@aws-cdk/assert-internal/jest'; import * as events from '@aws-cdk/aws-events'; import * as iam from '@aws-cdk/aws-iam'; +import * as sqs from '@aws-cdk/aws-sqs'; import { Stack } from '@aws-cdk/core'; import * as targets from '../../lib'; @@ -90,4 +91,79 @@ test('with supplied role', () => { Ref: 'Role1ABCC5F0', }], }); -}); \ No newline at end of file +}); + +test('with a Dead Letter Queue specified', () => { + const stack = new Stack(); + const rule = new events.Rule(stack, 'Rule', { + schedule: events.Schedule.expression('rate(1 min)'), + }); + const queue = new sqs.Queue(stack, 'Queue'); + + rule.addTarget(new targets.EventBus( + events.EventBus.fromEventBusArn( + stack, + 'External', + 'arn:aws:events:us-east-1:123456789012:default', + ), + { deadLetterQueue: queue }, + )); + + expect(stack).toHaveResource('AWS::Events::Rule', { + Targets: [{ + Arn: 'arn:aws:events:us-east-1:123456789012:default', + Id: 'Target0', + RoleArn: { + 'Fn::GetAtt': [ + 'RuleEventsRoleC51A4248', + 'Arn', + ], + }, + DeadLetterConfig: { + Arn: { + 'Fn::GetAtt': [ + 'Queue4A7E3555', + 'Arn', + ], + }, + }, + }], + }); + + expect(stack).toHaveResource('AWS::SQS::QueuePolicy', { + PolicyDocument: { + Statement: [ + { + Action: 'sqs:SendMessage', + Condition: { + ArnEquals: { + 'aws:SourceArn': { + 'Fn::GetAtt': [ + 'Rule4C995B7F', + 'Arn', + ], + }, + }, + }, + Effect: 'Allow', + Principal: { + Service: 'events.amazonaws.com', + }, + Resource: { + 'Fn::GetAtt': [ + 'Queue4A7E3555', + 'Arn', + ], + }, + Sid: 'AllowEventRuleRule', + }, + ], + Version: '2012-10-17', + }, + Queues: [ + { + Ref: 'Queue4A7E3555', + }, + ], + }); +}); diff --git a/packages/@aws-cdk/aws-events-targets/test/event-bus/integ.event-bus.expected.json b/packages/@aws-cdk/aws-events-targets/test/event-bus/integ.event-bus.expected.json index 632ddf1767598..a10603f0b03b5 100644 --- a/packages/@aws-cdk/aws-events-targets/test/event-bus/integ.event-bus.expected.json +++ b/packages/@aws-cdk/aws-events-targets/test/event-bus/integ.event-bus.expected.json @@ -19,6 +19,14 @@ ] ] }, + "DeadLetterConfig": { + "Arn": { + "Fn::GetAtt": [ + "Queue4A7E3555", + "Arn" + ] + } + }, "Id": "Target0", "RoleArn": { "Fn::GetAtt": [ @@ -78,6 +86,50 @@ } ] } + }, + "Queue4A7E3555": { + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "QueuePolicy25439813": { + "Type": "AWS::SQS::QueuePolicy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "sqs:SendMessage", + "Condition": { + "ArnEquals": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "Rule4C995B7F", + "Arn" + ] + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + }, + "Resource": { + "Fn::GetAtt": [ + "Queue4A7E3555", + "Arn" + ] + }, + "Sid": "AllowEventRuleeventsourcestackRuleFCA41174" + } + ], + "Version": "2012-10-17" + }, + "Queues": [ + { + "Ref": "Queue4A7E3555" + } + ] + } } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-events-targets/test/event-bus/integ.event-bus.ts b/packages/@aws-cdk/aws-events-targets/test/event-bus/integ.event-bus.ts index c0ec2ea421b85..5a102ea3cba6c 100644 --- a/packages/@aws-cdk/aws-events-targets/test/event-bus/integ.event-bus.ts +++ b/packages/@aws-cdk/aws-events-targets/test/event-bus/integ.event-bus.ts @@ -1,5 +1,6 @@ /// !cdk-integ pragma:ignore-assets import * as events from '@aws-cdk/aws-events'; +import * as sqs from '@aws-cdk/aws-sqs'; import * as cdk from '@aws-cdk/core'; import * as targets from '../../lib'; @@ -12,12 +13,18 @@ class EventSourceStack extends cdk.Stack { const rule = new events.Rule(this, 'Rule', { schedule: events.Schedule.expression('rate(1 minute)'), }); + + const queue = new sqs.Queue(this, 'Queue'); + rule.addTarget(new targets.EventBus( events.EventBus.fromEventBusArn( this, 'External', `arn:aws:events:${this.region}:999999999999:event-bus/test-bus`, ), + { + deadLetterQueue: queue, + }, )); } } From 5831456465fa44af96a268de56db0e3a8d3c2ea6 Mon Sep 17 00:00:00 2001 From: Julian Michel Date: Thu, 28 Oct 2021 01:09:43 +0200 Subject: [PATCH 067/148] fix(core): SecretValue.secretsManager fails for tokenized secret-id (#16230) `SecretValue.secretsManager` fails if a token is used for `secret-id`. This is caused by a validation which should be skipped for tokenized values. Solved by skipping the validation if token is unresolved. Fixes #16166. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/core/lib/secret-value.ts | 3 +- .../@aws-cdk/core/test/secret-value.test.ts | 47 ++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/core/lib/secret-value.ts b/packages/@aws-cdk/core/lib/secret-value.ts index 2cd1b772f3207..b57b704bd9ed6 100644 --- a/packages/@aws-cdk/core/lib/secret-value.ts +++ b/packages/@aws-cdk/core/lib/secret-value.ts @@ -1,6 +1,7 @@ import { CfnDynamicReference, CfnDynamicReferenceService } from './cfn-dynamic-reference'; import { CfnParameter } from './cfn-parameter'; import { Intrinsic } from './private/intrinsic'; +import { Token } from './token'; /** * Work with secret values in the CDK @@ -39,7 +40,7 @@ export class SecretValue extends Intrinsic { throw new Error('secretId cannot be empty'); } - if (!secretId.startsWith('arn:') && secretId.includes(':')) { + if (!Token.isUnresolved(secretId) && !secretId.startsWith('arn:') && secretId.includes(':')) { throw new Error(`secret id "${secretId}" is not an ARN but contains ":"`); } diff --git a/packages/@aws-cdk/core/test/secret-value.test.ts b/packages/@aws-cdk/core/test/secret-value.test.ts index a32702b98771d..2efcdffbe808d 100644 --- a/packages/@aws-cdk/core/test/secret-value.test.ts +++ b/packages/@aws-cdk/core/test/secret-value.test.ts @@ -1,4 +1,4 @@ -import { CfnDynamicReference, CfnDynamicReferenceService, CfnParameter, SecretValue, Stack } from '../lib'; +import { CfnDynamicReference, CfnDynamicReferenceService, CfnParameter, SecretValue, Stack, Token } from '../lib'; describe('secret value', () => { test('plainText', () => { @@ -28,6 +28,30 @@ describe('secret value', () => { }); + test('secretsManager with secret-id from token', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + const v = SecretValue.secretsManager(Token.asString({ Ref: 'secret-id' }), { + jsonField: 'json-key', + versionStage: 'version-stage', + }); + + // THEN + expect(stack.resolve(v)).toEqual({ + 'Fn::Join': [ + '', + [ + '{{resolve:secretsmanager:', + { Ref: 'secret-id' }, + ':SecretString:json-key:version-stage:}}', + ], + ], + }); + + }); + test('secretsManager with defaults', () => { // GIVEN const stack = new Stack(); @@ -40,6 +64,27 @@ describe('secret value', () => { }); + test('secretsManager with defaults, secret-id from token', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + const v = SecretValue.secretsManager(Token.asString({ Ref: 'secret-id' })); + + // THEN + expect(stack.resolve(v)).toEqual({ + 'Fn::Join': [ + '', + [ + '{{resolve:secretsmanager:', + { Ref: 'secret-id' }, + ':SecretString:::}}', + ], + ], + }); + + }); + test('secretsManager with an empty ID', () => { expect(() => SecretValue.secretsManager('')).toThrow(/secretId cannot be empty/); From e55301b635374a87822f78870981a9e06e13d99e Mon Sep 17 00:00:00 2001 From: Anurag Mohapatra Date: Thu, 28 Oct 2021 11:03:33 +1100 Subject: [PATCH 068/148] fix(cli): downgrade bootstrap stack error message needs a hint for new-style synthesis (#16237) Fix to the bootstrap error message on the version comparison to provide to peek at solution so as to warn users about new style stack synthesis not being enabled automatically in the cdk.json as the potential root cause Fixes https://github.com/aws/aws-cdk/issues/16009 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/lib/api/bootstrap/deploy-bootstrap.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk/lib/api/bootstrap/deploy-bootstrap.ts b/packages/aws-cdk/lib/api/bootstrap/deploy-bootstrap.ts index 4d66e59268dcc..49f97e71332c3 100644 --- a/packages/aws-cdk/lib/api/bootstrap/deploy-bootstrap.ts +++ b/packages/aws-cdk/lib/api/bootstrap/deploy-bootstrap.ts @@ -65,7 +65,7 @@ export class BootstrapStack { const newVersion = bootstrapVersionFromTemplate(template); if (this.currentToolkitInfo.found && newVersion < this.currentToolkitInfo.version && !options.force) { - throw new Error(`Not downgrading existing bootstrap stack from version '${this.currentToolkitInfo.version}' to version '${newVersion}'. Use --force to force.`); + throw new Error(`Not downgrading existing bootstrap stack from version '${this.currentToolkitInfo.version}' to version '${newVersion}'. Use --force to force or set the '@aws-cdk/core:newStyleStackSynthesis' feature flag in cdk.json to use the latest bootstrap version.`); } const outdir = await fs.mkdtemp(path.join(os.tmpdir(), 'cdk-bootstrap')); @@ -114,4 +114,4 @@ export function bootstrapVersionFromTemplate(template: any): number { } } return 0; -} \ No newline at end of file +} From a6aaa64bf9779b984f20d18881b4f6e510ac091a Mon Sep 17 00:00:00 2001 From: James Lakin Date: Thu, 28 Oct 2021 01:56:20 +0100 Subject: [PATCH 069/148] fix(logs): Apply tags to log retention Lambda (#17029) This hopefully fixes #15032 by implementing the `ITaggable` interface on the custom construct and then applying discovered tags to the underlying `CfnResource`. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-logs/lib/log-retention.ts | 5 +- .../aws-logs/test/log-retention.test.ts | 19 ++++++++ packages/@aws-cdk/core/lib/tag-manager.ts | 46 ++++++++++++++++++- 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-logs/lib/log-retention.ts b/packages/@aws-cdk/aws-logs/lib/log-retention.ts index f3054cf910f1c..fe4e3e3cff7af 100644 --- a/packages/@aws-cdk/aws-logs/lib/log-retention.ts +++ b/packages/@aws-cdk/aws-logs/lib/log-retention.ts @@ -128,9 +128,11 @@ export class LogRetention extends CoreConstruct { /** * Private provider Lambda function to support the log retention custom resource. */ -class LogRetentionFunction extends CoreConstruct { +class LogRetentionFunction extends CoreConstruct implements cdk.ITaggable { public readonly functionArn: cdk.Reference; + public readonly tags: cdk.TagManager = new cdk.TagManager(cdk.TagType.KEY_VALUE, 'AWS::Lambda::Function'); + constructor(scope: Construct, id: string, props: LogRetentionProps) { super(scope, id); @@ -164,6 +166,7 @@ class LogRetentionFunction extends CoreConstruct { S3Key: asset.s3ObjectKey, }, Role: role.roleArn, + Tags: this.tags.renderedTags, }, }); this.functionArn = resource.getAtt('Arn'); diff --git a/packages/@aws-cdk/aws-logs/test/log-retention.test.ts b/packages/@aws-cdk/aws-logs/test/log-retention.test.ts index 8f8ed85bb4d47..208031bc1744b 100644 --- a/packages/@aws-cdk/aws-logs/test/log-retention.test.ts +++ b/packages/@aws-cdk/aws-logs/test/log-retention.test.ts @@ -156,4 +156,23 @@ describe('log retention', () => { expect(logGroupArn.endsWith(':*')).toEqual(true); }); + + test('retention Lambda CfnResource receives propagated tags', () => { + const stack = new cdk.Stack(); + cdk.Tags.of(stack).add('test-key', 'test-value'); + new LogRetention(stack, 'MyLambda', { + logGroupName: 'group', + retention: RetentionDays.ONE_MONTH, + }); + + expect(stack).toHaveResourceLike('AWS::Lambda::Function', { + Tags: [ + { + Key: 'test-key', + Value: 'test-value', + }, + ], + }); + + }); }); diff --git a/packages/@aws-cdk/core/lib/tag-manager.ts b/packages/@aws-cdk/core/lib/tag-manager.ts index cdc224500ef1b..8f4893d5036f0 100644 --- a/packages/@aws-cdk/core/lib/tag-manager.ts +++ b/packages/@aws-cdk/core/lib/tag-manager.ts @@ -1,5 +1,7 @@ import { TagType } from './cfn-resource'; import { CfnTag } from './cfn-tag'; +import { Lazy } from './lazy'; +import { IResolvable } from './resolvable'; interface Tag { key: string; @@ -172,7 +174,7 @@ class KeyValueFormatter implements ITagFormatter { Value: tag.value, }); }); - return tags; + return tags.length > 0 ? tags : undefined; } } @@ -228,7 +230,32 @@ export interface TagManagerOptions { } /** - * TagManager facilitates a common implementation of tagging for Constructs. + * TagManager facilitates a common implementation of tagging for Constructs + * + * Normally, you do not need to use this class, as the CloudFormation specification + * will indicate which resources are taggable. However, sometimes you will need this + * to make custom resources taggable. Used `tagManager.renderedTags` to obtain a + * value that will resolve to the tags at synthesis time. + * + * @example + * import * as cdk from '@aws-cdk/core'; + * + * class MyConstruct extends cdk.Resource implements cdk.ITaggable { + * public readonly tags = new cdk.TagManager(cdk.TagType.KEY_VALUE, 'Whatever::The::Type'); + * + * constructor(scope: cdk.Construct, id: string) { + * super(scope, id); + * + * new cdk.CfnResource(this, 'Resource', { + * type: 'Whatever::The::Type', + * properties: { + * // ... + * Tags: this.tags.renderedTags, + * }, + * }); + * } + * } + * */ export class TagManager { @@ -247,6 +274,14 @@ export class TagManager { */ public readonly tagPropertyName: string; + /** + * A lazy value that represents the rendered tags at synthesis time + * + * If you need to make a custom construct taggable, use the value of this + * property to pass to the `tags` property of the underlying construct. + */ + public readonly renderedTags: IResolvable; + private readonly tags = new Map(); private readonly priorities = new Map(); private readonly tagFormatter: ITagFormatter; @@ -260,6 +295,8 @@ export class TagManager { this._setTag(...this.tagFormatter.parseTags(tagStructure, this.initialTagPriority)); } this.tagPropertyName = options.tagPropertyName || 'tags'; + + this.renderedTags = Lazy.any({ produce: () => this.renderTags() }); } /** @@ -287,6 +324,11 @@ export class TagManager { /** * Renders tags into the proper format based on TagType + * + * This method will eagerly render the tags currently applied. In + * most cases, you should be using `tagManager.renderedTags` instead, + * which will return a `Lazy` value that will resolve to the correct + * tags at synthesis time. */ public renderTags(): any { return this.tagFormatter.formatTags(this.sortedTags); From 823c4d6700fdbba7f0defb2cf4daa1543738284b Mon Sep 17 00:00:00 2001 From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com> Date: Wed, 27 Oct 2021 21:49:12 -0400 Subject: [PATCH 070/148] chore(lambda): make examples compile (#17188) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-lambda/README.md | 218 +++++++++--------- .../aws-lambda/rosetta/default.ts-fixture | 6 +- .../aws-lambda/rosetta/function.ts-fixture | 18 -- 3 files changed, 118 insertions(+), 124 deletions(-) delete mode 100644 packages/@aws-cdk/aws-lambda/rosetta/function.ts-fixture diff --git a/packages/@aws-cdk/aws-lambda/README.md b/packages/@aws-cdk/aws-lambda/README.md index dc97826d51135..bb42d0811994d 100644 --- a/packages/@aws-cdk/aws-lambda/README.md +++ b/packages/@aws-cdk/aws-lambda/README.md @@ -14,10 +14,10 @@ This construct library allows you to define AWS Lambda Functions. ```ts -const fn = new Function(this, 'MyFunction', { - runtime: Runtime.NODEJS_12_X, +const fn = new lambda.Function(this, 'MyFunction', { + runtime: lambda.Runtime.NODEJS_12_X, handler: 'index.handler', - code: Code.fromAsset(path.join(__dirname, 'lambda-handler')), + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), }); ``` @@ -62,8 +62,8 @@ The following `DockerImageFunction` construct uses a local folder with a Dockerfile as the asset that will be used as the function handler. ```ts -new DockerImageFunction(this, 'AssetFunction', { - code: DockerImageCode.fromImageAsset(path.join(__dirname, 'docker-handler')), +new lambda.DockerImageFunction(this, 'AssetFunction', { + code: lambda.DockerImageCode.fromImageAsset(path.join(__dirname, 'docker-handler')), }); ``` @@ -73,8 +73,8 @@ You can also specify an image that already exists in ECR as the function handler import * as ecr from '@aws-cdk/aws-ecr'; const repo = new ecr.Repository(this, 'Repository'); -new DockerImageFunction(this, 'ECRFunction', { - code: DockerImageCode.fromEcr(repo), +new lambda.DockerImageFunction(this, 'ECRFunction', { + code: lambda.DockerImageCode.fromEcr(repo), }); ``` @@ -90,13 +90,13 @@ The autogenerated Role is automatically given permissions to execute the Lambda function. To reference the autogenerated Role: ```ts -const fn = new Function(this, 'MyFunction', { - runtime: Runtime.NODEJS_12_X, +const fn = new lambda.Function(this, 'MyFunction', { + runtime: lambda.Runtime.NODEJS_12_X, handler: 'index.handler', - code: Code.fromAsset(path.join(__dirname, 'lambda-handler')), + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), }); -fn.role // the Role +const role = fn.role; // the Role ``` You can also provide your own IAM role. Provided IAM roles will not automatically @@ -104,15 +104,15 @@ be given permissions to execute the Lambda function. To provide a role and grant it appropriate permissions: ```ts -import * as iam from '@aws-cdk/aws-iam'; const myRole = new iam.Role(this, 'My Role', { assumedBy: new iam.ServicePrincipal('sns.amazonaws.com'), }); -const fn = new Function(this, 'MyFunction', { - runtime: Runtime.NODEJS_12_X, + +const fn = new lambda.Function(this, 'MyFunction', { + runtime: lambda.Runtime.NODEJS_12_X, handler: 'index.handler', - code: Code.fromAsset(path.join(__dirname, 'lambda-handler')), - role: myRole // user-provided role + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), + role: myRole, // user-provided role }); myRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole")); @@ -128,8 +128,8 @@ functions. You can also restrict permissions given to AWS services by providing a source account or ARN (representing the account and identifier of the resource that accesses the function or layer). -```ts fixture=function -import * as iam from '@aws-cdk/aws-iam'; +```ts +declare const fn: lambda.Function; const principal = new iam.ServicePrincipal('my-service'); fn.grantInvoke(principal); @@ -151,8 +151,8 @@ principal in question has conditions limiting the source account or ARN of the operation (see above), these conditions will be automatically added to the resource policy. -```ts fixture=function -import * as iam from '@aws-cdk/aws-iam'; +```ts +declare const fn: lambda.Function; const servicePrincipal = new iam.ServicePrincipal('my-service'); const sourceArn = 'arn:aws:s3:::my-bucket'; const sourceAccount = '111122223333'; @@ -193,8 +193,8 @@ The function version includes the following information: You could create a version to your lambda function using the `Version` construct. ```ts -const fn = new Function(this, 'MyFunction', ...); -const version = new Version(this, 'MyVersion', { +declare const fn: lambda.Function; +const version = new lambda.Version(this, 'MyVersion', { lambda: fn, }); ``` @@ -211,9 +211,12 @@ latest code. For instance - ```ts const codeVersion = "stringOrMethodToGetCodeVersion"; const fn = new lambda.Function(this, 'MyFunction', { - environment: { - 'CodeVersionString': codeVersion - } + runtime: lambda.Runtime.NODEJS_12_X, + handler: 'index.handler', + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), + environment: { + 'CodeVersionString': codeVersion, + }, }); ``` @@ -291,16 +294,14 @@ specify options for the current version through the `currentVersionOptions` property. ```ts -import * as cdk from '@aws-cdk/core'; - -const fn = new Function(this, 'MyFunction', { +const fn = new lambda.Function(this, 'MyFunction', { currentVersionOptions: { - removalPolicy: cdk.RemovalPolicy.RETAIN, // retain old versions - retryAttempts: 1 // async retry attempts + removalPolicy: RemovalPolicy.RETAIN, // retain old versions + retryAttempts: 1, // async retry attempts }, - runtime: Runtime.NODEJS_12_X, + runtime: lambda.Runtime.NODEJS_12_X, handler: 'index.handler', - code: Code.fromAsset(path.join(__dirname, 'lambda-handler')), + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), }); fn.currentVersion.addAlias('live'); @@ -318,11 +319,9 @@ By default, updating a layer creates a new layer version, and CloudFormation wil Alternatively, a removal policy can be used to retain the old version: ```ts -import * as cdk from '@aws-cdk/core'; - -new LayerVersion(this, 'MyLayer', { - removalPolicy: cdk.RemovalPolicy.RETAIN, - code: Code.fromAsset(path.join(__dirname, 'lambda-handler')), +new lambda.LayerVersion(this, 'MyLayer', { + removalPolicy: RemovalPolicy.RETAIN, + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), }); ``` @@ -336,18 +335,21 @@ for some workloads. A lambda function can be configured to be run on one of these platforms: ```ts -new Function(this, 'MyFunction', { - ... - architecture: Architecture.ARM_64, +new lambda.Function(this, 'MyFunction', { + runtime: lambda.Runtime.NODEJS_12_X, + handler: 'index.handler', + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), + architecture: lambda.Architecture.ARM_64, }); ``` Similarly, lambda layer versions can also be tagged with architectures it is compatible with. ```ts -new LayerVersion(this, 'MyLayer', { - ... - compatibleArchitectures: [Architecture.X86_64, Architecture.ARM_64], +new lambda.LayerVersion(this, 'MyLayer', { + removalPolicy: RemovalPolicy.RETAIN, + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), + compatibleArchitectures: [lambda.Architecture.X86_64, lambda.Architecture.ARM_64], }); ``` @@ -357,20 +359,24 @@ Lambda functions can be configured to use CloudWatch [Lambda Insights](https://d which provides low-level runtime metrics for a Lambda functions. ```ts -import * as lambda from '@aws-cdk/lambda'; - -new Function(this, 'MyFunction', { - insightsVersion: lambda.LambdaInsightsVersion.VERSION_1_0_98_0 -}) +new lambda.Function(this, 'MyFunction', { + runtime: lambda.Runtime.NODEJS_12_X, + handler: 'index.handler', + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), + insightsVersion: lambda.LambdaInsightsVersion.VERSION_1_0_98_0, +}); ``` If the version of insights is not yet available in the CDK, you can also provide the ARN directly as so - ```ts const layerArn = 'arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:14'; -new Function(this, 'MyFunction', { - insightsVersion: lambda.LambdaInsightsVersion.fromInsightVersionArn(layerArn) -}) +new lambda.Function(this, 'MyFunction', { + runtime: lambda.Runtime.NODEJS_12_X, + handler: 'index.handler', + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), + insightsVersion: lambda.LambdaInsightsVersion.fromInsightVersionArn(layerArn), +}); ``` ## Event Rule Target @@ -378,9 +384,11 @@ new Function(this, 'MyFunction', { You can use an AWS Lambda function as a target for an Amazon CloudWatch event rule: -```ts fixture=function +```ts import * as events from '@aws-cdk/aws-events'; import * as targets from '@aws-cdk/aws-events-targets'; + +declare const fn: lambda.Function; const rule = new events.Rule(this, 'Schedule Rule', { schedule: events.Schedule.cron({ minute: '0', hour: '4' }), }); @@ -402,18 +410,22 @@ includes classes for the various event sources supported by AWS Lambda. For example, the following code adds an SQS queue as an event source for a function: -```ts fixture=function +```ts import * as eventsources from '@aws-cdk/aws-lambda-event-sources'; import * as sqs from '@aws-cdk/aws-sqs'; + +declare const fn: lambda.Function; const queue = new sqs.Queue(this, 'Queue'); fn.addEventSource(new eventsources.SqsEventSource(queue)); ``` The following code adds an S3 bucket notification as an event source: -```ts fixture=function +```ts import * as eventsources from '@aws-cdk/aws-lambda-event-sources'; import * as s3 from '@aws-cdk/aws-s3'; + +declare const fn: lambda.Function; const bucket = new s3.Bucket(this, 'Bucket'); fn.addEventSource(new eventsources.S3EventSource(bucket, { events: [ s3.EventType.OBJECT_CREATED, s3.EventType.OBJECT_REMOVED ], @@ -429,11 +441,11 @@ A dead-letter queue can be automatically created for a Lambda function by setting the `deadLetterQueueEnabled: true` configuration. ```ts -const fn = new Function(this, 'MyFunction', { - runtime: Runtime.NODEJS_12_X, - handler: 'index.handler', - code: Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hi"); }'), - deadLetterQueueEnabled: true +const fn = new lambda.Function(this, 'MyFunction', { + runtime: lambda.Runtime.NODEJS_12_X, + handler: 'index.handler', + code: lambda.Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hi"); }'), + deadLetterQueueEnabled: true, }); ``` @@ -443,11 +455,11 @@ It is also possible to provide a dead-letter queue instead of getting a new queu import * as sqs from '@aws-cdk/aws-sqs'; const dlq = new sqs.Queue(this, 'DLQ'); -const fn = new Function(this, 'MyFunction', { - runtime: Runtime.NODEJS_12_X, - handler: 'index.handler', - code: Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hi"); }'), - deadLetterQueue: dlq +const fn = new lambda.Function(this, 'MyFunction', { + runtime: lambda.Runtime.NODEJS_12_X, + handler: 'index.handler', + code: lambda.Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hi"); }'), + deadLetterQueue: dlq, }); ``` @@ -457,11 +469,11 @@ to learn more about AWS Lambdas and DLQs. ## Lambda with X-Ray Tracing ```ts -const fn = new Function(this, 'MyFunction', { - runtime: Runtime.NODEJS_12_X, - handler: 'index.handler', - code: Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hi"); }'), - tracing: Tracing.ACTIVE +const fn = new lambda.Function(this, 'MyFunction', { + runtime: lambda.Runtime.NODEJS_12_X, + handler: 'index.handler', + code: lambda.Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hi"); }'), + tracing: lambda.Tracing.ACTIVE, }); ``` @@ -474,13 +486,11 @@ The following code configures the lambda function with CodeGuru profiling. By de profiling group - ```ts -import * as lambda from '@aws-cdk/aws-lambda'; - -const fn = new Function(this, 'MyFunction', { - runtime: Runtime.PYTHON_3_6, - handler: 'index.handler', - code: Code.fromAsset('lambda-handler'), - profiling: true +const fn = new lambda.Function(this, 'MyFunction', { + runtime: lambda.Runtime.PYTHON_3_6, + handler: 'index.handler', + code: lambda.Code.fromAsset('lambda-handler'), + profiling: true, }); ``` @@ -494,11 +504,11 @@ to learn more about AWS Lambda's Profiling support. ## Lambda with Reserved Concurrent Executions ```ts -const fn = new Function(this, 'MyFunction', { - runtime: Runtime.NODEJS_12_X, - handler: 'index.handler', - code: Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hi"); }'), - reservedConcurrentExecutions: 100 +const fn = new lambda.Function(this, 'MyFunction', { + runtime: lambda.Runtime.NODEJS_12_X, + handler: 'index.handler', + code: lambda.Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hi"); }'), + reservedConcurrentExecutions: 100, }); ``` @@ -509,15 +519,17 @@ managing concurrency. You can use Application AutoScaling to automatically configure the provisioned concurrency for your functions. AutoScaling can be set to track utilization or be based on a schedule. To configure AutoScaling on a function alias: -```ts fixture=function +```ts import * as autoscaling from '@aws-cdk/aws-autoscaling'; -const alias = new Alias(this, 'Alias', { + +declare const fn: lambda.Function; +const alias = new lambda.Alias(this, 'Alias', { aliasName: 'prod', version: fn.latestVersion, }); // Create AutoScaling target -const as = alias.addAutoScaling({ maxCapacity: 50 }) +const as = alias.addAutoScaling({ maxCapacity: 50 }); // Configure Target Tracking as.scaleOnUtilization({ @@ -591,12 +603,12 @@ const accessPoint = fileSystem.addAccessPoint('AccessPoint', { }, }); -const fn = new Function(this, 'MyLambda', { +const fn = new lambda.Function(this, 'MyLambda', { // mount the access point to /mnt/msg in the lambda runtime environment - filesystem: FileSystem.fromEfsAccessPoint(accessPoint, '/mnt/msg'), - runtime: Runtime.NODEJS_12_X, + filesystem: lambda.FileSystem.fromEfsAccessPoint(accessPoint, '/mnt/msg'), + runtime: lambda.Runtime.NODEJS_12_X, handler: 'index.handler', - code: Code.fromAsset(path.join(__dirname, 'lambda-handler')), + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), vpc, }); ``` @@ -626,17 +638,17 @@ Docker container is responsible for putting content at `/asset-output`. The cont Example with Python: ```ts -new Function(this, 'Function', { - code: Code.fromAsset(path.join(__dirname, 'my-python-handler'), { +new lambda.Function(this, 'Function', { + code: lambda.Code.fromAsset(path.join(__dirname, 'my-python-handler'), { bundling: { - image: Runtime.PYTHON_3_9.bundlingImage, + image: lambda.Runtime.PYTHON_3_9.bundlingImage, command: [ 'bash', '-c', 'pip install -r requirements.txt -t /asset-output && cp -au . /asset-output' ], }, }), - runtime: Runtime.PYTHON_3_9, + runtime: lambda.Runtime.PYTHON_3_9, handler: 'index.handler', }); ``` @@ -647,12 +659,10 @@ Use `cdk.DockerImage.fromRegistry(image)` to use an existing image or `cdk.DockerImage.fromBuild(path)` to build a specific image: ```ts -import * as cdk from '@aws-cdk/core'; - -new Function(this, 'Function', { - code: Code.fromAsset('/path/to/handler', { +new lambda.Function(this, 'Function', { + code: lambda.Code.fromAsset('/path/to/handler', { bundling: { - image: cdk.DockerImage.fromBuild('/path/to/dir/with/DockerFile', { + image: DockerImage.fromBuild('/path/to/dir/with/DockerFile', { buildArgs: { ARG1: 'value1', }, @@ -660,7 +670,7 @@ new Function(this, 'Function', { command: ['my', 'cool', 'command'], }, }), - runtime: Runtime.PYTHON_3_9, + runtime: lambda.Runtime.PYTHON_3_9, handler: 'index.handler', }); ``` @@ -679,21 +689,21 @@ When enabled, AWS Lambda checks every code deployment and verifies that the code For more information, see [Configuring code signing for AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/configuration-codesigning.html). The following code configures a function with code signing. -```typescript +```ts import * as signer from '@aws-cdk/aws-signer'; const signingProfile = new signer.SigningProfile(this, 'SigningProfile', { - platform: signer.Platform.AWS_LAMBDA_SHA384_ECDSA + platform: signer.Platform.AWS_LAMBDA_SHA384_ECDSA, }); -const codeSigningConfig = new CodeSigningConfig(this, 'CodeSigningConfig', { +const codeSigningConfig = new lambda.CodeSigningConfig(this, 'CodeSigningConfig', { signingProfiles: [signingProfile], }); -new Function(this, 'Function', { +new lambda.Function(this, 'Function', { codeSigningConfig, - runtime: Runtime.NODEJS_12_X, + runtime: lambda.Runtime.NODEJS_12_X, handler: 'index.handler', - code: Code.fromAsset(path.join(__dirname, 'lambda-handler')), + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), }); ``` diff --git a/packages/@aws-cdk/aws-lambda/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-lambda/rosetta/default.ts-fixture index 417454806bb9d..f473db8d31bd5 100644 --- a/packages/@aws-cdk/aws-lambda/rosetta/default.ts-fixture +++ b/packages/@aws-cdk/aws-lambda/rosetta/default.ts-fixture @@ -1,7 +1,9 @@ // Fixture with packages imported, but nothing else import * as path from 'path'; -import { Construct, Stack } from '@aws-cdk/core'; -import { Alias, Code, CodeSigningConfig, DockerImageCode, DockerImageFunction, FileSystem, Function, LayerVersion, Runtime, Tracing } from '@aws-cdk/aws-lambda'; +import { Construct } from 'constructs'; +import { DockerImage, RemovalPolicy, Stack } from '@aws-cdk/core'; +import * as lambda from '@aws-cdk/aws-lambda'; +import * as iam from '@aws-cdk/aws-iam'; class Fixture extends Stack { constructor(scope: Construct, id: string) { diff --git a/packages/@aws-cdk/aws-lambda/rosetta/function.ts-fixture b/packages/@aws-cdk/aws-lambda/rosetta/function.ts-fixture deleted file mode 100644 index 91eafe0abfcc0..0000000000000 --- a/packages/@aws-cdk/aws-lambda/rosetta/function.ts-fixture +++ /dev/null @@ -1,18 +0,0 @@ -// Fixture with function (`fn`) already created -import * as path from 'path'; -import { Construct, Stack } from '@aws-cdk/core'; -import { Alias, Code, Function, Runtime } from '@aws-cdk/aws-lambda'; - -class Fixture extends Stack { - constructor(scope: Construct, id: string) { - super(scope, id); - - const fn = new Function(this, 'MyFunction', { - runtime: Runtime.NODEJS_12_X, - handler: 'index.handler', - code: Code.fromAsset(path.join(__dirname, 'lambda-handler')), - }); - - /// here - } -} From 029eed9c8341545e090ec48ee97b47d25f4c3c56 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 28 Oct 2021 04:44:23 +0200 Subject: [PATCH 071/148] chore: upgrade to jsii 1.41 (#17190) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- package.json | 8 +- packages/awslint/package.json | 4 +- packages/decdk/package.json | 4 +- tools/@aws-cdk/cdk-build-tools/package.json | 6 +- yarn.lock | 162 ++++++++------------ 5 files changed, 74 insertions(+), 110 deletions(-) diff --git a/package.json b/package.json index 6115ddc36950c..7a521b7db98e1 100644 --- a/package.json +++ b/package.json @@ -20,10 +20,10 @@ "fs-extra": "^9.1.0", "graceful-fs": "^4.2.8", "jest-junit": "^12.3.0", - "jsii-diff": "^1.40.0", - "jsii-pacmak": "^1.40.0", - "jsii-reflect": "^1.40.0", - "jsii-rosetta": "^1.40.0", + "jsii-diff": "^1.41.0", + "jsii-pacmak": "^1.41.0", + "jsii-reflect": "^1.41.0", + "jsii-rosetta": "^1.41.0", "lerna": "^4.0.0", "patch-package": "^6.4.7", "standard-version": "^9.3.1", diff --git a/packages/awslint/package.json b/packages/awslint/package.json index 1bae6a09ba6cb..df07c732685ef 100644 --- a/packages/awslint/package.json +++ b/packages/awslint/package.json @@ -18,11 +18,11 @@ "awslint": "bin/awslint" }, "dependencies": { - "@jsii/spec": "^1.40.0", + "@jsii/spec": "^1.41.0", "camelcase": "^6.2.0", "colors": "^1.4.0", "fs-extra": "^9.1.0", - "jsii-reflect": "^1.40.0", + "jsii-reflect": "^1.41.0", "yargs": "^16.2.0" }, "devDependencies": { diff --git a/packages/decdk/package.json b/packages/decdk/package.json index 6a0a0eb5c0baa..7ebd9cc3d632c 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -244,7 +244,7 @@ "@aws-cdk/region-info": "0.0.0", "constructs": "^3.3.69", "fs-extra": "^9.1.0", - "jsii-reflect": "^1.40.0", + "jsii-reflect": "^1.41.0", "jsonschema": "^1.4.0", "yaml": "1.10.2", "yargs": "^16.2.0" @@ -255,7 +255,7 @@ "@types/yaml": "1.9.7", "@types/yargs": "^15.0.14", "jest": "^26.6.3", - "jsii": "^1.40.0" + "jsii": "^1.41.0" }, "keywords": [ "aws", diff --git a/tools/@aws-cdk/cdk-build-tools/package.json b/tools/@aws-cdk/cdk-build-tools/package.json index c8dfb507afc46..a99a32059c006 100644 --- a/tools/@aws-cdk/cdk-build-tools/package.json +++ b/tools/@aws-cdk/cdk-build-tools/package.json @@ -56,9 +56,9 @@ "fs-extra": "^9.1.0", "jest": "^27.3.1", "jest-junit": "^11.1.0", - "jsii": "^1.40.0", - "jsii-pacmak": "^1.40.0", - "jsii-reflect": "^1.40.0", + "jsii": "^1.41.0", + "jsii-pacmak": "^1.41.0", + "jsii-reflect": "^1.41.0", "markdownlint-cli": "^0.29.0", "nyc": "^15.1.0", "semver": "^7.3.5", diff --git a/yarn.lock b/yarn.lock index c63b92155ae6a..48ecde5d6ee28 100644 --- a/yarn.lock +++ b/yarn.lock @@ -760,10 +760,18 @@ chalk "^4.1.2" semver "^7.3.5" -"@jsii/spec@^1.40.0": - version "1.40.0" - resolved "https://registry.npmjs.org/@jsii/spec/-/spec-1.40.0.tgz#027dd2a9c2c0b49e5974ad6445728dde91569fe3" - integrity sha512-SJ9Kwz0C53bomYWb5PlESt6v8JmfgqqFjc1annNK+foHxcaUzs3trhKbBXgxhcoApE2pMnUIBj3DG9gLNmKdWw== +"@jsii/check-node@1.41.0": + version "1.41.0" + resolved "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.41.0.tgz#17b6895e1fcc0b8bbb8fa81b52b17c47c9c47674" + integrity sha512-lV/vMK1HZQcUye2vXPu6XsmnTk7fEui0GnQsPAX1eLWfRMkxkRblT4VZ9DQTYjMno2HuVP4IH51fiFoICMmnkA== + dependencies: + chalk "^4.1.2" + semver "^7.3.5" + +"@jsii/spec@^1.41.0": + version "1.41.0" + resolved "https://registry.npmjs.org/@jsii/spec/-/spec-1.41.0.tgz#d504c8536139a97986b1ec63201d3575972e1e9c" + integrity sha512-sN7x6C0DGLngiO6SkrM/7gVaHyeja59bDZODZtBXIq8kBIC+GgAFS8P0s1e5FpU9mHHvvHq4rvzvcIbxw0nkXw== dependencies: jsonschema "^1.4.0" @@ -2250,11 +2258,6 @@ ansi-regex@^2.0.0: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" @@ -3078,11 +3081,6 @@ co@^4.6.0: resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - codemaker@^1.39.0: version "1.39.0" resolved "https://registry.npmjs.org/codemaker/-/codemaker-1.39.0.tgz#d8103f4b587210b1d6aa073d62ffb510ac20bc42" @@ -3092,10 +3090,10 @@ codemaker@^1.39.0: decamelize "^5.0.1" fs-extra "^9.1.0" -codemaker@^1.40.0: - version "1.40.0" - resolved "https://registry.npmjs.org/codemaker/-/codemaker-1.40.0.tgz#80ed75a433fb08976c602b9080dc7fffbb13dbb9" - integrity sha512-X0dMlXILO5r9/YhNAbiLl9kNIfhATfGS8nAT7xC09zREipANnCEbjZuF8jtFGzrD942/k5QNROmqRtqRaZJ1QQ== +codemaker@^1.41.0: + version "1.41.0" + resolved "https://registry.npmjs.org/codemaker/-/codemaker-1.41.0.tgz#814edff6ffd241727794e76f81c5f9e4df135162" + integrity sha512-Iow0udcpshcVmztwSSJDTRhJxTbH0nXU3pxf7iF0gv6+BWC5Nd2aWQ2W5rHECySQPIvmWn4KEpV/SvXgvfl0aA== dependencies: camelcase "^6.2.0" decamelize "^5.0.1" @@ -5536,18 +5534,6 @@ is-extglob@^2.1.1: resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -6706,70 +6692,72 @@ jsesc@^2.5.1: resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== -jsii-diff@^1.40.0: - version "1.40.0" - resolved "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.40.0.tgz#97668273bc6c7f8ea6c6c27ebd8d70d433e1208d" - integrity sha512-Q0ctTmPE3wZ03CP++MxjPMBV3ynonDHq1gsd5mFUk9DW+cTyKb78KUkyjhgQnuiehXLRDQtoTlWJkH9C5xhEnQ== +jsii-diff@^1.41.0: + version "1.41.0" + resolved "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.41.0.tgz#ef88aa98081e4bb41f13d24074fce9bee1574d24" + integrity sha512-LTfqGh0f0fUuWu8DBkEUgl0fteIBfzyEiExcqLBXbztg/8JRbt3DYUr63hHULJj4O/rnRTaaYNH7oT1sg4gpSQ== dependencies: - "@jsii/check-node" "1.40.0" - "@jsii/spec" "^1.40.0" + "@jsii/check-node" "1.41.0" + "@jsii/spec" "^1.41.0" fs-extra "^9.1.0" - jsii-reflect "^1.40.0" + jsii-reflect "^1.41.0" log4js "^6.3.0" typescript "~3.9.10" yargs "^16.2.0" -jsii-pacmak@^1.40.0: - version "1.40.0" - resolved "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.40.0.tgz#5c0ecd5ff9c0917931bbe66773402dfe5517fbec" - integrity sha512-8IyvvWiD2eUpVhw0WXrYJILz+NSeNEwcWfQB+fUmn2gL8q27hlPZhHE7BVlr8+rb+EJVVLeHmpAMgA/SF9g/vQ== +jsii-pacmak@^1.41.0: + version "1.41.0" + resolved "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.41.0.tgz#b94575f4a7c658d3fbd1c5f30876ce53a22ed126" + integrity sha512-B3ohEObc2xSnWoawK0q4qVkxa9Dh4A+x1y9K31AAS5jGbhdjbdS/FfphlUbukIoSR0NBJLgJg9pT+h/PIlUqdA== dependencies: - "@jsii/check-node" "1.40.0" - "@jsii/spec" "^1.40.0" + "@jsii/check-node" "1.41.0" + "@jsii/spec" "^1.41.0" clone "^2.1.2" - codemaker "^1.40.0" + codemaker "^1.41.0" commonmark "^0.30.0" escape-string-regexp "^4.0.0" fs-extra "^9.1.0" - jsii-reflect "^1.40.0" - jsii-rosetta "^1.40.0" + jsii-reflect "^1.41.0" + jsii-rosetta "^1.41.0" semver "^7.3.5" spdx-license-list "^6.4.0" xmlbuilder "^15.1.1" yargs "^16.2.0" -jsii-reflect@^1.40.0: - version "1.40.0" - resolved "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.40.0.tgz#f8715f1506059d49294b32fe2c710753dd9545ba" - integrity sha512-/ccIjkRSfbHCl1MCfwWFaz2RjoAAiNH5teE95Qi11a4gbTu52WcOFIg3Y+8llzHmmLykr9jTDqBtgyzi9WI6dw== +jsii-reflect@^1.41.0: + version "1.41.0" + resolved "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.41.0.tgz#3c8fbcbbb7e2853b7c2a59384524ccbd2d9d832c" + integrity sha512-KQaAXQ38hyREs7IuBChZldSyvW1gezHRezGKGc6BZILwlIX330F3GIauJ2rJKJinh/Lo/DlMfd0k1mxdBz/W9A== dependencies: - "@jsii/check-node" "1.40.0" - "@jsii/spec" "^1.40.0" + "@jsii/check-node" "1.41.0" + "@jsii/spec" "^1.41.0" colors "^1.4.0" fs-extra "^9.1.0" - oo-ascii-tree "^1.40.0" + oo-ascii-tree "^1.41.0" yargs "^16.2.0" -jsii-rosetta@^1.40.0: - version "1.40.0" - resolved "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.40.0.tgz#eff34919ed9d4193ddb4a684f6108c82db3feb7c" - integrity sha512-Gb257CdUbHV8ZRFYflZy7F7alH5X49T+pX2133F7eaoMpRqc0V6jQsphaL4V+S/jK29XOfXtANmq55AvmwsWLQ== +jsii-rosetta@^1.41.0: + version "1.41.0" + resolved "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.41.0.tgz#ddf3f49738489d8330aa4eff96f0a9c8c811792d" + integrity sha512-wSjMqRBhjBKB8kx+gIXE7YXoiOlTFH/ugksHz2K4UwqriPmEHue8b7LkV3d/mD8xuhXWS6ekGAz67Gd1RSB7Sg== dependencies: - "@jsii/check-node" "1.40.0" - "@jsii/spec" "^1.40.0" + "@jsii/check-node" "1.41.0" + "@jsii/spec" "^1.41.0" "@xmldom/xmldom" "^0.7.5" commonmark "^0.30.0" fs-extra "^9.1.0" + sort-json "^2.0.0" typescript "~3.9.10" + workerpool "^6.1.5" yargs "^16.2.0" -jsii@^1.40.0: - version "1.40.0" - resolved "https://registry.npmjs.org/jsii/-/jsii-1.40.0.tgz#cc04f2bad5ae9495513af921cfcaca99dc8753d3" - integrity sha512-QUPmQzq7c/FREvtfw9+eIU16LB45hxRPtdLO2Ci2ZX1df4E4+vegtfvvjUJ21diVo2hwVp4UCftKqrXZ/cXEFg== +jsii@^1.41.0: + version "1.41.0" + resolved "https://registry.npmjs.org/jsii/-/jsii-1.41.0.tgz#926e033d7ba57c65d6d070dee1d4d19da0fa9508" + integrity sha512-5pjfWjSaMzE+mkpW//llBSGLcXJGNjE0KFSf73USPZTfJC09dBEJ4KJM85SogCNnWHwG5QecEpZStxNvt8GI7g== dependencies: - "@jsii/check-node" "1.40.0" - "@jsii/spec" "^1.40.0" + "@jsii/check-node" "1.41.0" + "@jsii/spec" "^1.41.0" case "^1.6.3" colors "^1.4.0" deep-equal "^2.0.5" @@ -7972,11 +7960,6 @@ null-check@^1.0.0: resolved "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" integrity sha1-l33/1xdgErnsMNKjnbXPcqBDnt0= -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" @@ -8113,10 +8096,10 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -oo-ascii-tree@^1.40.0: - version "1.40.0" - resolved "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.40.0.tgz#69005b8f5f140ed23a81e90b3659750dc3a62522" - integrity sha512-nkiEc8TJZwGxPdEB1jRxHWyc/qBTPQSf70KhO+WjuiWzVfLVEWF/dksWRjm8e510YmPrBjfYCJOn+BVlOUojSQ== +oo-ascii-tree@^1.41.0: + version "1.41.0" + resolved "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.41.0.tgz#88883d2b8446ded7082a96faf3294e1092aeeb46" + integrity sha512-WxQIFO+JMCIJBlIMUATsp+PW5kqDMy2CD7u5uC9qQk29XInUMO+RN7/QVZJsPHO3o73eJFN9CFc9XDWQJwVKBQ== open@^7.4.2: version "7.4.2" @@ -9599,7 +9582,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -string-width@*, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +string-width@*, string-width@^1.0.1, "string-width@^1.0.2 || 2", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -9608,23 +9591,6 @@ string-width@*, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - string.prototype.repeat@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz#aba36de08dcee6a5a337d49b2ea1da1b28fc0ecf" @@ -9677,13 +9643,6 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" @@ -10540,6 +10499,11 @@ wordwrap@>=0.0.2, wordwrap@^1.0.0: resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= +workerpool@^6.1.5: + version "6.1.5" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" + integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" From 5cee43e73a836addf5554d74c617f543a450249d Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 28 Oct 2021 05:41:35 +0200 Subject: [PATCH 072/148] chore: activate 'rosetta infuse' feature (#17191) `jsii-rosetta infuse` will modify all the assemblies in-place to add examples to types that don't have examples yet. This feature depends on jsii 1.41, and should not be merged before jsii has been upgraded to that version (either by #17187 or by #17190). Depends-On: #17190 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- pack.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pack.sh b/pack.sh index 168a17f972406..3c2d7dbce6c1a 100755 --- a/pack.sh +++ b/pack.sh @@ -39,12 +39,17 @@ function lerna_scopes() { # Compile examples with respect to "decdk" directory, as all packages will # be symlinked there so they can all be included. echo "Extracting code samples" >&2 -node --experimental-worker $(which $ROSETTA) \ +$ROSETTA extract \ --compile \ --output samples.tabl.json \ --directory packages/decdk \ $(cat $TMPDIR/jsii.txt) +echo "Infusing examples back into assemblies" >&2 +$ROSETTA infuse \ + samples.tabl.json \ + $(cat $TMPDIR/jsii.txt) + # Jsii packaging (all at once using jsii-pacmak) echo "Packaging jsii modules" >&2 $PACMAK \ From 758568007bf82a97ed6edba3ef4717735b224bf9 Mon Sep 17 00:00:00 2001 From: Kyle Roach Date: Thu, 28 Oct 2021 04:34:47 +0000 Subject: [PATCH 073/148] feat(codebuild): add fromEcrRepository to LinuxGpuBuildImage (#17170) Resolves #16500 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-codebuild/README.md | 2 + .../lib/linux-gpu-build-image.ts | 16 ++ .../test/linux-gpu-build-image.test.ts | 174 ++++++++++++++++++ packages/@aws-cdk/aws-ecr/lib/repository.ts | 4 +- 4 files changed, 195 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-codebuild/README.md b/packages/@aws-cdk/aws-codebuild/README.md index ff73599bca8e4..8a5fa30ac408b 100644 --- a/packages/@aws-cdk/aws-codebuild/README.md +++ b/packages/@aws-cdk/aws-codebuild/README.md @@ -320,6 +320,8 @@ new codebuild.Project(this, 'Project', { }) ``` +Alternatively, you can reference an image available in an ECR repository using the `LinuxGpuBuildImage.fromEcrRepository(repo[, tag])` method. + ## Logs CodeBuild lets you specify an S3 Bucket, CloudWatch Log Group or both to receive logs from your projects. diff --git a/packages/@aws-cdk/aws-codebuild/lib/linux-gpu-build-image.ts b/packages/@aws-cdk/aws-codebuild/lib/linux-gpu-build-image.ts index 6cbf5bcfc2f7e..b26611745afbb 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/linux-gpu-build-image.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/linux-gpu-build-image.ts @@ -91,6 +91,22 @@ export class LinuxGpuBuildImage implements IBindableBuildImage { return new LinuxGpuBuildImage(repositoryName, tag, account); } + + /** + * Returns a GPU image running Linux from an ECR repository. + * + * NOTE: if the repository is external (i.e. imported), then we won't be able to add + * a resource policy statement for it so CodeBuild can pull the image. + * + * @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-ecr.html + * + * @param repository The ECR repository + * @param tag Image tag (default "latest") + */ + public static fromEcrRepository(repository: ecr.IRepository, tag: string = 'latest'): IBuildImage { + return new LinuxGpuBuildImage(repository.repositoryName, tag, repository.env.account); + } + public readonly type = 'LINUX_GPU_CONTAINER'; public readonly defaultComputeType = ComputeType.LARGE; public readonly imageId: string; diff --git a/packages/@aws-cdk/aws-codebuild/test/linux-gpu-build-image.test.ts b/packages/@aws-cdk/aws-codebuild/test/linux-gpu-build-image.test.ts index 7e32ab033c68c..d3b0d44dde984 100644 --- a/packages/@aws-cdk/aws-codebuild/test/linux-gpu-build-image.test.ts +++ b/packages/@aws-cdk/aws-codebuild/test/linux-gpu-build-image.test.ts @@ -1,5 +1,6 @@ import { arrayWith, objectLike } from '@aws-cdk/assert-internal'; import '@aws-cdk/assert-internal/jest'; +import * as ecr from '@aws-cdk/aws-ecr'; import * as cdk from '@aws-cdk/core'; import * as codebuild from '../lib'; @@ -58,4 +59,177 @@ describe('Linux GPU build image', () => { }); }); }); + + describe('ECR Repository', () => { + test('allows creating a build image from a new ECR repository', () => { + const stack = new cdk.Stack(); + + const repository = new ecr.Repository(stack, 'my-repo'); + + new codebuild.Project(stack, 'Project', { + buildSpec: codebuild.BuildSpec.fromObject({ + version: '0.2', + phases: { + build: { commands: ['ls'] }, + }, + }), + environment: { + buildImage: codebuild.LinuxGpuBuildImage.fromEcrRepository(repository, 'v1'), + }, + }); + + expect(stack).toHaveResourceLike('AWS::CodeBuild::Project', { + Environment: { + ComputeType: 'BUILD_GENERAL1_LARGE', + Image: { + 'Fn::Join': ['', [ + { Ref: 'AWS::AccountId' }, + '.dkr.ecr.', + { Ref: 'AWS::Region' }, + '.', + { Ref: 'AWS::URLSuffix' }, + '/', + { Ref: 'myrepo5DFA62E5' }, + ':v1', + ]], + }, + }, + }); + + expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Statement: arrayWith(objectLike({ + Action: [ + 'ecr:BatchCheckLayerAvailability', + 'ecr:GetDownloadUrlForLayer', + 'ecr:BatchGetImage', + ], + Resource: { + 'Fn::Join': ['', [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':ecr:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':repository/', + { Ref: 'myrepo5DFA62E5' }, + ]], + }, + })), + }, + }); + }); + + test('allows creating a build image from an existing ECR repository', () => { + const stack = new cdk.Stack(); + + const repository = ecr.Repository.fromRepositoryName(stack, 'my-imported-repo', 'test-repo'); + + new codebuild.Project(stack, 'Project', { + buildSpec: codebuild.BuildSpec.fromObject({ + version: '0.2', + phases: { + build: { commands: ['ls'] }, + }, + }), + environment: { + buildImage: codebuild.LinuxGpuBuildImage.fromEcrRepository(repository), + }, + }); + + expect(stack).toHaveResourceLike('AWS::CodeBuild::Project', { + Environment: { + ComputeType: 'BUILD_GENERAL1_LARGE', + Image: { + 'Fn::Join': ['', [ + { Ref: 'AWS::AccountId' }, + '.dkr.ecr.', + { Ref: 'AWS::Region' }, + '.', + { Ref: 'AWS::URLSuffix' }, + '/test-repo:latest', + ]], + }, + }, + }); + + expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Statement: arrayWith(objectLike({ + Action: [ + 'ecr:BatchCheckLayerAvailability', + 'ecr:GetDownloadUrlForLayer', + 'ecr:BatchGetImage', + ], + Resource: { + 'Fn::Join': ['', [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':ecr:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':repository/test-repo', + ]], + }, + })), + }, + }); + }); + + test('allows creating a build image from an existing cross-account ECR repository', () => { + const stack = new cdk.Stack(); + + const repository = ecr.Repository.fromRepositoryArn(stack, 'my-cross-acount-repo', 'arn:aws:ecr:us-east-1:585695036304:repository/foo/bar/foo/fooo'); + + new codebuild.Project(stack, 'Project', { + buildSpec: codebuild.BuildSpec.fromObject({ + version: '0.2', + phases: { + build: { commands: ['ls'] }, + }, + }), + environment: { + buildImage: codebuild.LinuxGpuBuildImage.fromEcrRepository(repository), + }, + }); + + expect(stack).toHaveResourceLike('AWS::CodeBuild::Project', { + Environment: { + ComputeType: 'BUILD_GENERAL1_LARGE', + Image: { + 'Fn::Join': ['', [ + '585695036304.dkr.ecr.', + { Ref: 'AWS::Region' }, + '.', + { Ref: 'AWS::URLSuffix' }, + '/foo/bar/foo/fooo:latest', + ]], + }, + }, + }); + + expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Statement: arrayWith(objectLike({ + Action: [ + 'ecr:BatchCheckLayerAvailability', + 'ecr:GetDownloadUrlForLayer', + 'ecr:BatchGetImage', + ], + Resource: { + 'Fn::Join': ['', [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':ecr:', + { Ref: 'AWS::Region' }, + ':585695036304:repository/foo/bar/foo/fooo', + ]], + }, + })), + }, + }); + }); + }); }); diff --git a/packages/@aws-cdk/aws-ecr/lib/repository.ts b/packages/@aws-cdk/aws-ecr/lib/repository.ts index af8547ba5edaf..0511290e113a5 100644 --- a/packages/@aws-cdk/aws-ecr/lib/repository.ts +++ b/packages/@aws-cdk/aws-ecr/lib/repository.ts @@ -411,7 +411,9 @@ export class Repository extends RepositoryBase { } } - return new Import(scope, id); + return new Import(scope, id, { + environmentFromArn: repositoryArn, + }); } public static fromRepositoryName(scope: Construct, id: string, repositoryName: string): IRepository { From 1f570e84e48e157b36d84bfb8434e50484d7f3e2 Mon Sep 17 00:00:00 2001 From: Madeline Kusters <80541297+madeline-k@users.noreply.github.com> Date: Wed, 27 Oct 2021 22:28:55 -0700 Subject: [PATCH 074/148] chore(aws-applicationautoscaling): add unit tests to increase branch coverage (#17173) increasing branch coverage from 74/75% to 80% ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../test/scalable-target.test.ts | 107 +++++++++++++++--- .../test/{cron.test.ts => schedule.test.ts} | 15 +++ 2 files changed, 105 insertions(+), 17 deletions(-) rename packages/@aws-cdk/aws-applicationautoscaling/test/{cron.test.ts => schedule.test.ts} (79%) diff --git a/packages/@aws-cdk/aws-applicationautoscaling/test/scalable-target.test.ts b/packages/@aws-cdk/aws-applicationautoscaling/test/scalable-target.test.ts index 8628a8624468c..508ae3bb2c9e2 100644 --- a/packages/@aws-cdk/aws-applicationautoscaling/test/scalable-target.test.ts +++ b/packages/@aws-cdk/aws-applicationautoscaling/test/scalable-target.test.ts @@ -1,5 +1,6 @@ import '@aws-cdk/assert-internal/jest'; import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; +import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; import * as appscaling from '../lib'; import { createScalableTarget } from './util'; @@ -26,8 +27,6 @@ describe('scalable target', () => { MinCapacity: 1, MaxCapacity: 20, }); - - }); test('validation does not fail when using Tokens', () => { @@ -51,8 +50,6 @@ describe('scalable target', () => { MinCapacity: 10, MaxCapacity: 1, }); - - }); test('add scheduled scaling', () => { @@ -80,8 +77,6 @@ describe('scalable target', () => { }, ], }); - - }); test('step scaling on MathExpression', () => { @@ -136,21 +131,99 @@ describe('scalable target', () => { ], Threshold: 49, }); + }); + test('test service namespace enum', () => { + expect(appscaling.ServiceNamespace.APPSTREAM).toEqual('appstream'); + expect(appscaling.ServiceNamespace.COMPREHEND).toEqual('comprehend'); + expect(appscaling.ServiceNamespace.CUSTOM_RESOURCE).toEqual('custom-resource'); + expect(appscaling.ServiceNamespace.DYNAMODB).toEqual('dynamodb'); + expect(appscaling.ServiceNamespace.EC2).toEqual('ec2'); + expect(appscaling.ServiceNamespace.ECS).toEqual('ecs'); + expect(appscaling.ServiceNamespace.ELASTIC_MAP_REDUCE).toEqual('elasticmapreduce'); + expect(appscaling.ServiceNamespace.LAMBDA).toEqual('lambda'); + expect(appscaling.ServiceNamespace.RDS).toEqual('rds'); + expect(appscaling.ServiceNamespace.SAGEMAKER).toEqual('sagemaker'); + }); + test('create scalable target with negative minCapacity throws error', () => { + const stack = new cdk.Stack(); + expect(() => { + new appscaling.ScalableTarget(stack, 'Target', { + serviceNamespace: appscaling.ServiceNamespace.DYNAMODB, + scalableDimension: 'test:TestCount', + resourceId: 'test:this/test', + minCapacity: -1, + maxCapacity: 20, + }); + }).toThrow('minCapacity cannot be negative, got: -1'); }); - test('test service namespace enum', () => { - expect(appscaling.ServiceNamespace.APPSTREAM).toEqual( 'appstream'); - expect(appscaling.ServiceNamespace.COMPREHEND).toEqual( 'comprehend'); - expect(appscaling.ServiceNamespace.CUSTOM_RESOURCE).toEqual( 'custom-resource'); - expect(appscaling.ServiceNamespace.DYNAMODB).toEqual( 'dynamodb'); - expect(appscaling.ServiceNamespace.EC2).toEqual( 'ec2'); - expect(appscaling.ServiceNamespace.ECS).toEqual( 'ecs'); - expect(appscaling.ServiceNamespace.ELASTIC_MAP_REDUCE).toEqual( 'elasticmapreduce'); - expect(appscaling.ServiceNamespace.LAMBDA).toEqual( 'lambda'); - expect(appscaling.ServiceNamespace.RDS).toEqual( 'rds'); - expect(appscaling.ServiceNamespace.SAGEMAKER).toEqual( 'sagemaker'); + test('create scalable target with negative maxCapacity throws error', () => { + const stack = new cdk.Stack(); + expect(() => { + new appscaling.ScalableTarget(stack, 'Target', { + serviceNamespace: appscaling.ServiceNamespace.DYNAMODB, + scalableDimension: 'test:TestCount', + resourceId: 'test:this/test', + minCapacity: 1, + maxCapacity: -1, + }); + }).toThrow('maxCapacity cannot be negative, got: -1'); + }); + + test('create scalable target with maxCapacity less than minCapacity throws error', () => { + const stack = new cdk.Stack(); + expect(() => { + new appscaling.ScalableTarget(stack, 'Target', { + serviceNamespace: appscaling.ServiceNamespace.DYNAMODB, + scalableDimension: 'test:TestCount', + resourceId: 'test:this/test', + minCapacity: 2, + maxCapacity: 1, + }); + }).toThrow('minCapacity (2) should be lower than maxCapacity (1)'); + }); + test('create scalable target with custom role', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new appscaling.ScalableTarget(stack, 'Target', { + serviceNamespace: appscaling.ServiceNamespace.DYNAMODB, + scalableDimension: 'test:TestCount', + resourceId: 'test:this/test', + minCapacity: 1, + maxCapacity: 20, + role: new iam.Role(stack, 'Role', { + assumedBy: new iam.ServicePrincipal('test.amazonaws.com'), + }), + }); + + // THEN + expect(stack).toHaveResource('AWS::ApplicationAutoScaling::ScalableTarget', { + ServiceNamespace: 'dynamodb', + ScalableDimension: 'test:TestCount', + ResourceId: 'test:this/test', + MinCapacity: 1, + MaxCapacity: 20, + RoleARN: { + 'Fn::GetAtt': [ + 'Role1ABCC5F0', + 'Arn', + ], + }, + }); + }); + + test('add scheduled scaling with neither of min/maxCapacity defined throws error', () => { + const stack = new cdk.Stack(); + const target = createScalableTarget(stack); + expect(() => { + target.scaleOnSchedule('ScaleUp', { + schedule: appscaling.Schedule.rate(cdk.Duration.minutes(1)), + }); + }).toThrow(/You must supply at least one of minCapacity or maxCapacity, got/); }); }); diff --git a/packages/@aws-cdk/aws-applicationautoscaling/test/cron.test.ts b/packages/@aws-cdk/aws-applicationautoscaling/test/schedule.test.ts similarity index 79% rename from packages/@aws-cdk/aws-applicationautoscaling/test/cron.test.ts rename to packages/@aws-cdk/aws-applicationautoscaling/test/schedule.test.ts index b3c337883146c..6583be41f97c5 100644 --- a/packages/@aws-cdk/aws-applicationautoscaling/test/cron.test.ts +++ b/packages/@aws-cdk/aws-applicationautoscaling/test/schedule.test.ts @@ -11,7 +11,9 @@ describe('cron', () => { expect(appscaling.Schedule.cron({ hour: '18', minute: '24' }).expressionString).toEqual('cron(24 18 * * ? *)'); }); +}); +describe('rate', () => { test('rate must be whole number of minutes', () => { expect(() => { appscaling.Schedule.rate(Duration.minutes(0.13456)); @@ -53,3 +55,16 @@ describe('cron', () => { }); }); + +describe('expression', () => { + test('test using a literal schedule expression', () => { + expect(appscaling.Schedule.expression('cron(0 18 * * ? *)').expressionString).toEqual('cron(0 18 * * ? *)'); + + }); +}); + +describe('at', () => { + test('test using at with a specific Date', () => { + expect(appscaling.Schedule.at(new Date(2021, 10, 26)).expressionString).toEqual('at(2021-11-26T00:00:00)'); + }); +}); From c4ba858278bffe1a987ea8200c313f17f7f1cbe9 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 28 Oct 2021 12:02:52 +0200 Subject: [PATCH 075/148] chore: revert activate 'rosetta infuse' feature (#17207) The examples we copy into docblocks may contain block comments themselves. However, the docblock renderer does not escape the docblock *closing* text, so the doc block gets terminated early and compiling fails: ```java /** * Initialization props for the `NestedStack` construct. *

* Example: *

*

{@code
 * // Example automatically generated. See https://github.com/aws/jsii/issues/826
 * import software.amazon.awscdk.core.App;
 * import software.amazon.awscdk.core.CfnOutput;
 * import software.amazon.awscdk.core.NestedStack;
 * import lib.RestApi;
 * import lib.Stage;
 * /**
 *  * This file showcases how to split up a RestApi's Resources and Methods across nested stacks.
 *  *
 *  * The root stack 'RootStack' first defines a RestApi.
 *  * Two nested stacks BooksStack and PetsStack, create corresponding Resources '/books' and '/pets'.
 *  * They are then deployed to a 'prod' Stage via a third nested stack - DeployStack.
 *  *
 *  * To verify this worked, go to the APIGateway
 *  */    <------------ OOOPS!
 * public class RootStack extends Stack {
 *     public RootStack(Construct scope) {
 *         super(scope, "integ-restapi-import-RootStack");
 *         RestApi restApi = RestApi.Builder.cre

```

Revert this until we can address the quoting issue.

Reverts aws/aws-cdk#17191
---
 pack.sh | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/pack.sh b/pack.sh
index 3c2d7dbce6c1a..168a17f972406 100755
--- a/pack.sh
+++ b/pack.sh
@@ -39,17 +39,12 @@ function lerna_scopes() {
 # Compile examples with respect to "decdk" directory, as all packages will
 # be symlinked there so they can all be included.
 echo "Extracting code samples" >&2
-$ROSETTA extract \
+node --experimental-worker $(which $ROSETTA) \
   --compile \
   --output samples.tabl.json \
   --directory packages/decdk \
   $(cat $TMPDIR/jsii.txt)
 
-echo "Infusing examples back into assemblies" >&2
-$ROSETTA infuse \
-  samples.tabl.json \
-  $(cat $TMPDIR/jsii.txt)
-
 # Jsii packaging (all at once using jsii-pacmak)
 echo "Packaging jsii modules" >&2
 $PACMAK \

From bc07cb0e383aa64280a9c7f8ac4870d296830cf7 Mon Sep 17 00:00:00 2001
From: Ryan Parker 
Date: Thu, 28 Oct 2021 04:10:15 -0700
Subject: [PATCH 076/148] feat(aws-route53-targets): Support for Elastic
 Beanstalk environment URLs (#16305)

## Summary

This PR adds a new Route53 target `ElasticBeanstalkEnvironmentTarget` for creating RecordSets that target Elastic Beanstalk environment URLs.

E.g.

```ts
const ebsEnvironmentUrl = 'mysampleenvironment.xyz.us-east-1.elasticbeanstalk.com';

new route53.ARecord(this, 'AliasRecord', {
	zone,
    target: route53.RecordTarget.fromAlias(new alias.ElasticBeanstalkEnvironmentTarget(ebsEnvironmentUrl)),
});
```

[How to find your Elastic Beanstalk environment URL](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-beanstalk-environment.html#routing-to-beanstalk-environment-get-domain-name)

Fixes: https://github.com/aws/aws-cdk/issues/3206


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../@aws-cdk/aws-route53-targets/README.md    | 11 +++++++
 .../elastic-beanstalk-environment-target.ts   | 33 +++++++++++++++++++
 .../@aws-cdk/aws-route53-targets/lib/index.ts |  1 +
 ...astic-beanstalk-environment-target.test.ts | 25 ++++++++++++++
 .../region-info/build-tools/fact-tables.ts    | 31 +++++++++++++++++
 .../build-tools/generate-static-data.ts       |  5 ++-
 packages/@aws-cdk/region-info/lib/fact.ts     |  5 +++
 .../@aws-cdk/region-info/lib/region-info.ts   |  7 ++++
 8 files changed, 117 insertions(+), 1 deletion(-)
 create mode 100644 packages/@aws-cdk/aws-route53-targets/lib/elastic-beanstalk-environment-target.ts
 create mode 100644 packages/@aws-cdk/aws-route53-targets/test/elastic-beanstalk-environment-target.test.ts

diff --git a/packages/@aws-cdk/aws-route53-targets/README.md b/packages/@aws-cdk/aws-route53-targets/README.md
index 07be5b2e363d0..6c703ad5adc8f 100644
--- a/packages/@aws-cdk/aws-route53-targets/README.md
+++ b/packages/@aws-cdk/aws-route53-targets/README.md
@@ -129,4 +129,15 @@ See [the Developer Guide](https://docs.aws.amazon.com/Route53/latest/DeveloperGu
   });
   ```
 
+* Elastic Beanstalk environment:
+
+**Important:** Only supports Elastic Beanstalk environments created after 2016 that have a regional endpoint.
+
+  ```ts
+  new route53.ARecord(this, 'AliasRecord', {
+    zone,
+    target: route53.RecordTarget.fromAlias(new alias.ElasticBeanstalkEnvironmentEndpointTarget(ebsEnvironmentUrl)),
+  });
+  ```
+
 See the documentation of `@aws-cdk/aws-route53` for more information.
diff --git a/packages/@aws-cdk/aws-route53-targets/lib/elastic-beanstalk-environment-target.ts b/packages/@aws-cdk/aws-route53-targets/lib/elastic-beanstalk-environment-target.ts
new file mode 100644
index 0000000000000..ef48c2845c233
--- /dev/null
+++ b/packages/@aws-cdk/aws-route53-targets/lib/elastic-beanstalk-environment-target.ts
@@ -0,0 +1,33 @@
+import * as route53 from '@aws-cdk/aws-route53';
+import * as cdk from '@aws-cdk/core';
+import { RegionInfo } from '@aws-cdk/region-info';
+
+/**
+ * Use an Elastic Beanstalk environment URL as an alias record target.
+ * E.g. mysampleenvironment.xyz.us-east-1.elasticbeanstalk.com
+ *
+ * Only supports Elastic Beanstalk environments created after 2016 that have a regional endpoint.
+ */
+export class ElasticBeanstalkEnvironmentEndpointTarget implements route53.IAliasRecordTarget {
+  constructor(private readonly environmentEndpoint: string) {
+  }
+
+  public bind(_record: route53.IRecordSet, _zone?: route53.IHostedZone): route53.AliasRecordTargetConfig {
+    if (cdk.Token.isUnresolved(this.environmentEndpoint)) {
+      throw new Error('Cannot use an EBS alias as `environmentEndpoint`. You must find your EBS environment endpoint via the AWS console. See the Elastic Beanstalk developer guide: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customdomains.html');
+    }
+
+    const dnsName = this.environmentEndpoint;
+    const region = cdk.Fn.select(2, cdk.Fn.split('.', dnsName));
+    const { ebsEnvEndpointHostedZoneId: hostedZoneId } = RegionInfo.get(region);
+
+    if (!hostedZoneId || !dnsName) {
+      throw new Error(`Elastic Beanstalk environment target is not supported for the "${region}" region.`);
+    }
+
+    return {
+      hostedZoneId,
+      dnsName,
+    };
+  }
+}
diff --git a/packages/@aws-cdk/aws-route53-targets/lib/index.ts b/packages/@aws-cdk/aws-route53-targets/lib/index.ts
index 92f1d9ee08d25..714719322b883 100644
--- a/packages/@aws-cdk/aws-route53-targets/lib/index.ts
+++ b/packages/@aws-cdk/aws-route53-targets/lib/index.ts
@@ -1,6 +1,7 @@
 export * from './api-gateway-domain-name';
 export * from './api-gatewayv2-domain-name';
 export * from './bucket-website-target';
+export * from './elastic-beanstalk-environment-target';
 export * from './classic-load-balancer-target';
 export * from './cloudfront-target';
 export * from './load-balancer-target';
diff --git a/packages/@aws-cdk/aws-route53-targets/test/elastic-beanstalk-environment-target.test.ts b/packages/@aws-cdk/aws-route53-targets/test/elastic-beanstalk-environment-target.test.ts
new file mode 100644
index 0000000000000..ed18f49362118
--- /dev/null
+++ b/packages/@aws-cdk/aws-route53-targets/test/elastic-beanstalk-environment-target.test.ts
@@ -0,0 +1,25 @@
+import '@aws-cdk/assert-internal/jest';
+import * as route53 from '@aws-cdk/aws-route53';
+import { Stack } from '@aws-cdk/core';
+import * as targets from '../lib';
+
+test('use EBS environment as record target', () => {
+  // GIVEN
+  const stack = new Stack();
+  const zone = new route53.PublicHostedZone(stack, 'HostedZone', { zoneName: 'test.public' });
+
+  // WHEN
+  new route53.ARecord(stack, 'Alias', {
+    zone,
+    recordName: '_foo',
+    target: route53.RecordTarget.fromAlias(new targets.ElasticBeanstalkEnvironmentEndpointTarget('mysampleenvironment.xyz.us-east-1.elasticbeanstalk.com')),
+  });
+
+  // THEN
+  expect(stack).toHaveResource('AWS::Route53::RecordSet', {
+    AliasTarget: {
+      DNSName: 'mysampleenvironment.xyz.us-east-1.elasticbeanstalk.com',
+      HostedZoneId: 'Z117KPS5GTRQ2G',
+    },
+  });
+});
diff --git a/packages/@aws-cdk/region-info/build-tools/fact-tables.ts b/packages/@aws-cdk/region-info/build-tools/fact-tables.ts
index 0e1f923dc2a02..6d95f24e5a7e8 100644
--- a/packages/@aws-cdk/region-info/build-tools/fact-tables.ts
+++ b/packages/@aws-cdk/region-info/build-tools/fact-tables.ts
@@ -72,6 +72,37 @@ export const ROUTE_53_BUCKET_WEBSITE_ZONE_IDS: { [region: string]: string } = {
   'us-west-2': 'Z3BJ6K6RIION7M',
 };
 
+/**
+ * The hosted zone Id of the Elastic Beanstalk environment.
+ *
+ * @see https://docs.aws.amazon.com/general/latest/gr/elasticbeanstalk.html
+ */
+export const EBS_ENV_ENDPOINT_HOSTED_ZONE_IDS: { [region: string]: string } = {
+  'af-south-1': 'Z1EI3BVKMKK4AM',
+  'ap-east-1': 'ZPWYUBWRU171A',
+  'ap-northeast-1': 'Z1R25G3KIG2GBW',
+  'ap-northeast-2': 'Z3JE5OI70TWKCP',
+  'ap-northeast-3': 'ZNE5GEY1TIAGY',
+  'ap-south-1': 'Z18NTBI3Y7N9TZ',
+  'ap-southeast-1': 'Z16FZ9L249IFLT',
+  'ap-southeast-2': 'Z2PCDNR3VC2G1N',
+  'ca-central-1': 'ZJFCZL7SSZB5I',
+  'eu-central-1': 'Z1FRNW7UH4DEZJ',
+  'eu-north-1': 'Z23GO28BZ5AETM',
+  'eu-south-1': 'Z10VDYYOA2JFKM',
+  'eu-west-1': 'Z2NYPWQ7DFZAZH',
+  'eu-west-2': 'Z1GKAAAUGATPF1',
+  'eu-west-3': 'Z5WN6GAYWG5OB',
+  'me-south-1': 'Z2BBTEKR2I36N2',
+  'sa-east-1': 'Z10X7K2B4QSOFV',
+  'us-east-1': 'Z117KPS5GTRQ2G',
+  'us-east-2': 'Z14LCN19Q5QHIC',
+  'us-gov-east-1': 'Z35TSARG0EJ4VU',
+  'us-gov-west-1': 'Z4KAURWC4UUUG',
+  'us-west-1': 'Z1LQECGX5PH1X',
+  'us-west-2': 'Z38NKT9BP95V3O',
+};
+
 interface Region { partition: string, domainSuffix: string }
 
 export const PARTITION_MAP: { [region: string]: Region } = {
diff --git a/packages/@aws-cdk/region-info/build-tools/generate-static-data.ts b/packages/@aws-cdk/region-info/build-tools/generate-static-data.ts
index dd42309b78c8a..006de89d3994d 100644
--- a/packages/@aws-cdk/region-info/build-tools/generate-static-data.ts
+++ b/packages/@aws-cdk/region-info/build-tools/generate-static-data.ts
@@ -4,7 +4,7 @@ import { Default } from '../lib/default';
 import { AWS_REGIONS, AWS_SERVICES } from './aws-entities';
 import {
   APPMESH_ECR_ACCOUNTS, AWS_CDK_METADATA, AWS_OLDER_REGIONS, CLOUDWATCH_LAMBDA_INSIGHTS_ARNS, DLC_REPOSITORY_ACCOUNTS,
-  ELBV2_ACCOUNTS, FIREHOSE_CIDR_BLOCKS, PARTITION_MAP, ROUTE_53_BUCKET_WEBSITE_ZONE_IDS,
+  ELBV2_ACCOUNTS, FIREHOSE_CIDR_BLOCKS, PARTITION_MAP, ROUTE_53_BUCKET_WEBSITE_ZONE_IDS, EBS_ENV_ENDPOINT_HOSTED_ZONE_IDS,
 } from './fact-tables';
 
 async function main(): Promise {
@@ -57,6 +57,9 @@ async function main(): Promise {
 
     registerFact(region, 'S3_STATIC_WEBSITE_ZONE_53_HOSTED_ZONE_ID', ROUTE_53_BUCKET_WEBSITE_ZONE_IDS[region] || '');
 
+    registerFact(region, 'EBS_ENV_ENDPOINT_HOSTED_ZONE_ID', EBS_ENV_ENDPOINT_HOSTED_ZONE_IDS[region] || '');
+
+
     registerFact(region, 'ELBV2_ACCOUNT', ELBV2_ACCOUNTS[region]);
 
     registerFact(region, 'DLC_REPOSITORY_ACCOUNT', DLC_REPOSITORY_ACCOUNTS[region]);
diff --git a/packages/@aws-cdk/region-info/lib/fact.ts b/packages/@aws-cdk/region-info/lib/fact.ts
index c099aced9fd55..8d4e33802be43 100644
--- a/packages/@aws-cdk/region-info/lib/fact.ts
+++ b/packages/@aws-cdk/region-info/lib/fact.ts
@@ -128,6 +128,11 @@ export class FactName {
    */
   public static readonly S3_STATIC_WEBSITE_ZONE_53_HOSTED_ZONE_ID = 's3-static-website:route-53-hosted-zone-id';
 
+  /**
+   * The hosted zone ID used by Route 53 to alias a EBS environment endpoint in this region (e.g: Z2O1EMRO9K5GLX)
+   */
+  public static readonly EBS_ENV_ENDPOINT_HOSTED_ZONE_ID = 'ebs-environment:route-53-hosted-zone-id';
+
   /**
    * The prefix for VPC Endpoint Service names,
    * cn.com.amazonaws.vpce for China regions,
diff --git a/packages/@aws-cdk/region-info/lib/region-info.ts b/packages/@aws-cdk/region-info/lib/region-info.ts
index baa2c43635892..3482acf66b9a1 100644
--- a/packages/@aws-cdk/region-info/lib/region-info.ts
+++ b/packages/@aws-cdk/region-info/lib/region-info.ts
@@ -77,6 +77,13 @@ export class RegionInfo {
     return Fact.find(this.name, FactName.S3_STATIC_WEBSITE_ZONE_53_HOSTED_ZONE_ID);
   }
 
+  /**
+  * The hosted zone ID used by Route 53 to alias a EBS environment endpoint in this region (e.g: Z2O1EMRO9K5GLX)
+  */
+  public get ebsEnvEndpointHostedZoneId(): string | undefined {
+    return Fact.find(this.name, FactName.EBS_ENV_ENDPOINT_HOSTED_ZONE_ID);
+  }
+
   /**
    * The prefix for VPC Endpoint Service names,
    * cn.com.amazonaws.vpce for China regions,

From c24af54946d3668afa596dbf2a776b7cf21f8a99 Mon Sep 17 00:00:00 2001
From: Zack Ganger 
Date: Thu, 28 Oct 2021 08:08:20 -0400
Subject: [PATCH 077/148] feat(ec2): VPC endpoint for AWS Xray  (#16788)

Adds a static instance of InterfaceVpcEndpointAwsService for Xray to simplify creation of endpoints for users. VPC endpoint support for XRay was [launched](https://aws.amazon.com/about-aws/whats-new/2021/05/aws-x-ray-now-supports-vpc-endpoints/) in May.

Modeled this addition on #16306

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts | 1 +
 packages/@aws-cdk/aws-ec2/package.json        | 1 +
 2 files changed, 2 insertions(+)

diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts
index 3282da410d09a..00c59bbd2a022 100644
--- a/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts
+++ b/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts
@@ -309,6 +309,7 @@ export class InterfaceVpcEndpointAwsService implements IInterfaceVpcEndpointServ
   public static readonly STEP_FUNCTIONS = new InterfaceVpcEndpointAwsService('states');
   public static readonly LAMBDA = new InterfaceVpcEndpointAwsService('lambda');
   public static readonly TRANSCRIBE = new InterfaceVpcEndpointAwsService('transcribe');
+  public static readonly XRAY = new InterfaceVpcEndpointAwsService('xray');
 
   /**
    * The name of the service.
diff --git a/packages/@aws-cdk/aws-ec2/package.json b/packages/@aws-cdk/aws-ec2/package.json
index b7ea820e221b5..6cf7d368e25a2 100644
--- a/packages/@aws-cdk/aws-ec2/package.json
+++ b/packages/@aws-cdk/aws-ec2/package.json
@@ -262,6 +262,7 @@
       "docs-public-apis:@aws-cdk/aws-ec2.InterfaceVpcEndpointAwsService.STEP_FUNCTIONS",
       "docs-public-apis:@aws-cdk/aws-ec2.InterfaceVpcEndpointAwsService.LAMBDA",
       "docs-public-apis:@aws-cdk/aws-ec2.InterfaceVpcEndpointAwsService.TRANSCRIBE",
+      "docs-public-apis:@aws-cdk/aws-ec2.InterfaceVpcEndpointAwsService.XRAY",
       "docs-public-apis:@aws-cdk/aws-ec2.Port.toString",
       "docs-public-apis:@aws-cdk/aws-ec2.PrivateSubnet.fromPrivateSubnetAttributes",
       "docs-public-apis:@aws-cdk/aws-ec2.PublicSubnet.fromPublicSubnetAttributes",

From 0318253b423bb65ca7e6bf65411df767f2734296 Mon Sep 17 00:00:00 2001
From: Christian Moore 
Date: Thu, 28 Oct 2021 09:03:53 -0400
Subject: [PATCH 078/148] feat(ec2): add c5ad instances (#16428)

Innocuous addition of c5ad instance class

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-ec2/lib/instance-types.ts | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts
index 97d3d03e55219..4f81f970bf2db 100644
--- a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts
+++ b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts
@@ -213,6 +213,11 @@ export enum InstanceClass {
    */
   COMPUTE5_NVME_DRIVE = 'c5d',
 
+  /**
+   * Compute optimized instances with local NVME drive, 5th generation
+   */
+  C5D = 'c5d',
+
   /**
    * Compute optimized instances based on AMD EPYC, 5th generation.
    */
@@ -224,9 +229,14 @@ export enum InstanceClass {
   C5A = 'c5a',
 
   /**
-   * Compute optimized instances with local NVME drive, 5th generation
+   * Compute optimized instances with local NVME drive based on AMD EPYC, 5th generation.
    */
-  C5D = 'c5d',
+  COMPUTE5_AMD_NVME_DRIVE = 'c5ad',
+
+  /**
+   * Compute optimized instances with local NVME drive based on AMD EPYC, 5th generation.
+   */
+  C5AD = 'c5ad',
 
   /**
    * Compute optimized instances for high performance computing, 5th generation

From 4b32a25fd118c48999d81c5d4021a55142599cf6 Mon Sep 17 00:00:00 2001
From: Rico Huijbers 
Date: Thu, 28 Oct 2021 15:58:14 +0200
Subject: [PATCH 079/148] chore: disable 'rosetta strict' for all packages
 (#17211)

Currently, `strict` mode in Rosetta will fail the build in the pipeline
without failing the build in a PR review.

This causes unpredictable stoppages in our pipeline that we cannot
afford, so we're disabling the feature for now.

Strict mode will be re-enabled as soon as we are able to add Rosetta
checks to PR reviews.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/assertions/package.json                       | 2 +-
 packages/@aws-cdk/aws-kinesisfirehose-destinations/package.json | 2 +-
 packages/@aws-cdk/aws-redshift/package.json                     | 2 +-
 packages/@aws-cdk/cloud-assembly-schema/package.json            | 2 +-
 packages/@aws-cdk/cx-api/package.json                           | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/packages/@aws-cdk/assertions/package.json b/packages/@aws-cdk/assertions/package.json
index ac9a08ae297d6..2fe93a7d79d86 100644
--- a/packages/@aws-cdk/assertions/package.json
+++ b/packages/@aws-cdk/assertions/package.json
@@ -50,7 +50,7 @@
     "metadata": {
       "jsii": {
         "rosetta": {
-          "strict": true
+          "strict": false
         }
       }
     }
diff --git a/packages/@aws-cdk/aws-kinesisfirehose-destinations/package.json b/packages/@aws-cdk/aws-kinesisfirehose-destinations/package.json
index 36c981f2c54cd..6f1d68d6cedb3 100644
--- a/packages/@aws-cdk/aws-kinesisfirehose-destinations/package.json
+++ b/packages/@aws-cdk/aws-kinesisfirehose-destinations/package.json
@@ -32,7 +32,7 @@
     "metadata": {
       "jsii": {
         "rosetta": {
-          "strict": true
+          "strict": false
         }
       }
     }
diff --git a/packages/@aws-cdk/aws-redshift/package.json b/packages/@aws-cdk/aws-redshift/package.json
index d6ed1ff2f96ca..02fb952ab4c41 100644
--- a/packages/@aws-cdk/aws-redshift/package.json
+++ b/packages/@aws-cdk/aws-redshift/package.json
@@ -32,7 +32,7 @@
     "metadata": {
       "jsii": {
         "rosetta": {
-          "strict": true
+          "strict": false
         }
       }
     }
diff --git a/packages/@aws-cdk/cloud-assembly-schema/package.json b/packages/@aws-cdk/cloud-assembly-schema/package.json
index e6aee07a67f09..11226b0f1521a 100644
--- a/packages/@aws-cdk/cloud-assembly-schema/package.json
+++ b/packages/@aws-cdk/cloud-assembly-schema/package.json
@@ -32,7 +32,7 @@
     "metadata": {
       "jsii": {
         "rosetta": {
-          "strict": true
+          "strict": false
         }
       }
     }
diff --git a/packages/@aws-cdk/cx-api/package.json b/packages/@aws-cdk/cx-api/package.json
index 8d4293f2b5ee4..0a92e1c3492b6 100644
--- a/packages/@aws-cdk/cx-api/package.json
+++ b/packages/@aws-cdk/cx-api/package.json
@@ -32,7 +32,7 @@
     "metadata": {
       "jsii": {
         "rosetta": {
-          "strict": true
+          "strict": false
         }
       }
     }

From 6e13adc281722a491c0708954d7ed637ad45033b Mon Sep 17 00:00:00 2001
From: Vishal Gupta 
Date: Thu, 28 Oct 2021 07:52:44 -0700
Subject: [PATCH 080/148] feat(ec2): include p4d instance class (#17147)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*

Instance class is missing p4d instance class. This PR adds that instance class.
---
 packages/@aws-cdk/aws-ec2/lib/instance-types.ts | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts
index 4f81f970bf2db..a2c5ccdadc760 100644
--- a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts
+++ b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts
@@ -452,10 +452,20 @@ export enum InstanceClass {
   PARALLEL3 = 'p3',
 
   /**
-   * Parallel-processing optimized instances, 3nd generation
+   * Parallel-processing optimized instances, 3rd generation
    */
   P3 = 'p3',
 
+  /**
+   * Parallel-processing optimized instances, 4th generation
+   */
+  PARALLEL4 = 'p4d',
+
+  /**
+   * Parallel-processing optimized instances, 4th generation
+   */
+  P4D = 'p4d',
+
   /**
    * Arm processor based instances, 1st generation
    */

From f7e68e9d1cbeb9882e38d91eec1ff19f58da6f1a Mon Sep 17 00:00:00 2001
From: Kyle Roach 
Date: Thu, 28 Oct 2021 11:47:13 -0400
Subject: [PATCH 081/148] chore(apigateway): specify description on
 `addApiKey()` (#17107)

Previously defining a description was not possible when using `addApiKey` method.

This PR enables this by moving the description field to ApiKeyOptions.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-apigateway/lib/api-key.ts | 14 +++++++-------
 .../aws-apigateway/test/api-key.test.ts         | 17 +++++++++++++++++
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/packages/@aws-cdk/aws-apigateway/lib/api-key.ts b/packages/@aws-cdk/aws-apigateway/lib/api-key.ts
index f48a01193385f..a8065430fef4c 100644
--- a/packages/@aws-cdk/aws-apigateway/lib/api-key.ts
+++ b/packages/@aws-cdk/aws-apigateway/lib/api-key.ts
@@ -40,6 +40,13 @@ export interface ApiKeyOptions extends ResourceOptions {
    * @default none
    */
   readonly value?: string;
+
+  /**
+   * A description of the purpose of the API key.
+   * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html#cfn-apigateway-apikey-description
+   * @default none
+   */
+  readonly description?: string;
 }
 
 /**
@@ -59,13 +66,6 @@ export interface ApiKeyProps extends ApiKeyOptions {
    */
   readonly customerId?: string;
 
-  /**
-   * A description of the purpose of the API key.
-   * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html#cfn-apigateway-apikey-description
-   * @default none
-   */
-  readonly description?: string;
-
   /**
    * Indicates whether the API key can be used by clients.
    * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html#cfn-apigateway-apikey-enabled
diff --git a/packages/@aws-cdk/aws-apigateway/test/api-key.test.ts b/packages/@aws-cdk/aws-apigateway/test/api-key.test.ts
index f4f348a2a3d23..6fee9378f1217 100644
--- a/packages/@aws-cdk/aws-apigateway/test/api-key.test.ts
+++ b/packages/@aws-cdk/aws-apigateway/test/api-key.test.ts
@@ -41,6 +41,23 @@ describe('api key', () => {
     });
   });
 
+  test('add description to apiKey', () => {
+    // GIVEN
+    const stack = new cdk.Stack();
+    const api = new apigateway.RestApi(stack, 'test-api');
+    api.root.addMethod('GET'); // api must have atleast one method.
+
+    // WHEN
+    api.addApiKey('my-api-key', {
+      description: 'The most secret api key',
+    });
+
+    // THEN
+    expect(stack).toHaveResource('AWS::ApiGateway::ApiKey', {
+      Description: 'The most secret api key',
+    });
+  });
+
   test('use an imported api key', () => {
     // GIVEN
     const stack = new cdk.Stack();

From 7f194000697b85deb410ae0d7f7d4ac3c2654bcc Mon Sep 17 00:00:00 2001
From: Mario Viens 
Date: Thu, 28 Oct 2021 09:40:40 -0700
Subject: [PATCH 082/148] docs(assert): clarify assert library use with
 monocdk. (#17202)

Using monocdk with the @aws-cdk/assert creates problems. I initially was going to create a PR to fix the problem it created (some circular dependency unravelling which JSON.stringify fails on, along with alarms not actually being found to be added to the stack I was testing), but instead I found this is what we should use instead, which this readme update would have saved me a lot of time troubleshooting.

This I believe should put this line right below the quote section in the top of both https://www.npmjs.com/package/@aws-cdk/assert and https://www.npmjs.com/package/@monocdk-experiment/assert

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/assert-internal/README.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/packages/@aws-cdk/assert-internal/README.md b/packages/@aws-cdk/assert-internal/README.md
index 9256b46d2b154..ae72469dc59e2 100644
--- a/packages/@aws-cdk/assert-internal/README.md
+++ b/packages/@aws-cdk/assert-internal/README.md
@@ -11,6 +11,8 @@
 > announced in the release notes. This means that while you may use them, you may need to update
 > your source code when upgrading to a newer version of this package.
 
+If using monocdk, use [@monocdk-experiment/assert](https://www.npmjs.com/package/@monocdk-experiment/assert) instead.
+
 ---
 
 

From 0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21 Mon Sep 17 00:00:00 2001
From: Tatsuya Yamamoto 
Date: Fri, 29 Oct 2021 03:08:57 +0900
Subject: [PATCH 083/148] feat(iot): allow setting Actions of TopicRule
 (#17110)

I'm trying to implement aws-iot L2 Constructs.

This PR is the next step of #16681

refar:
- https://github.com/aws/aws-cdk/pull/16681#discussion_r733912215

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-iot-actions/README.md   |  30 +++++
 .../@aws-cdk/aws-iot-actions/lib/index.ts     |   3 +-
 .../lib/lambda-function-action.ts             |  30 +++++
 .../@aws-cdk/aws-iot-actions/package.json     |  10 ++
 ...integ.lambda-function-action.expected.json |  97 +++++++++++++++
 .../lambda/integ.lambda-function-action.ts    |  31 +++++
 .../lambda/lambda-function-action.test.ts     |  57 +++++++++
 packages/@aws-cdk/aws-iot/README.md           |  35 ++++--
 packages/@aws-cdk/aws-iot/lib/action.ts       |  24 ++++
 packages/@aws-cdk/aws-iot/lib/index.ts        |   1 +
 packages/@aws-cdk/aws-iot/lib/iot-sql.ts      |   1 -
 packages/@aws-cdk/aws-iot/lib/topic-rule.ts   |  43 ++++++-
 .../test/integ.topic-rule.expected.json       |   8 +-
 .../@aws-cdk/aws-iot/test/integ.topic-rule.ts |   9 ++
 .../@aws-cdk/aws-iot/test/topic-rule.test.ts  | 115 +++++++++++++++++-
 tools/@aws-cdk/pkglint/lib/rules.ts           |   1 +
 16 files changed, 472 insertions(+), 23 deletions(-)
 create mode 100644 packages/@aws-cdk/aws-iot-actions/lib/lambda-function-action.ts
 create mode 100644 packages/@aws-cdk/aws-iot-actions/test/lambda/integ.lambda-function-action.expected.json
 create mode 100644 packages/@aws-cdk/aws-iot-actions/test/lambda/integ.lambda-function-action.ts
 create mode 100644 packages/@aws-cdk/aws-iot-actions/test/lambda/lambda-function-action.test.ts
 create mode 100644 packages/@aws-cdk/aws-iot/lib/action.ts

diff --git a/packages/@aws-cdk/aws-iot-actions/README.md b/packages/@aws-cdk/aws-iot-actions/README.md
index 1c098d25eb3de..67d9b2924dd53 100644
--- a/packages/@aws-cdk/aws-iot-actions/README.md
+++ b/packages/@aws-cdk/aws-iot-actions/README.md
@@ -18,3 +18,33 @@
 This library contains integration classes to send data to any number of
 supported AWS Services. Instances of these classes should be passed to
 `TopicRule` defined in `@aws-cdk/aws-iot`.
+
+Currently supported are:
+
+- Invoke a Lambda function
+
+## Invoke a Lambda function
+
+The code snippet below creates an AWS IoT Rule that invoke a Lambda function
+when it is triggered.
+
+```ts
+import * as iot from '@aws-cdk/aws-iot';
+import * as actions from '@aws-cdk/aws-iot-actions';
+import * as lambda from '@aws-cdk/aws-lambda';
+
+const func = new lambda.Function(this, 'MyFunction', {
+  runtime: lambda.Runtime.NODEJS_14_X,
+  handler: 'index.handler',
+  code: lambda.Code.fromInline(`
+    exports.handler = (event) => {
+      console.log("It is test for lambda action of AWS IoT Rule.", event);
+    };`
+  ),
+});
+
+new iot.TopicRule(this, 'TopicRule', {
+  sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, timestamp() as timestamp, temperature FROM 'device/+/data'"),
+  actions: [new actions.LambdaFunctionAction(func)],
+});
+```
diff --git a/packages/@aws-cdk/aws-iot-actions/lib/index.ts b/packages/@aws-cdk/aws-iot-actions/lib/index.ts
index 3e4b0ef0a73d4..751863744ffe2 100644
--- a/packages/@aws-cdk/aws-iot-actions/lib/index.ts
+++ b/packages/@aws-cdk/aws-iot-actions/lib/index.ts
@@ -1,2 +1 @@
-// this is placeholder for monocdk
-export const dummy = true;
+export * from './lambda-function-action';
diff --git a/packages/@aws-cdk/aws-iot-actions/lib/lambda-function-action.ts b/packages/@aws-cdk/aws-iot-actions/lib/lambda-function-action.ts
new file mode 100644
index 0000000000000..8296e112e8be5
--- /dev/null
+++ b/packages/@aws-cdk/aws-iot-actions/lib/lambda-function-action.ts
@@ -0,0 +1,30 @@
+import * as iam from '@aws-cdk/aws-iam';
+import * as iot from '@aws-cdk/aws-iot';
+import * as lambda from '@aws-cdk/aws-lambda';
+
+/**
+ * The action to invoke an AWS Lambda function, passing in an MQTT message.
+ */
+export class LambdaFunctionAction implements iot.IAction {
+  /**
+   * @param func The lambda function to be invoked by this action
+   */
+  constructor(private readonly func: lambda.IFunction) {}
+
+  bind(topicRule: iot.ITopicRule): iot.ActionConfig {
+    this.func.addPermission('invokedByAwsIotRule', {
+      action: 'lambda:InvokeFunction',
+      principal: new iam.ServicePrincipal('iot.amazonaws.com'),
+      sourceAccount: topicRule.env.account,
+      sourceArn: topicRule.topicRuleArn,
+    });
+
+    return {
+      configuration: {
+        lambda: {
+          functionArn: this.func.functionArn,
+        },
+      },
+    };
+  }
+}
diff --git a/packages/@aws-cdk/aws-iot-actions/package.json b/packages/@aws-cdk/aws-iot-actions/package.json
index 76878637e0430..3b66b73a1562e 100644
--- a/packages/@aws-cdk/aws-iot-actions/package.json
+++ b/packages/@aws-cdk/aws-iot-actions/package.json
@@ -79,9 +79,19 @@
     "jest": "^26.6.3"
   },
   "dependencies": {
+    "@aws-cdk/aws-iam": "0.0.0",
+    "@aws-cdk/aws-iot": "0.0.0",
+    "@aws-cdk/aws-lambda": "0.0.0",
+    "@aws-cdk/core": "0.0.0",
+    "constructs": "^3.3.69"
   },
   "homepage": "https://github.com/aws/aws-cdk",
   "peerDependencies": {
+    "@aws-cdk/aws-iam": "0.0.0",
+    "@aws-cdk/aws-iot": "0.0.0",
+    "@aws-cdk/aws-lambda": "0.0.0",
+    "@aws-cdk/core": "0.0.0",
+    "constructs": "^3.3.69"
   },
   "engines": {
     "node": ">= 10.13.0 <13 || >=13.7.0"
diff --git a/packages/@aws-cdk/aws-iot-actions/test/lambda/integ.lambda-function-action.expected.json b/packages/@aws-cdk/aws-iot-actions/test/lambda/integ.lambda-function-action.expected.json
new file mode 100644
index 0000000000000..345ead052c921
--- /dev/null
+++ b/packages/@aws-cdk/aws-iot-actions/test/lambda/integ.lambda-function-action.expected.json
@@ -0,0 +1,97 @@
+{
+  "Resources": {
+    "MyFunctionServiceRole3C357FF2": {
+      "Type": "AWS::IAM::Role",
+      "Properties": {
+        "AssumeRolePolicyDocument": {
+          "Statement": [
+            {
+              "Action": "sts:AssumeRole",
+              "Effect": "Allow",
+              "Principal": {
+                "Service": "lambda.amazonaws.com"
+              }
+            }
+          ],
+          "Version": "2012-10-17"
+        },
+        "ManagedPolicyArns": [
+          {
+            "Fn::Join": [
+              "",
+              [
+                "arn:",
+                {
+                  "Ref": "AWS::Partition"
+                },
+                ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
+              ]
+            ]
+          }
+        ]
+      }
+    },
+    "MyFunction3BAA72D1": {
+      "Type": "AWS::Lambda::Function",
+      "Properties": {
+        "Code": {
+          "ZipFile": "\n        exports.handler = (event) => {\n          console.log(\"It is test for lambda action of AWS IoT Rule.\", event);\n        };\""
+        },
+        "Role": {
+          "Fn::GetAtt": [
+            "MyFunctionServiceRole3C357FF2",
+            "Arn"
+          ]
+        },
+        "Handler": "index.handler",
+        "Runtime": "nodejs14.x"
+      },
+      "DependsOn": [
+        "MyFunctionServiceRole3C357FF2"
+      ]
+    },
+    "MyFunctioninvokedByAwsIotRule5581F304": {
+      "Type": "AWS::Lambda::Permission",
+      "Properties": {
+        "Action": "lambda:InvokeFunction",
+        "FunctionName": {
+          "Fn::GetAtt": [
+            "MyFunction3BAA72D1",
+            "Arn"
+          ]
+        },
+        "Principal": "iot.amazonaws.com",
+        "SourceAccount": {
+          "Ref": "AWS::AccountId"
+        },
+        "SourceArn": {
+          "Fn::GetAtt": [
+            "TopicRule40A4EA44",
+            "Arn"
+          ]
+        }
+      }
+    },
+    "TopicRule40A4EA44": {
+      "Type": "AWS::IoT::TopicRule",
+      "Properties": {
+        "TopicRulePayload": {
+          "Actions": [
+            {
+              "Lambda": {
+                "FunctionArn": {
+                  "Fn::GetAtt": [
+                    "MyFunction3BAA72D1",
+                    "Arn"
+                  ]
+                }
+              }
+            }
+          ],
+          "AwsIotSqlVersion": "2016-03-23",
+          "Sql": "SELECT topic(2) as device_id, timestamp() as timestamp, temperature FROM 'device/+/data'"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-iot-actions/test/lambda/integ.lambda-function-action.ts b/packages/@aws-cdk/aws-iot-actions/test/lambda/integ.lambda-function-action.ts
new file mode 100644
index 0000000000000..58a7773afec03
--- /dev/null
+++ b/packages/@aws-cdk/aws-iot-actions/test/lambda/integ.lambda-function-action.ts
@@ -0,0 +1,31 @@
+/// !cdk-integ pragma:ignore-assets
+import * as iot from '@aws-cdk/aws-iot';
+import * as lambda from '@aws-cdk/aws-lambda';
+import * as cdk from '@aws-cdk/core';
+import * as actions from '../../lib';
+
+const app = new cdk.App();
+
+class TestStack extends cdk.Stack {
+  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
+    super(scope, id, props);
+
+    const func = new lambda.Function(this, 'MyFunction', {
+      runtime: lambda.Runtime.NODEJS_14_X,
+      handler: 'index.handler',
+      code: lambda.Code.fromInline(`
+        exports.handler = (event) => {
+          console.log("It is test for lambda action of AWS IoT Rule.", event);
+        };"`,
+      ),
+    });
+
+    new iot.TopicRule(this, 'TopicRule', {
+      sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, timestamp() as timestamp, temperature FROM 'device/+/data'"),
+      actions: [new actions.LambdaFunctionAction(func)],
+    });
+  }
+}
+
+new TestStack(app, 'test-stack');
+app.synth();
diff --git a/packages/@aws-cdk/aws-iot-actions/test/lambda/lambda-function-action.test.ts b/packages/@aws-cdk/aws-iot-actions/test/lambda/lambda-function-action.test.ts
new file mode 100644
index 0000000000000..76263f5fa5e5c
--- /dev/null
+++ b/packages/@aws-cdk/aws-iot-actions/test/lambda/lambda-function-action.test.ts
@@ -0,0 +1,57 @@
+import { Template } from '@aws-cdk/assertions';
+import * as iot from '@aws-cdk/aws-iot';
+import * as lambda from '@aws-cdk/aws-lambda';
+import * as cdk from '@aws-cdk/core';
+import * as actions from '../../lib';
+
+test('create a topic rule with lambda action and a lambda permission to be invoked by the topic rule', () => {
+  // GIVEN
+  const stack = new cdk.Stack();
+  const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
+    sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id FROM 'device/+/data'"),
+  });
+  const func = new lambda.Function(stack, 'MyFunction', {
+    runtime: lambda.Runtime.NODEJS_14_X,
+    handler: 'index.handler',
+    code: lambda.Code.fromInline('console.log("foo")'),
+  });
+
+  // WHEN
+  topicRule.addAction(new actions.LambdaFunctionAction(func));
+
+  // THEN
+  Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
+    TopicRulePayload: {
+      Actions: [
+        {
+          Lambda: {
+            FunctionArn: {
+              'Fn::GetAtt': [
+                'MyFunction3BAA72D1',
+                'Arn',
+              ],
+            },
+          },
+        },
+      ],
+    },
+  });
+
+  Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', {
+    Action: 'lambda:InvokeFunction',
+    FunctionName: {
+      'Fn::GetAtt': [
+        'MyFunction3BAA72D1',
+        'Arn',
+      ],
+    },
+    Principal: 'iot.amazonaws.com',
+    SourceAccount: { Ref: 'AWS::AccountId' },
+    SourceArn: {
+      'Fn::GetAtt': [
+        'MyTopicRule4EC2091C',
+        'Arn',
+      ],
+    },
+  });
+});
diff --git a/packages/@aws-cdk/aws-iot/README.md b/packages/@aws-cdk/aws-iot/README.md
index bbde9aae8a21d..6a9640629891a 100644
--- a/packages/@aws-cdk/aws-iot/README.md
+++ b/packages/@aws-cdk/aws-iot/README.md
@@ -40,16 +40,35 @@ import * as iot from '@aws-cdk/aws-iot';
 
 ## `TopicRule`
 
-The `TopicRule` construct defined Rules that give your devices the ability to
-interact with AWS services.
-
-For example, to define a rule:
+Create a topic rule that give your devices the ability to interact with AWS services.
+You can create a topic rule with an action that invoke the Lambda action as following:
 
 ```ts
-new iot.TopicRule(stack, 'MyTopicRule', {
-  topicRuleName: 'MyRuleName', // optional property
-  sql: iot.IotSql.fromStringAsVer20160323(
-    "SELECT topic(2) as device_id, temperature FROM 'device/+/data'",
+import * as iot from '@aws-cdk/aws-iot';
+import * as actions from '@aws-cdk/aws-iot-actions';
+import * as lambda from '@aws-cdk/aws-lambda';
+
+const func = new lambda.Function(this, 'MyFunction', {
+  runtime: lambda.Runtime.NODEJS_14_X,
+  handler: 'index.handler',
+  code: lambda.Code.fromInline(`
+    exports.handler = (event) => {
+      console.log("It is test for lambda action of AWS IoT Rule.", event);
+    };`
   ),
 });
+
+new iot.TopicRule(this, 'TopicRule', {
+  sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, timestamp() as timestamp FROM 'device/+/data'"),
+  actions: [new actions.LambdaFunctionAction(func)],
+});
+```
+
+Or, you can add an action after constructing the `TopicRule` instance as following:
+
+```ts
+const topicRule = new iot.TopicRule(this, 'TopicRule', {
+  sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, timestamp() as timestamp FROM 'device/+/data'"),
+});
+topicRule.addAction(new actions.LambdaFunctionAction(func))
 ```
diff --git a/packages/@aws-cdk/aws-iot/lib/action.ts b/packages/@aws-cdk/aws-iot/lib/action.ts
new file mode 100644
index 0000000000000..f22daf6194b1c
--- /dev/null
+++ b/packages/@aws-cdk/aws-iot/lib/action.ts
@@ -0,0 +1,24 @@
+import { CfnTopicRule } from './iot.generated';
+import { ITopicRule } from './topic-rule';
+
+/**
+ * An abstract action for TopicRule.
+ */
+export interface IAction {
+  /**
+   * Returns the topic rule action specification.
+   *
+   * @param topicRule The TopicRule that would trigger this action.
+   */
+  bind(topicRule: ITopicRule): ActionConfig;
+}
+
+/**
+ * Properties for an topic rule action
+ */
+export interface ActionConfig {
+  /**
+   * The configuration for this action.
+   */
+  readonly configuration: CfnTopicRule.ActionProperty;
+}
diff --git a/packages/@aws-cdk/aws-iot/lib/index.ts b/packages/@aws-cdk/aws-iot/lib/index.ts
index 18b6f2e03aaeb..f2e82a6c755b2 100644
--- a/packages/@aws-cdk/aws-iot/lib/index.ts
+++ b/packages/@aws-cdk/aws-iot/lib/index.ts
@@ -1,3 +1,4 @@
+export * from './action';
 export * from './iot-sql';
 export * from './topic-rule';
 
diff --git a/packages/@aws-cdk/aws-iot/lib/iot-sql.ts b/packages/@aws-cdk/aws-iot/lib/iot-sql.ts
index c673552743364..7014778cc94ab 100644
--- a/packages/@aws-cdk/aws-iot/lib/iot-sql.ts
+++ b/packages/@aws-cdk/aws-iot/lib/iot-sql.ts
@@ -56,7 +56,6 @@ export abstract class IotSql {
   public abstract bind(scope: Construct): IotSqlConfig;
 }
 
-
 class IotSqlImpl extends IotSql {
   constructor(private readonly version: string, private readonly sql: string) {
     super();
diff --git a/packages/@aws-cdk/aws-iot/lib/topic-rule.ts b/packages/@aws-cdk/aws-iot/lib/topic-rule.ts
index 17f121eb29ab3..a8cd21fe2bd96 100644
--- a/packages/@aws-cdk/aws-iot/lib/topic-rule.ts
+++ b/packages/@aws-cdk/aws-iot/lib/topic-rule.ts
@@ -1,5 +1,6 @@
-import { ArnFormat, Resource, Stack, IResource } from '@aws-cdk/core';
+import { ArnFormat, Resource, Stack, IResource, Lazy } from '@aws-cdk/core';
 import { Construct } from 'constructs';
+import { IAction } from './action';
 import { IotSql } from './iot-sql';
 import { CfnTopicRule } from './iot.generated';
 
@@ -28,11 +29,18 @@ export interface ITopicRule extends IResource {
  */
 export interface TopicRuleProps {
   /**
-   * The name of the rule.
+   * The name of the topic rule.
    * @default None
    */
   readonly topicRuleName?: string;
 
+  /**
+   * The actions associated with the topic rule.
+   *
+   * @default No actions will be perform
+   */
+  readonly actions?: IAction[];
+
   /**
    * A simplified SQL syntax to filter messages received on an MQTT topic and push the data elsewhere.
    *
@@ -69,17 +77,19 @@ export class TopicRule extends Resource implements ITopicRule {
   }
 
   /**
-   * Arn of this rule
+   * Arn of this topic rule
    * @attribute
    */
   public readonly topicRuleArn: string;
 
   /**
-   * Name of this rule
+   * Name of this topic rule
    * @attribute
    */
   public readonly topicRuleName: string;
 
+  private readonly actions: CfnTopicRule.ActionProperty[] = [];
+
   constructor(scope: Construct, id: string, props: TopicRuleProps) {
     super(scope, id, {
       physicalName: props.topicRuleName,
@@ -90,7 +100,7 @@ export class TopicRule extends Resource implements ITopicRule {
     const resource = new CfnTopicRule(this, 'Resource', {
       ruleName: this.physicalName,
       topicRulePayload: {
-        actions: [],
+        actions: Lazy.any({ produce: () => this.actions }),
         awsIotSqlVersion: sqlConfig.awsIotSqlVersion,
         sql: sqlConfig.sql,
       },
@@ -102,5 +112,28 @@ export class TopicRule extends Resource implements ITopicRule {
       resourceName: this.physicalName,
     });
     this.topicRuleName = this.getResourceNameAttribute(resource.ref);
+
+    props.actions?.forEach(action => {
+      this.addAction(action);
+    });
+  }
+
+  /**
+   * Add a action to the topic rule.
+   *
+   * @param action the action to associate with the topic rule.
+   */
+  public addAction(action: IAction): void {
+    const { configuration } = action.bind(this);
+
+    const keys = Object.keys(configuration);
+    if (keys.length === 0) {
+      throw new Error('An action property cannot be an empty object.');
+    }
+    if (keys.length > 1) {
+      throw new Error(`An action property cannot have multiple keys, received: ${keys}`);
+    }
+
+    this.actions.push(configuration);
   }
 }
diff --git a/packages/@aws-cdk/aws-iot/test/integ.topic-rule.expected.json b/packages/@aws-cdk/aws-iot/test/integ.topic-rule.expected.json
index cf4be2735229e..9daad98410825 100644
--- a/packages/@aws-cdk/aws-iot/test/integ.topic-rule.expected.json
+++ b/packages/@aws-cdk/aws-iot/test/integ.topic-rule.expected.json
@@ -4,7 +4,13 @@
       "Type": "AWS::IoT::TopicRule",
       "Properties": {
         "TopicRulePayload": {
-          "Actions": [],
+          "Actions": [
+            {
+              "Http": {
+                "Url": "https://example.com"
+              }
+            }
+          ],
           "AwsIotSqlVersion": "2015-10-08",
           "Sql": "SELECT topic(2) as device_id FROM 'device/+/data'"
         }
diff --git a/packages/@aws-cdk/aws-iot/test/integ.topic-rule.ts b/packages/@aws-cdk/aws-iot/test/integ.topic-rule.ts
index a06edc3c3f5e1..0f4bab54a9d2a 100644
--- a/packages/@aws-cdk/aws-iot/test/integ.topic-rule.ts
+++ b/packages/@aws-cdk/aws-iot/test/integ.topic-rule.ts
@@ -10,6 +10,15 @@ class TestStack extends cdk.Stack {
 
     new iot.TopicRule(this, 'TopicRule', {
       sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id FROM 'device/+/data'"),
+      actions: [
+        {
+          bind: () => ({
+            configuration: {
+              http: { url: 'https://example.com' },
+            },
+          }),
+        },
+      ],
     });
   }
 }
diff --git a/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts b/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts
index 1dec8c3065a86..66246e860dddb 100644
--- a/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts
+++ b/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts
@@ -19,14 +19,14 @@ test('Default property', () => {
 
 test('can get topic rule name', () => {
   const stack = new cdk.Stack();
-  const rule = new iot.TopicRule(stack, 'MyTopicRule', {
+  const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
     sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"),
   });
 
   new cdk.CfnResource(stack, 'Res', {
     type: 'Test::Resource',
     properties: {
-      TopicRuleName: rule.topicRuleName,
+      TopicRuleName: topicRule.topicRuleName,
     },
   });
 
@@ -37,14 +37,14 @@ test('can get topic rule name', () => {
 
 test('can get topic rule arn', () => {
   const stack = new cdk.Stack();
-  const rule = new iot.TopicRule(stack, 'MyTopicRule', {
+  const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
     sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"),
   });
 
   new cdk.CfnResource(stack, 'Res', {
     type: 'Test::Resource',
     properties: {
-      TopicRuleArn: rule.topicRuleArn,
+      TopicRuleArn: topicRule.topicRuleArn,
     },
   });
 
@@ -100,16 +100,119 @@ test.each([
   }).toThrow('IoT SQL string cannot be empty');
 });
 
+test('can set actions', () => {
+  const stack = new cdk.Stack();
+
+  const action1: iot.IAction = {
+    bind: () => ({
+      configuration: {
+        http: { url: 'http://example.com' },
+      },
+    }),
+  };
+  const action2: iot.IAction = {
+    bind: () => ({
+      configuration: {
+        lambda: { functionArn: 'test-functionArn' },
+      },
+    }),
+  };
+
+  new iot.TopicRule(stack, 'MyTopicRule', {
+    sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"),
+    actions: [action1, action2],
+  });
+
+  Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
+    TopicRulePayload: {
+      Actions: [
+        { Http: { Url: 'http://example.com' } },
+        { Lambda: { FunctionArn: 'test-functionArn' } },
+      ],
+      Sql: "SELECT topic(2) as device_id, temperature FROM 'device/+/data'",
+    },
+  });
+});
+
+test('can add an action', () => {
+  const stack = new cdk.Stack();
+
+  const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
+    sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"),
+  });
+  topicRule.addAction({
+    bind: () => ({
+      configuration: {
+        http: { url: 'http://example.com' },
+      },
+    }),
+  });
+  topicRule.addAction({
+    bind: () => ({
+      configuration: {
+        lambda: { functionArn: 'test-functionArn' },
+      },
+    }),
+  });
+
+  Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
+    TopicRulePayload: {
+      Actions: [
+        { Http: { Url: 'http://example.com' } },
+        { Lambda: { FunctionArn: 'test-functionArn' } },
+      ],
+      Sql: "SELECT topic(2) as device_id, temperature FROM 'device/+/data'",
+    },
+  });
+});
+
+test('cannot add an action as empty object', () => {
+  const stack = new cdk.Stack();
+  const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
+    sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"),
+  });
+
+  const emptyKeysAction: iot.IAction = {
+    bind: () => ({
+      configuration: {},
+    }),
+  };
+
+  expect(() => {
+    topicRule.addAction(emptyKeysAction);
+  }).toThrow('An action property cannot be an empty object.');
+});
+
+test('cannot add an action that have multiple keys', () => {
+  const stack = new cdk.Stack();
+  const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
+    sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"),
+  });
+
+  const multipleKeysAction: iot.IAction = {
+    bind: () => ({
+      configuration: {
+        http: { url: 'http://example.com' },
+        lambda: { functionArn: 'test-functionArn' },
+      },
+    }),
+  };
+
+  expect(() => {
+    topicRule.addAction(multipleKeysAction);
+  }).toThrow('An action property cannot have multiple keys, received: http,lambda');
+});
+
 test('can import a TopicRule by ARN', () => {
   const stack = new cdk.Stack();
 
-  const topicRuleArn = 'arn:aws:iot:ap-northeast-1:123456789012:rule/my-rule-name';
+  const topicRuleArn = 'arn:aws:iot:ap-northeast-1:123456789012:rule/my-topic-rule-name';
 
   const topicRule = iot.TopicRule.fromTopicRuleArn(stack, 'TopicRuleFromArn', topicRuleArn);
 
   expect(topicRule).toMatchObject({
     topicRuleArn,
-    topicRuleName: 'my-rule-name',
+    topicRuleName: 'my-topic-rule-name',
   });
 });
 
diff --git a/tools/@aws-cdk/pkglint/lib/rules.ts b/tools/@aws-cdk/pkglint/lib/rules.ts
index e18fcb1086fdb..eda6436884d77 100644
--- a/tools/@aws-cdk/pkglint/lib/rules.ts
+++ b/tools/@aws-cdk/pkglint/lib/rules.ts
@@ -1653,6 +1653,7 @@ export class NoExperimentalDependents extends ValidationRule {
     ['@aws-cdk/aws-apigatewayv2-authorizers', ['@aws-cdk/aws-apigatewayv2']],
     ['@aws-cdk/aws-events-targets', ['@aws-cdk/aws-kinesisfirehose']],
     ['@aws-cdk/aws-kinesisfirehose-destinations', ['@aws-cdk/aws-kinesisfirehose']],
+    ['@aws-cdk/aws-iot-actions', ['@aws-cdk/aws-iot']],
   ]);
 
   private readonly excludedModules = ['@aws-cdk/cloudformation-include'];

From 0d7452ee3ce22179242241ed85cf55a173af19b5 Mon Sep 17 00:00:00 2001
From: Calvin Combs <66279577+comcalvi@users.noreply.github.com>
Date: Thu, 28 Oct 2021 12:30:43 -0700
Subject: [PATCH 084/148] chore: transfer ownership of cfn-include to @comcalvi
 (#17218)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .github/workflows/issue-label-assign.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/issue-label-assign.yml b/.github/workflows/issue-label-assign.yml
index b7bfacd0126b0..f4d9f3b293c48 100644
--- a/.github/workflows/issue-label-assign.yml
+++ b/.github/workflows/issue-label-assign.yml
@@ -217,7 +217,7 @@ jobs:
            {"area":"@aws-cdk/cfnspec","keywords":["cfn-spec"],"labels":["@aws-cdk/cfnspec"],"assignees":["rix0rrr"]},
            {"area":"@aws-cdk/cloud-assembly-schema","keywords":["cloud-assembly-schema","manifest"],"labels":["@aws-cdk/cloud-assembly-schema"],"assignees":["rix0rrr"]},
            {"area":"@aws-cdk/cloudformation-diff","keywords":["cloudformation-diff","cfn-diff"],"labels":["@aws-cdk/cloudformation-diff"],"assignees":["skinny85"]},
-           {"area":"@aws-cdk/cloudformation-include","keywords":["cloudformation-include","cfn-include"],"labels":["@aws-cdk/cloudformation-include"],"assignees":["skinny85"]},
+           {"area":"@aws-cdk/cloudformation-include","keywords":["cloudformation-include","cfn-include"],"labels":["@aws-cdk/cloudformation-include"],"assignees":["comcalvi"]},
            {"area":"@aws-cdk/core","keywords":["cross-account","nested stacks","core"],"labels":["@aws-cdk/core"],"assignees":["rix0rrr"]},
            {"area":"@aws-cdk/custom-resources","keywords":["custom-resource","provider"],"labels":["@aws-cdk/custom-resources"],"assignees":["rix0rrr"]},
            {"area":"@aws-cdk/cx-api","keywords":["cx-api","cloudartifact","cloudassembly"],"labels":["@aws-cdk/cx-api"],"assignees":["rix0rrr"]},

From 4c6cee5027c1b72af9eec809f646bb5751d683e2 Mon Sep 17 00:00:00 2001
From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com>
Date: Fri, 29 Oct 2021 04:33:34 -0400
Subject: [PATCH 085/148] chore(route53): make examples compile (#17226)

in this PR:
- chore(route53): make examples compile
- chore(route53-targets): make examples compile
- chore(route53-patterns): make examples compile

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../@aws-cdk/aws-route53-patterns/README.md   | 20 ++---
 .../rosetta/default.ts-fixture                | 12 +++
 .../@aws-cdk/aws-route53-targets/README.md    | 71 ++++++++++++----
 .../rosetta/default.ts-fixture                | 12 +++
 packages/@aws-cdk/aws-route53/README.md       | 80 ++++++++-----------
 .../aws-route53/rosetta/default.ts-fixture    | 14 ++++
 6 files changed, 139 insertions(+), 70 deletions(-)
 create mode 100644 packages/@aws-cdk/aws-route53-patterns/rosetta/default.ts-fixture
 create mode 100644 packages/@aws-cdk/aws-route53-targets/rosetta/default.ts-fixture
 create mode 100644 packages/@aws-cdk/aws-route53/rosetta/default.ts-fixture

diff --git a/packages/@aws-cdk/aws-route53-patterns/README.md b/packages/@aws-cdk/aws-route53-patterns/README.md
index 4fa852aaad777..a8c9c6b3874e0 100644
--- a/packages/@aws-cdk/aws-route53-patterns/README.md
+++ b/packages/@aws-cdk/aws-route53-patterns/README.md
@@ -41,13 +41,13 @@ must be in US East (N. Virginia).
 The following example creates an HTTPS redirect from `foo.example.com` to `bar.example.com`
 As an existing certificate is not provided, one will be created in `us-east-1` by the CDK.
 
-  ```ts
-  new HttpsRedirect(stack, 'Redirect', {
-    recordNames: ['foo.example.com'],
-    targetDomain: 'bar.example.com',
-    zone: HostedZone.fromHostedZoneAttributes(stack, 'HostedZone', {
-      hostedZoneId: 'ID',
-      zoneName: 'example.com',
-    })
-  });
-  ```
+```ts
+new patterns.HttpsRedirect(this, 'Redirect', {
+  recordNames: ['foo.example.com'],
+  targetDomain: 'bar.example.com',
+  zone: route53.HostedZone.fromHostedZoneAttributes(this, 'HostedZone', {
+    hostedZoneId: 'ID',
+    zoneName: 'example.com',
+  }),
+});
+```
diff --git a/packages/@aws-cdk/aws-route53-patterns/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-route53-patterns/rosetta/default.ts-fixture
new file mode 100644
index 0000000000000..1ec9038bfff0b
--- /dev/null
+++ b/packages/@aws-cdk/aws-route53-patterns/rosetta/default.ts-fixture
@@ -0,0 +1,12 @@
+// Fixture with packages imported, but nothing else
+import { Construct } from 'constructs';
+import { Stack } from '@aws-cdk/core';
+import * as route53 from '@aws-cdk/aws-route53';
+import * as patterns from '@aws-cdk/aws-route53-patterns';
+
+class Fixture extends Stack {
+  constructor(scope: Construct, id: string) {
+    super(scope, id);
+    /// here
+  }
+}
diff --git a/packages/@aws-cdk/aws-route53-targets/README.md b/packages/@aws-cdk/aws-route53-targets/README.md
index 6c703ad5adc8f..9d53630628ddd 100644
--- a/packages/@aws-cdk/aws-route53-targets/README.md
+++ b/packages/@aws-cdk/aws-route53-targets/README.md
@@ -14,9 +14,14 @@ This library contains Route53 Alias Record targets for:
 * API Gateway custom domains
 
   ```ts
+  import * as apigw from '@aws-cdk/aws-apigateway';
+
+  declare const zone: route53.HostedZone;
+  declare const restApi: apigw.LambdaRestApi;
+
   new route53.ARecord(this, 'AliasRecord', {
     zone,
-    target: route53.RecordTarget.fromAlias(new alias.ApiGateway(restApi)),
+    target: route53.RecordTarget.fromAlias(new targets.ApiGateway(restApi)),
     // or - route53.RecordTarget.fromAlias(new alias.ApiGatewayDomain(domainName)),
   });
   ```
@@ -24,38 +29,57 @@ This library contains Route53 Alias Record targets for:
 * API Gateway V2 custom domains
 
   ```ts
+  import * as apigwv2 from '@aws-cdk/aws-apigatewayv2';
+
+  declare const zone: route53.HostedZone;
+  declare const domainName: apigwv2.DomainName;
 
   new route53.ARecord(this, 'AliasRecord', {
     zone,
-    target: route53.RecordTarget.fromAlias(new alias.ApiGatewayv2DomainProperties(domainName.regionalDomainName, domainName.regionalHostedZoneId)),
+    target: route53.RecordTarget.fromAlias(new targets.ApiGatewayv2DomainProperties(domainName.regionalDomainName, domainName.regionalHostedZoneId)),
   });
   ```
 
 * CloudFront distributions
 
   ```ts
+  import * as cloudfront from '@aws-cdk/aws-cloudfront';
+
+  declare const zone: route53.HostedZone;
+  declare const distribution: cloudfront.CloudFrontWebDistribution;
+
   new route53.ARecord(this, 'AliasRecord', {
     zone,
-    target: route53.RecordTarget.fromAlias(new alias.CloudFrontTarget(distribution)),
+    target: route53.RecordTarget.fromAlias(new targets.CloudFrontTarget(distribution)),
   });
   ```
 
 * ELBv2 load balancers
 
   ```ts
+  import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2';
+  
+  declare const zone: route53.HostedZone;
+  declare const lb: elbv2.ApplicationLoadBalancer;
+
   new route53.ARecord(this, 'AliasRecord', {
     zone,
-    target: route53.RecordTarget.fromAlias(new alias.LoadBalancerTarget(elbv2)),
-    // or - route53.RecordTarget.fromAlias(new alias.ApiGatewayDomain(domainName)),
+    target: route53.RecordTarget.fromAlias(new targets.LoadBalancerTarget(lb)),
+    // or - route53.RecordTarget.fromAlias(new targets.ApiGatewayDomain(domainName)),
   });
   ```
 
 * Classic load balancers
 
   ```ts
+  import * as elb from '@aws-cdk/aws-elasticloadbalancing';
+  
+  declare const zone: route53.HostedZone;
+  declare const lb: elb.LoadBalancer;
+
   new route53.ARecord(this, 'AliasRecord', {
     zone,
-    target: route53.RecordTarget.fromAlias(new alias.ClassicLoadBalancerTarget(elb)),
+    target: route53.RecordTarget.fromAlias(new targets.ClassicLoadBalancerTarget(lb)),
     // or - route53.RecordTarget.fromAlias(new alias.ApiGatewayDomain(domainName)),
   });
   ```
@@ -67,7 +91,12 @@ For example, if the Amazon-provided DNS for the load balancer is `ALB-xxxxxxx.us
 * GlobalAccelerator
 
   ```ts
-  new route53.ARecord(stack, 'AliasRecord', {
+  import * as globalaccelerator from '@aws-cdk/aws-globalaccelerator';
+
+  declare const zone: route53.HostedZone;
+  declare const accelerator: globalaccelerator.Accelerator;
+
+  new route53.ARecord(this, 'AliasRecord', {
     zone,
     target: route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorTarget(accelerator)),
     // or - route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorDomainTarget('xyz.awsglobalaccelerator.com')),
@@ -82,9 +111,14 @@ See [the documentation on DNS addressing](https://docs.aws.amazon.com/global-acc
 **Important:** Based on the CFN docs for VPCEndpoints - [see here](attrDnsEntries) - the attributes returned for DnsEntries in CloudFormation is a combination of the hosted zone ID and the DNS name. The entries are ordered as follows: regional public DNS, zonal public DNS, private DNS, and wildcard DNS. This order is not enforced for AWS Marketplace services, and therefore this CDK construct is ONLY guaranteed to work with non-marketplace services.
 
   ```ts
-  new route53.ARecord(stack, "AliasRecord", {
+  import * as ec2 from '@aws-cdk/aws-ec2';
+
+  declare const zone: route53.HostedZone;
+  declare const interfaceVpcEndpoint: ec2.InterfaceVpcEndpoint;
+
+  new route53.ARecord(this, "AliasRecord", {
     zone,
-    target: route53.RecordTarget.fromAlias(new alias.InterfaceVpcEndpointTarget(interfaceVpcEndpoint))
+    target: route53.RecordTarget.fromAlias(new targets.InterfaceVpcEndpointTarget(interfaceVpcEndpoint)),
   });
   ```
 
@@ -94,35 +128,44 @@ See [the documentation on DNS addressing](https://docs.aws.amazon.com/global-acc
 See [the Developer Guide](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/getting-started.html) for more info.
 
   ```ts
-  const [recordName, domainName] = ['www', 'example.com'];
+  import * as s3 from '@aws-cdk/aws-s3';
+  
+  const recordName = 'www';
+  const domainName = 'example.com';
 
-  const bucketWebsite = new Bucket(this, 'BucketWebsite', {
+  const bucketWebsite = new s3.Bucket(this, 'BucketWebsite', {
     bucketName: [recordName, domainName].join('.'), // www.example.com
     publicReadAccess: true,
     websiteIndexDocument: 'index.html',
   });
 
-  const zone = HostedZone.fromLookup(this, 'Zone', {domainName}); // example.com
+  const zone = route53.HostedZone.fromLookup(this, 'Zone', {domainName}); // example.com
 
   new route53.ARecord(this, 'AliasRecord', {
     zone,
     recordName, // www
-    target: route53.RecordTarget.fromAlias(new alias.BucketWebsiteTarget(bucket)),
+    target: route53.RecordTarget.fromAlias(new targets.BucketWebsiteTarget(bucketWebsite)),
   });
   ```
 
 * User pool domain
 
   ```ts
+  import * as cognito from '@aws-cdk/aws-cognito';
+
+  declare const zone: route53.HostedZone;
+  declare const domain: cognito.UserPoolDomain;
   new route53.ARecord(this, 'AliasRecord', {
     zone,
-    target: route53.RecordTarget.fromAlias(new alias.UserPoolDomainTarget(domain)),
+    target: route53.RecordTarget.fromAlias(new targets.UserPoolDomainTarget(domain)),
   });
   ```
 
 * Route 53 record
 
   ```ts
+  declare const zone: route53.HostedZone;
+  declare const record: route53.ARecord;
   new route53.ARecord(this, 'AliasRecord', {
     zone,
     target: route53.RecordTarget.fromAlias(new targets.Route53RecordTarget(record)),
diff --git a/packages/@aws-cdk/aws-route53-targets/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-route53-targets/rosetta/default.ts-fixture
new file mode 100644
index 0000000000000..6274dd0805499
--- /dev/null
+++ b/packages/@aws-cdk/aws-route53-targets/rosetta/default.ts-fixture
@@ -0,0 +1,12 @@
+// Fixture with packages imported, but nothing else
+import { Construct } from 'constructs';
+import { Stack } from '@aws-cdk/core';
+import * as route53 from '@aws-cdk/aws-route53';
+import * as targets from '@aws-cdk/aws-route53-targets';
+
+class Fixture extends Stack {
+  constructor(scope: Construct, id: string) {
+    super(scope, id);
+    /// here
+  }
+}
diff --git a/packages/@aws-cdk/aws-route53/README.md b/packages/@aws-cdk/aws-route53/README.md
index d4376f335d848..46dce3574a130 100644
--- a/packages/@aws-cdk/aws-route53/README.md
+++ b/packages/@aws-cdk/aws-route53/README.md
@@ -14,10 +14,8 @@
 To add a public hosted zone:
 
 ```ts
-import * as route53 from '@aws-cdk/aws-route53';
-
 new route53.PublicHostedZone(this, 'HostedZone', {
-  zoneName: 'fully.qualified.domain.com'
+  zoneName: 'fully.qualified.domain.com',
 });
 ```
 
@@ -26,14 +24,11 @@ To add a private hosted zone, use `PrivateHostedZone`. Note that
 VPC you're configuring for private hosted zones.
 
 ```ts
-import * as ec2 from '@aws-cdk/aws-ec2';
-import * as route53 from '@aws-cdk/aws-route53';
-
-const vpc = new ec2.Vpc(this, 'VPC');
+declare const vpc: ec2.Vpc;
 
 const zone = new route53.PrivateHostedZone(this, 'HostedZone', {
   zoneName: 'fully.qualified.domain.com',
-  vpc    // At least one VPC has to be added to a Private Hosted Zone.
+  vpc,    // At least one VPC has to be added to a Private Hosted Zone.
 });
 ```
 
@@ -44,7 +39,7 @@ Additional VPCs can be added with `zone.addVpc()`.
 To add a TXT record to your zone:
 
 ```ts
-import * as route53 from '@aws-cdk/aws-route53';
+declare const myZone: route53.HostedZone;
 
 new route53.TxtRecord(this, 'TXTRecord', {
   zone: myZone,
@@ -54,7 +49,7 @@ new route53.TxtRecord(this, 'TXTRecord', {
                        // Defaults to zone root if not specified.
   values: [            // Will be quoted for you, and " will be escaped automatically.
     'Bar!',
-    'Baz?'
+    'Baz?',
   ],
   ttl: Duration.minutes(90),       // Optional - default is 30 minutes
 });
@@ -63,14 +58,14 @@ new route53.TxtRecord(this, 'TXTRecord', {
 To add a NS record to your zone:
 
 ```ts
-import * as route53 from '@aws-cdk/aws-route53';
+declare const myZone: route53.HostedZone;
 
 new route53.NsRecord(this, 'NSRecord', {
   zone: myZone,
   recordName: 'foo',  
   values: [            
     'ns-1.awsdns.co.uk.',
-    'ns-2.awsdns.com.'
+    'ns-2.awsdns.com.',
   ],
   ttl: Duration.minutes(90),       // Optional - default is 30 minutes
 });
@@ -79,7 +74,7 @@ new route53.NsRecord(this, 'NSRecord', {
 To add a DS record to your zone:
 
 ```ts
-import * as route53 from '@aws-cdk/aws-route53';
+declare const myZone: route53.HostedZone;
 
 new route53.DsRecord(this, 'DSRecord', {
   zone: myZone,
@@ -94,44 +89,41 @@ new route53.DsRecord(this, 'DSRecord', {
 To add an A record to your zone:
 
 ```ts
-import * as route53 from '@aws-cdk/aws-route53';
+declare const myZone: route53.HostedZone;
 
 new route53.ARecord(this, 'ARecord', {
   zone: myZone,
-  target: route53.RecordTarget.fromIpAddresses('1.2.3.4', '5.6.7.8')
+  target: route53.RecordTarget.fromIpAddresses('1.2.3.4', '5.6.7.8'),
 });
 ```
 
 To add an A record for an EC2 instance with an Elastic IP (EIP) to your zone:
 
 ```ts
-import * as ec2 from '@aws-cdk/aws-ec2';
-import * as route53 from '@aws-cdk/aws-route53';
-
-const instance = new ec2.Instance(this, 'Instance', {
-  // ...
-});
+declare const instance: ec2.Instance;
 
 const elasticIp = new ec2.CfnEIP(this, 'EIP', {
   domain: 'vpc',
-  instanceId: instance.instanceId
+  instanceId: instance.instanceId,
 });
 
+declare const myZone: route53.HostedZone;
 new route53.ARecord(this, 'ARecord', {
   zone: myZone,
-  target: route53.RecordTarget.fromIpAddresses(elasticIp.ref)
+  target: route53.RecordTarget.fromIpAddresses(elasticIp.ref),
 });
 ```
 
 To add an AAAA record pointing to a CloudFront distribution:
 
 ```ts
-import * as route53 from '@aws-cdk/aws-route53';
-import * as targets from '@aws-cdk/aws-route53-targets';
+import * as cloudfront from '@aws-cdk/aws-cloudfront';
 
+declare const myZone: route53.HostedZone;
+declare const distribution: cloudfront.CloudFrontWebDistribution;
 new route53.AaaaRecord(this, 'Alias', {
   zone: myZone,
-  target: route53.RecordTarget.fromAlias(new targets.CloudFrontTarget(distribution))
+  target: route53.RecordTarget.fromAlias(new targets.CloudFrontTarget(distribution)),
 });
 ```
 
@@ -145,8 +137,6 @@ To add a NS record to a HostedZone in different account you can do the following
 In the account containing the parent hosted zone:
 
 ```ts
-import * as route53 from '@aws-cdk/aws-route53';
-
 const parentZone = new route53.PublicHostedZone(this, 'HostedZone', {
   zoneName: 'someexample.com',
   crossAccountZoneDelegationPrincipal: new iam.AccountPrincipal('12345678901'),
@@ -157,11 +147,8 @@ const parentZone = new route53.PublicHostedZone(this, 'HostedZone', {
 In the account containing the child zone to be delegated:
 
 ```ts
-import * as iam from '@aws-cdk/aws-iam';
-import * as route53 from '@aws-cdk/aws-route53';
-
 const subZone = new route53.PublicHostedZone(this, 'SubZone', {
-  zoneName: 'sub.someexample.com'
+  zoneName: 'sub.someexample.com',
 });
 
 // import the delegation role by constructing the roleArn
@@ -188,8 +175,8 @@ If you don't know the ID of the Hosted Zone to import, you can use the
 `HostedZone.fromLookup`:
 
 ```ts
-HostedZone.fromLookup(this, 'MyZone', {
-  domainName: 'example.com'
+route53.HostedZone.fromLookup(this, 'MyZone', {
+  domainName: 'example.com',
 });
 ```
 
@@ -198,18 +185,19 @@ out the [documentation](https://docs.aws.amazon.com/cdk/latest/guide/environment
 automatically looks into your `~/.aws/config` file for the `[default]` profile.
 If you want to specify a different account run `cdk deploy --profile [profile]`.
 
-```ts
+```text
 new MyDevStack(app, 'dev', { 
   env: { 
     account: process.env.CDK_DEFAULT_ACCOUNT, 
-    region: process.env.CDK_DEFAULT_REGION 
-}});
+    region: process.env.CDK_DEFAULT_REGION,
+  },
+});
 ```
 
 If you know the ID and Name of a Hosted Zone, you can import it directly:
 
 ```ts
-const zone = HostedZone.fromHostedZoneAttributes(this, 'MyZone', {
+const zone = route53.HostedZone.fromHostedZoneAttributes(this, 'MyZone', {
   zoneName: 'example.com',
   hostedZoneId: 'ZOJJZC49E0EPZ',
 });
@@ -219,7 +207,7 @@ Alternatively, use the `HostedZone.fromHostedZoneId` to import hosted zones if
 you know the ID and the retrieval for the `zoneName` is undesirable.
 
 ```ts
-const zone = HostedZone.fromHostedZoneId(this, 'MyZone', 'ZOJJZC49E0EPZ');
+const zone = route53.HostedZone.fromHostedZoneId(this, 'MyZone', 'ZOJJZC49E0EPZ');
 ```
 
 ## VPC Endpoint Service Private DNS
@@ -245,22 +233,22 @@ Assuming your account has ownership of the particular domain/subdomain,
 this construct sets up the private DNS configuration on the endpoint service,
 creates all the necessary Route53 entries, and verifies domain ownership.
 
-```ts
+```ts nofixture
 import { Stack } from '@aws-cdk/core';
 import { Vpc, VpcEndpointService } from '@aws-cdk/aws-ec2';
 import { NetworkLoadBalancer } from '@aws-cdk/aws-elasticloadbalancingv2';
-import { PublicHostedZone } from '@aws-cdk/aws-route53';
+import { PublicHostedZone, VpcEndpointServiceDomainName } from '@aws-cdk/aws-route53';
 
-stack = new Stack();
-vpc = new Vpc(stack, 'VPC');
-nlb = new NetworkLoadBalancer(stack, 'NLB', {
+const stack = new Stack();
+const vpc = new Vpc(stack, 'VPC');
+const nlb = new NetworkLoadBalancer(stack, 'NLB', {
   vpc,
 });
-vpces = new VpcEndpointService(stack, 'VPCES', {
+const vpces = new VpcEndpointService(stack, 'VPCES', {
   vpcEndpointServiceLoadBalancers: [nlb],
 });
 // You must use a public hosted zone so domain ownership can be verified
-zone = new PublicHostedZone(stack, 'PHZ', {
+const zone = new PublicHostedZone(stack, 'PHZ', {
   zoneName: 'aws-cdk.dev',
 });
 new VpcEndpointServiceDomainName(stack, 'EndpointDomain', {
diff --git a/packages/@aws-cdk/aws-route53/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-route53/rosetta/default.ts-fixture
new file mode 100644
index 0000000000000..6473005fda521
--- /dev/null
+++ b/packages/@aws-cdk/aws-route53/rosetta/default.ts-fixture
@@ -0,0 +1,14 @@
+// Fixture with packages imported, but nothing else
+import { Construct } from 'constructs';
+import { Duration, Stack } from '@aws-cdk/core';
+import * as route53 from '@aws-cdk/aws-route53';
+import * as targets from '@aws-cdk/aws-route53-targets';
+import * as ec2 from '@aws-cdk/aws-ec2';
+import * as iam from '@aws-cdk/aws-iam';
+
+class Fixture extends Stack {
+  constructor(scope: Construct, id: string) {
+    super(scope, id);
+    /// here
+  }
+}

From 888e5a06ca67b6e7438bfcc5923eeb46f55203f1 Mon Sep 17 00:00:00 2001
From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com>
Date: Fri, 29 Oct 2021 05:28:31 -0400
Subject: [PATCH 086/148] chore(iam): make examples compile (#17195)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-iam/README.md           | 58 ++++++++++---------
 .../aws-iam/lib/permissions-boundary.ts       |  8 +--
 .../aws-iam/rosetta/default.ts-fixture        | 13 ++---
 3 files changed, 40 insertions(+), 39 deletions(-)

diff --git a/packages/@aws-cdk/aws-iam/README.md b/packages/@aws-cdk/aws-iam/README.md
index b54a0bff34fc4..a81b25d53e6ba 100644
--- a/packages/@aws-cdk/aws-iam/README.md
+++ b/packages/@aws-cdk/aws-iam/README.md
@@ -30,8 +30,8 @@ Managed policies can be attached using `xxx.addManagedPolicy(ManagedPolicy.fromA
 Many of the AWS CDK resources have `grant*` methods that allow you to grant other resources access to that resource. As an example, the following code gives a Lambda function write permissions (Put, Update, Delete) to a DynamoDB table.
 
 ```ts
-const fn = new lambda.Function(this, 'Function', functionProps);
-const table = new dynamodb.Table(this, 'Table', tableProps);
+declare const fn: lambda.Function;
+declare const table: dynamodb.Table;
 
 table.grantWriteData(fn);
 ```
@@ -39,8 +39,8 @@ table.grantWriteData(fn);
 The more generic `grant` method allows you to give specific permissions to a resource:
 
 ```ts
-const fn = new lambda.Function(this, 'Function', functionProps);
-const table = new dynamodb.Table(this, 'Table', tableProps);
+declare const fn: lambda.Function;
+declare const table: dynamodb.Table;
 
 table.grant(fn, 'dynamodb:PutItem');
 ```
@@ -186,7 +186,7 @@ const role = new iam.Role(this, 'MyRole', {
   assumedBy: new iam.CompositePrincipal(
     new iam.ServicePrincipal('ec2.amazonaws.com'),
     new iam.AccountPrincipal('1818188181818187272')
-  )
+  ),
 });
 ```
 
@@ -212,7 +212,7 @@ Cognito, Amazon, Google or Facebook, for example:
 const principal = new iam.WebIdentityPrincipal('cognito-identity.amazonaws.com')
   .withConditions({
     "StringEquals": { "cognito-identity.amazonaws.com:aud": "us-east-2:12345678-abcd-abcd-abcd-123456" },
-    "ForAnyValue:StringLike": {"cognito-identity.amazonaws.com:amr": "unauthenticated"}
+    "ForAnyValue:StringLike": {"cognito-identity.amazonaws.com:amr": "unauthenticated" },
   });
 ```
 
@@ -256,11 +256,11 @@ const customPolicyDocument = iam.PolicyDocument.fromJson(policyDocument);
 
 // You can pass this document as an initial document to a ManagedPolicy
 // or inline Policy.
-const newManagedPolicy = new ManagedPolicy(stack, 'MyNewManagedPolicy', {
-  document: customPolicyDocument
+const newManagedPolicy = new iam.ManagedPolicy(this, 'MyNewManagedPolicy', {
+  document: customPolicyDocument,
 });
-const newPolicy = new Policy(stack, 'MyNewPolicy', {
-  document: customPolicyDocument
+const newPolicy = new iam.Policy(this, 'MyNewPolicy', {
+  document: customPolicyDocument,
 });
 ```
 
@@ -296,15 +296,18 @@ const boundary2 = new iam.ManagedPolicy(this, 'Boundary2', {
 });
 
 // Directly apply the boundary to a Role you create
+declare const role: iam.Role;
 iam.PermissionsBoundary.of(role).apply(boundary);
 
 // Apply the boundary to an Role that was implicitly created for you
-iam.PermissionsBoundary.of(lambdaFunction).apply(boundary);
+declare const fn: lambda.Function;
+iam.PermissionsBoundary.of(fn).apply(boundary);
 
 // Apply the boundary to all Roles in a stack
-iam.PermissionsBoundary.of(stack).apply(boundary);
+iam.PermissionsBoundary.of(this).apply(boundary);
 
 // Remove a Permissions Boundary that is inherited, for example from the Stack level
+declare const customResource: CustomResource;
 iam.PermissionsBoundary.of(customResource).clear();
 ```
 
@@ -347,10 +350,13 @@ pool](https://docs.aws.amazon.com/cognito/latest/developerguide/open-id.html)
 you can reference the provider's ARN as follows:
 
 ```ts
+import * as cognito from '@aws-cdk/aws-cognito';
+
+declare const myProvider: iam.OpenIdConnectProvider;
 new cognito.CfnIdentityPool(this, 'IdentityPool', {
   openIdConnectProviderArns: [myProvider.openIdConnectProviderArn],
   // And the other properties for your identity pool
-  allowUnauthenticatedIdentities,
+  allowUnauthenticatedIdentities: false,
 });
 ```
 
@@ -359,7 +365,7 @@ The `OpenIdConnectPrincipal` class can be used as a principal used with a `OpenI
 ```ts
 const provider = new iam.OpenIdConnectProvider(this, 'MyProvider', {
   url: 'https://openid/connect',
-  clientIds: [ 'myclient1', 'myclient2' ]
+  clientIds: [ 'myclient1', 'myclient2' ],
 });
 const principal = new iam.OpenIdConnectPrincipal(provider);
 ```
@@ -410,25 +416,25 @@ new iam.Role(this, 'Role', {
 IAM manages users for your AWS account. To create a new user:
 
 ```ts
-const user = new User(this, 'MyUser');
+const user = new iam.User(this, 'MyUser');
 ```
 
 To import an existing user by name [with path](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-friendly-names):
 
 ```ts
-const user = User.fromUserName(stack, 'MyImportedUserByName', 'johnsmith');
+const user = iam.User.fromUserName(this, 'MyImportedUserByName', 'johnsmith');
 ```
 
 To import an existing user by ARN:
 
 ```ts
-const user = User.fromUserArn(this, 'MyImportedUserByArn', 'arn:aws:iam::123456789012:user/johnsmith');
+const user = iam.User.fromUserArn(this, 'MyImportedUserByArn', 'arn:aws:iam::123456789012:user/johnsmith');
 ```
 
 To import an existing user by attributes:
 
 ```ts
-const user = User.fromUserAttributes(stack, 'MyImportedUserByAttributes', {
+const user = iam.User.fromUserAttributes(this, 'MyImportedUserByAttributes', {
   userArn: 'arn:aws:iam::123456789012:user/johnsmith',
 });
 ```
@@ -436,8 +442,8 @@ const user = User.fromUserAttributes(stack, 'MyImportedUserByAttributes', {
 To add a user to a group (both for a new and imported user/group):
 
 ```ts
-const user = new User(this, 'MyUser'); // or User.fromUserName(stack, 'User', 'johnsmith');
-const group = new Group(this, 'MyGroup'); // or Group.fromGroupArn(stack, 'Group', 'arn:aws:iam::account-id:group/group-name');
+const user = new iam.User(this, 'MyUser'); // or User.fromUserName(stack, 'User', 'johnsmith');
+const group = new iam.Group(this, 'MyGroup'); // or Group.fromGroupArn(stack, 'Group', 'arn:aws:iam::account-id:group/group-name');
 
 user.addToGroup(group);
 // or
@@ -447,9 +453,9 @@ group.addUser(user);
 
 ## Features
 
- * Policy name uniqueness is enforced. If two policies by the same name are attached to the same
-   principal, the attachment will fail.
- * Policy names are not required - the CDK logical ID will be used and ensured to be unique.
- * Policies are validated during synthesis to ensure that they have actions, and that policies
-   attached to IAM principals specify relevant resources, while policies attached to resources
-   specify which IAM principals they apply to.
+  * Policy name uniqueness is enforced. If two policies by the same name are attached to the same
+    principal, the attachment will fail.
+  * Policy names are not required - the CDK logical ID will be used and ensured to be unique.
+  * Policies are validated during synthesis to ensure that they have actions, and that policies
+    attached to IAM principals specify relevant resources, while policies attached to resources
+    specify which IAM principals they apply to.
diff --git a/packages/@aws-cdk/aws-iam/lib/permissions-boundary.ts b/packages/@aws-cdk/aws-iam/lib/permissions-boundary.ts
index c1a3dde69a026..5084caf9fe4fc 100644
--- a/packages/@aws-cdk/aws-iam/lib/permissions-boundary.ts
+++ b/packages/@aws-cdk/aws-iam/lib/permissions-boundary.ts
@@ -6,10 +6,10 @@ import { IManagedPolicy } from './managed-policy';
 /**
  * Modify the Permissions Boundaries of Users and Roles in a construct tree
  *
- * @example
- *
- * const policy = ManagedPolicy.fromAwsManagedPolicyName('ReadOnlyAccess');
- * PermissionsBoundary.of(stack).apply(policy);
+ * ```ts
+ * const policy = iam.ManagedPolicy.fromAwsManagedPolicyName('ReadOnlyAccess');
+ * iam.PermissionsBoundary.of(this).apply(policy);
+ * ```
  */
 export class PermissionsBoundary {
   /**
diff --git a/packages/@aws-cdk/aws-iam/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-iam/rosetta/default.ts-fixture
index a76493f53c694..a27f557ccf250 100644
--- a/packages/@aws-cdk/aws-iam/rosetta/default.ts-fixture
+++ b/packages/@aws-cdk/aws-iam/rosetta/default.ts-fixture
@@ -1,17 +1,12 @@
-import { Construct } from '@aws-cdk/core';
+import { Construct } from 'constructs';
+import { CustomResource, Stack } from '@aws-cdk/core';
 import * as codepipeline from '@aws-cdk/aws-codepipeline';
-import * as cognito from '@aws-cdk/aws-cognito';
 import * as dynamodb from '@aws-cdk/aws-dynamodb';
 import * as lambda from '@aws-cdk/aws-lambda';
 import * as iam from '@aws-cdk/aws-iam';
 
-declare const allowUnauthenticatedIdentities: boolean;
-declare const functionProps: lambda.FunctionProps;
-declare const myProvider: iam.OpenIdConnectProvider;
-declare const tableProps: dynamodb.TableProps;
-
-class fixture$construct extends Construct {
-  public constructor(scope: Construct, id: string) {
+class Fixture extends Stack {
+  constructor(scope: Construct, id: string) {
     super(scope, id);
 
     /// here

From 0a23953d92df070736f7d036cc2b24e68de4bf64 Mon Sep 17 00:00:00 2001
From: Kyle Roach 
Date: Fri, 29 Oct 2021 06:33:01 -0400
Subject: [PATCH 087/148] fix(elasticloadbalancingv2): always set stickiness
 (#17111)

CloudFormation does not process the removal of the stickiness attribute from the template as a delta that needs to be processed.

This results in scenarios where if a property was set in an application, that removing it would have no effect.

The fix to this is to always explicitly set the property so that a delta is always processed.

Fixes #16620


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../integ.all-service-addons.expected.json    | 22 ++++++++++-------
 .../integ.imported-environment.expected.json  | 22 ++++++++++-------
 .../test/http/integ.alb.expected.json         | 24 ++++++++++++-------
 .../test/integ.asg-w-elbv2.expected.json      | 18 +++++++++-----
 ...on-load-balanced-ecs-service.expected.json | 12 ++++++++++
 ...eg.alb-fargate-service-https.expected.json |  6 +++++
 .../fargate/integ.asset-image.expected.json   |  6 +++++
 ...oad-balanced-fargate-service.expected.json |  6 +++++
 .../fargate/integ.executionrole.expected.json |  6 +++++
 .../fargate/integ.l3-autocreate.expected.json |  6 +++++
 .../fargate/integ.l3-vpconly.expected.json    |  6 +++++
 .../test/fargate/integ.l3.expected.json       |  6 +++++
 .../integ.special-listener.expected.json      |  6 +++++
 .../test/ec2/integ.lb-awsvpc-nw.expected.json | 18 +++++++++-----
 .../test/ec2/integ.lb-bridge-nw.expected.json | 18 +++++++++-----
 .../fargate/integ.lb-awsvpc-nw.expected.json  | 18 +++++++++-----
 .../test/integ.alb-target.expected.json       |  6 +++++
 .../test/integ.lambda-target.expected.json    | 14 +++++++----
 .../lib/alb/application-target-group.ts       |  4 ++++
 .../test/alb/listener.test.ts                 |  8 +++++++
 .../test/alb/target-group.test.ts             |  4 ++++
 .../test/integ.alb.dualstack.expected.json    | 24 ++++++++++++++-----
 .../test/integ.alb2.expected.json             | 24 ++++++++++++++-----
 23 files changed, 217 insertions(+), 67 deletions(-)

diff --git a/packages/@aws-cdk-containers/ecs-service-extensions/test/integ.all-service-addons.expected.json b/packages/@aws-cdk-containers/ecs-service-extensions/test/integ.all-service-addons.expected.json
index afdf0319a819a..bd9224e586933 100644
--- a/packages/@aws-cdk-containers/ecs-service-extensions/test/integ.all-service-addons.expected.json
+++ b/packages/@aws-cdk-containers/ecs-service-extensions/test/integ.all-service-addons.expected.json
@@ -102,15 +102,15 @@
     "productionenvironmentvpcPublicSubnet1NATGateway6075E4CA": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "productionenvironmentvpcPublicSubnet1Subnet8D92C089"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "productionenvironmentvpcPublicSubnet1EIP54BA88DB",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "productionenvironmentvpcPublicSubnet1Subnet8D92C089"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -199,15 +199,15 @@
     "productionenvironmentvpcPublicSubnet2NATGatewayE1850FCC": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "productionenvironmentvpcPublicSubnet2Subnet298E6C31"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "productionenvironmentvpcPublicSubnet2EIP14CA46AA",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "productionenvironmentvpcPublicSubnet2Subnet298E6C31"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -296,15 +296,15 @@
     "productionenvironmentvpcPublicSubnet3NATGateway94604057": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "productionenvironmentvpcPublicSubnet3SubnetC7B5665D"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "productionenvironmentvpcPublicSubnet3EIP53405AED",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "productionenvironmentvpcPublicSubnet3SubnetC7B5665D"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -2391,6 +2391,10 @@
           {
             "Key": "deregistration_delay.timeout_seconds",
             "Value": "10"
+          },
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
           }
         ],
         "TargetType": "ip",
diff --git a/packages/@aws-cdk-containers/ecs-service-extensions/test/integ.imported-environment.expected.json b/packages/@aws-cdk-containers/ecs-service-extensions/test/integ.imported-environment.expected.json
index dbc216370e40d..c85f5d9b0231d 100644
--- a/packages/@aws-cdk-containers/ecs-service-extensions/test/integ.imported-environment.expected.json
+++ b/packages/@aws-cdk-containers/ecs-service-extensions/test/integ.imported-environment.expected.json
@@ -17,7 +17,7 @@
               },
               "/",
               {
-                "Ref": "AssetParametersb537a3d3462b62d59d4661ff456403d270823b5c9974ea4f4264ff95683a8ba8S3Bucket60C7B412"
+                "Ref": "AssetParameterse2fc78c01b63f40b6bbcc8ce3c0eaccd3bf8f0aa6196b65f8ee87fb97e343886S3Bucket85F9E22A"
               },
               "/",
               {
@@ -27,7 +27,7 @@
                     "Fn::Split": [
                       "||",
                       {
-                        "Ref": "AssetParametersb537a3d3462b62d59d4661ff456403d270823b5c9974ea4f4264ff95683a8ba8S3VersionKey6900DC52"
+                        "Ref": "AssetParameterse2fc78c01b63f40b6bbcc8ce3c0eaccd3bf8f0aa6196b65f8ee87fb97e343886S3VersionKey8103F967"
                       }
                     ]
                   }
@@ -40,7 +40,7 @@
                     "Fn::Split": [
                       "||",
                       {
-                        "Ref": "AssetParametersb537a3d3462b62d59d4661ff456403d270823b5c9974ea4f4264ff95683a8ba8S3VersionKey6900DC52"
+                        "Ref": "AssetParameterse2fc78c01b63f40b6bbcc8ce3c0eaccd3bf8f0aa6196b65f8ee87fb97e343886S3VersionKey8103F967"
                       }
                     ]
                   }
@@ -163,6 +163,10 @@
           {
             "Key": "deregistration_delay.timeout_seconds",
             "Value": "10"
+          },
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
           }
         ],
         "TargetType": "ip",
@@ -358,17 +362,17 @@
     }
   },
   "Parameters": {
-    "AssetParametersb537a3d3462b62d59d4661ff456403d270823b5c9974ea4f4264ff95683a8ba8S3Bucket60C7B412": {
+    "AssetParameterse2fc78c01b63f40b6bbcc8ce3c0eaccd3bf8f0aa6196b65f8ee87fb97e343886S3Bucket85F9E22A": {
       "Type": "String",
-      "Description": "S3 bucket for asset \"b537a3d3462b62d59d4661ff456403d270823b5c9974ea4f4264ff95683a8ba8\""
+      "Description": "S3 bucket for asset \"e2fc78c01b63f40b6bbcc8ce3c0eaccd3bf8f0aa6196b65f8ee87fb97e343886\""
     },
-    "AssetParametersb537a3d3462b62d59d4661ff456403d270823b5c9974ea4f4264ff95683a8ba8S3VersionKey6900DC52": {
+    "AssetParameterse2fc78c01b63f40b6bbcc8ce3c0eaccd3bf8f0aa6196b65f8ee87fb97e343886S3VersionKey8103F967": {
       "Type": "String",
-      "Description": "S3 key for asset version \"b537a3d3462b62d59d4661ff456403d270823b5c9974ea4f4264ff95683a8ba8\""
+      "Description": "S3 key for asset version \"e2fc78c01b63f40b6bbcc8ce3c0eaccd3bf8f0aa6196b65f8ee87fb97e343886\""
     },
-    "AssetParametersb537a3d3462b62d59d4661ff456403d270823b5c9974ea4f4264ff95683a8ba8ArtifactHash5EEB924C": {
+    "AssetParameterse2fc78c01b63f40b6bbcc8ce3c0eaccd3bf8f0aa6196b65f8ee87fb97e343886ArtifactHash6FA4ABA8": {
       "Type": "String",
-      "Description": "Artifact hash for asset \"b537a3d3462b62d59d4661ff456403d270823b5c9974ea4f4264ff95683a8ba8\""
+      "Description": "Artifact hash for asset \"e2fc78c01b63f40b6bbcc8ce3c0eaccd3bf8f0aa6196b65f8ee87fb97e343886\""
     }
   }
 }
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.expected.json b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.expected.json
index b9f5d96ff4656..65149587fb3ce 100644
--- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.expected.json
+++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.expected.json
@@ -95,15 +95,15 @@
     "VPCPublicSubnet1NATGatewayE0556630": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet1SubnetB4246D30"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet1EIP6AD938E8",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet1SubnetB4246D30"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -192,15 +192,15 @@
     "VPCPublicSubnet2NATGateway3C070193": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet2Subnet74179F39"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet2EIP4947BC00",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet2Subnet74179F39"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -289,15 +289,15 @@
     "VPCPublicSubnet3NATGatewayD3048F5C": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet3Subnet631C5E25"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet3EIPAD4BC883",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet3Subnet631C5E25"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -596,6 +596,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "VpcId": {
           "Ref": "VPCB9E5F0B4"
         }
diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.expected.json b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.expected.json
index 34f240a76559d..236be6f46be9e 100644
--- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.expected.json
+++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.expected.json
@@ -95,15 +95,15 @@
     "VPCPublicSubnet1NATGatewayE0556630": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet1SubnetB4246D30"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet1EIP6AD938E8",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet1SubnetB4246D30"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -192,15 +192,15 @@
     "VPCPublicSubnet2NATGateway3C070193": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet2Subnet74179F39"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet2EIP4947BC00",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet2Subnet74179F39"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -671,6 +671,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "instance",
         "VpcId": {
           "Ref": "VPCB9E5F0B4"
diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/ec2/integ.multiple-application-load-balanced-ecs-service.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/ec2/integ.multiple-application-load-balanced-ecs-service.expected.json
index 5ce81fe00ad59..4d4e00fe664e4 100644
--- a/packages/@aws-cdk/aws-ecs-patterns/test/ec2/integ.multiple-application-load-balanced-ecs-service.expected.json
+++ b/packages/@aws-cdk/aws-ecs-patterns/test/ec2/integ.multiple-application-load-balanced-ecs-service.expected.json
@@ -954,6 +954,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "instance",
         "VpcId": {
           "Ref": "Vpc8378EB38"
@@ -965,6 +971,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "instance",
         "VpcId": {
           "Ref": "Vpc8378EB38"
diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https.expected.json
index 76713f6d4ef64..ee6317ba0f94f 100644
--- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https.expected.json
+++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https.expected.json
@@ -467,6 +467,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "ip",
         "VpcId": {
           "Ref": "Vpc8378EB38"
diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.asset-image.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.asset-image.expected.json
index dc589f5d6c48f..1be85fbb5e688 100644
--- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.asset-image.expected.json
+++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.asset-image.expected.json
@@ -453,6 +453,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "ip",
         "VpcId": {
           "Ref": "Vpc8378EB38"
diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.circuit-breaker-load-balanced-fargate-service.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.circuit-breaker-load-balanced-fargate-service.expected.json
index 24b4bb012e384..e43d5c95abf8b 100644
--- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.circuit-breaker-load-balanced-fargate-service.expected.json
+++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.circuit-breaker-load-balanced-fargate-service.expected.json
@@ -453,6 +453,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "ip",
         "VpcId": {
           "Ref": "Vpc8378EB38"
diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.executionrole.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.executionrole.expected.json
index b3921b410fabd..6d2654abe539c 100644
--- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.executionrole.expected.json
+++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.executionrole.expected.json
@@ -502,6 +502,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "ip",
         "VpcId": {
           "Ref": "Vpc8378EB38"
diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-autocreate.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-autocreate.expected.json
index 61b34b57938cd..a61c1948d90fe 100644
--- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-autocreate.expected.json
+++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-autocreate.expected.json
@@ -95,6 +95,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "ip",
         "VpcId": {
           "Ref": "EcsDefaultClusterMnL3mNNYNVpc7788A521"
diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-vpconly.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-vpconly.expected.json
index d63db295a39cc..771eef386379d 100644
--- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-vpconly.expected.json
+++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-vpconly.expected.json
@@ -450,6 +450,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "ip",
         "VpcId": {
           "Ref": "Vpc8378EB38"
diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.expected.json
index 886e4a35dcf63..7ea739f68ff99 100644
--- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.expected.json
+++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.expected.json
@@ -453,6 +453,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "ip",
         "VpcId": {
           "Ref": "Vpc8378EB38"
diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.special-listener.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.special-listener.expected.json
index 7fa930b16d66d..91c1f4e575e23 100644
--- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.special-listener.expected.json
+++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.special-listener.expected.json
@@ -692,6 +692,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "ip",
         "VpcId": {
           "Ref": "Vpc8378EB38"
diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.expected.json
index 1fef2d83e2784..fb1143317da2c 100644
--- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.expected.json
+++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.expected.json
@@ -95,15 +95,15 @@
     "VpcPublicSubnet1NATGateway4D7517AA": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VpcPublicSubnet1EIPD7E02669",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -192,15 +192,15 @@
     "VpcPublicSubnet2NATGateway9182C01D": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VpcPublicSubnet2Subnet691E08A3"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VpcPublicSubnet2EIP3C605A87",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VpcPublicSubnet2Subnet691E08A3"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -1070,6 +1070,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "ip",
         "VpcId": {
           "Ref": "Vpc8378EB38"
diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.expected.json
index 1bcb9d34f8dbd..662773111278c 100644
--- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.expected.json
+++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.expected.json
@@ -95,15 +95,15 @@
     "VpcPublicSubnet1NATGateway4D7517AA": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VpcPublicSubnet1EIPD7E02669",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -192,15 +192,15 @@
     "VpcPublicSubnet2NATGateway9182C01D": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VpcPublicSubnet2Subnet691E08A3"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VpcPublicSubnet2EIP3C605A87",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VpcPublicSubnet2Subnet691E08A3"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -1034,6 +1034,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "instance",
         "VpcId": {
           "Ref": "Vpc8378EB38"
diff --git a/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.expected.json b/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.expected.json
index b0e138464af2a..de47fd2260762 100644
--- a/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.expected.json
+++ b/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.expected.json
@@ -95,15 +95,15 @@
     "VpcPublicSubnet1NATGateway4D7517AA": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VpcPublicSubnet1EIPD7E02669",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -192,15 +192,15 @@
     "VpcPublicSubnet2NATGateway9182C01D": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VpcPublicSubnet2Subnet691E08A3"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VpcPublicSubnet2EIP3C605A87",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VpcPublicSubnet2Subnet691E08A3"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -649,6 +649,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "ip",
         "VpcId": {
           "Ref": "Vpc8378EB38"
diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/test/integ.alb-target.expected.json b/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/test/integ.alb-target.expected.json
index 8832e3edf3726..ff70395ffda8b 100644
--- a/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/test/integ.alb-target.expected.json
+++ b/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/test/integ.alb-target.expected.json
@@ -462,6 +462,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "TargetType": "ip",
         "VpcId": {
           "Ref": "Vpc8378EB38"
diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/test/integ.lambda-target.expected.json b/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/test/integ.lambda-target.expected.json
index cca2c6d366998..75905be0cd5ba 100644
--- a/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/test/integ.lambda-target.expected.json
+++ b/packages/@aws-cdk/aws-elasticloadbalancingv2-targets/test/integ.lambda-target.expected.json
@@ -95,15 +95,15 @@
     "StackPublicSubnet1NATGatewayD2E1ABF7": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "StackPublicSubnet1Subnet0AD81D22"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "StackPublicSubnet1EIPBDAAB2A5",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "StackPublicSubnet1Subnet0AD81D22"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -404,6 +404,12 @@
     "LBListenerTargetsGroup76EF81E8": {
       "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
       "Properties": {
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "Targets": [
           {
             "Id": {
@@ -457,13 +463,13 @@
         "Code": {
           "ZipFile": "\ndef handler(event, context):\n  return {\n    \"isBase64Encoded\": False,\n    \"statusCode\": 200,\n    \"statusDescription\": \"200 OK\",\n    \"headers\": {\n        \"Set-cookie\": \"cookies\",\n        \"Content-Type\": \"application/json\"\n    },\n    \"body\": \"Hello from Lambda\"\n  }\n      "
         },
-        "Handler": "index.handler",
         "Role": {
           "Fn::GetAtt": [
             "FunServiceRole3CC876D7",
             "Arn"
           ]
         },
+        "Handler": "index.handler",
         "Runtime": "python3.6"
       },
       "DependsOn": [
diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts
index d1329665ba7d6..025d655aef181 100644
--- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts
+++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-target-group.ts
@@ -144,9 +144,13 @@ export class ApplicationTargetGroup extends TargetGroupBase implements IApplicat
         }
         this.setAttribute('slow_start.duration_seconds', props.slowStart.toSeconds().toString());
       }
+
       if (props.stickinessCookieDuration) {
         this.enableCookieStickiness(props.stickinessCookieDuration, props.stickinessCookieName);
+      } else {
+        this.setAttribute('stickiness.enabled', 'false');
       }
+
       if (props.loadBalancingAlgorithmType) {
         this.setAttribute('load_balancing.algorithm.type', props.loadBalancingAlgorithmType);
       }
diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/listener.test.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/listener.test.ts
index 885c872482e9c..c47585d98a5f7 100644
--- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/listener.test.ts
+++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/listener.test.ts
@@ -862,6 +862,10 @@ describe('tests', () => {
           Key: 'deregistration_delay.timeout_seconds',
           Value: '30',
         },
+        {
+          Key: 'stickiness.enabled',
+          Value: 'false',
+        },
       ],
     });
   });
@@ -883,6 +887,10 @@ describe('tests', () => {
     // THEN
     expect(stack).toHaveResource('AWS::ElasticLoadBalancingV2::TargetGroup', {
       TargetGroupAttributes: [
+        {
+          Key: 'stickiness.enabled',
+          Value: 'false',
+        },
         {
           Key: 'load_balancing.algorithm.type',
           Value: 'least_outstanding_requests',
diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/target-group.test.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/target-group.test.ts
index 078be310dd3f8..313985e09d3ee 100644
--- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/target-group.test.ts
+++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/target-group.test.ts
@@ -171,6 +171,10 @@ describe('tests', () => {
     // THEN
     expect(stack).toHaveResource('AWS::ElasticLoadBalancingV2::TargetGroup', {
       TargetGroupAttributes: [
+        {
+          Key: 'stickiness.enabled',
+          Value: 'false',
+        },
         {
           Key: 'load_balancing.algorithm.type',
           Value: 'least_outstanding_requests',
diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.dualstack.expected.json b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.dualstack.expected.json
index 4358667cb43ed..780859bd7f314 100644
--- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.dualstack.expected.json
+++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.dualstack.expected.json
@@ -120,15 +120,15 @@
     "VPCPublicSubnet1NATGatewayE0556630": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet1SubnetB4246D30"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet1EIP6AD938E8",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet1SubnetB4246D30"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -254,15 +254,15 @@
     "VPCPublicSubnet2NATGateway3C070193": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet2Subnet74179F39"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet2EIP4947BC00",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet2Subnet74179F39"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -529,6 +529,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "Targets": [
           {
             "Id": "10.0.128.4"
@@ -545,6 +551,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "Targets": [
           {
             "Id": "10.0.128.5"
diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb2.expected.json b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb2.expected.json
index ef8989719a37e..9aa4015d15f18 100644
--- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb2.expected.json
+++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb2.expected.json
@@ -95,15 +95,15 @@
     "VPCPublicSubnet1NATGatewayE0556630": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet1SubnetB4246D30"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet1EIP6AD938E8",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet1SubnetB4246D30"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -192,15 +192,15 @@
     "VPCPublicSubnet2NATGateway3C070193": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet2Subnet74179F39"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet2EIP4947BC00",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet2Subnet74179F39"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -438,6 +438,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "Targets": [
           {
             "Id": "10.0.128.4"
@@ -454,6 +460,12 @@
       "Properties": {
         "Port": 80,
         "Protocol": "HTTP",
+        "TargetGroupAttributes": [
+          {
+            "Key": "stickiness.enabled",
+            "Value": "false"
+          }
+        ],
         "Targets": [
           {
             "Id": "10.0.128.5"

From 7a333b018c9bb2430165177d3e65614cf1d66519 Mon Sep 17 00:00:00 2001
From: Jonathan Goldwasser 
Date: Fri, 29 Oct 2021 13:28:43 +0200
Subject: [PATCH 088/148] feat(core): subtract Durations (#16734)

Add a `.minus()` method to `Duration`.

Closes #16535


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/core/README.md             |  9 ++++++++-
 packages/@aws-cdk/core/lib/duration.ts       | 13 +++++++++++--
 packages/@aws-cdk/core/test/duration.test.ts |  6 +++++-
 packages/aws-cdk-lib/README.md               |  9 ++++++++-
 4 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/packages/@aws-cdk/core/README.md b/packages/@aws-cdk/core/README.md
index 79ac6e6bb3e4d..611467116459e 100644
--- a/packages/@aws-cdk/core/README.md
+++ b/packages/@aws-cdk/core/README.md
@@ -172,6 +172,13 @@ Duration.days(7)        // 7 days
 Duration.parse('PT5M')  // 5 minutes
 ```
 
+Durations can be added or subtracted together:
+
+```ts
+Duration.minutes(1).plus(Duration.seconds(60)); // 2 minutes
+Duration.minutes(5).minus(Duration.seconds(10)); // 290 secondes
+```
+
 ## Size (Digital Information Quantity)
 
 To make specification of digital storage quantities unambiguous, a class called
@@ -805,7 +812,7 @@ regionTable.findInMap('us-east-2', 'regionName');
 ```
 
 On the other hand, the following code will produce the "Mappings" section shown above,
-since the top-level key is an unresolved token. The call to `findInMap` will return a token that resolves to 
+since the top-level key is an unresolved token. The call to `findInMap` will return a token that resolves to
 `{ "Fn::FindInMap": [ "RegionTable", { "Ref": "AWS::Region" }, "regionName" ] }`.
 
 ```ts
diff --git a/packages/@aws-cdk/core/lib/duration.ts b/packages/@aws-cdk/core/lib/duration.ts
index 0061e7928e900..5c7bb804b917c 100644
--- a/packages/@aws-cdk/core/lib/duration.ts
+++ b/packages/@aws-cdk/core/lib/duration.ts
@@ -105,8 +105,17 @@ export class Duration {
    */
   public plus(rhs: Duration): Duration {
     const targetUnit = finestUnit(this.unit, rhs.unit);
-    const total = convert(this.amount, this.unit, targetUnit, {}) + convert(rhs.amount, rhs.unit, targetUnit, {});
-    return new Duration(total, targetUnit);
+    const res = convert(this.amount, this.unit, targetUnit, {}) + convert(rhs.amount, rhs.unit, targetUnit, {});
+    return new Duration(res, targetUnit);
+  }
+
+  /**
+   * Substract two Durations together
+   */
+  public minus(rhs: Duration): Duration {
+    const targetUnit = finestUnit(this.unit, rhs.unit);
+    const res = convert(this.amount, this.unit, targetUnit, {}) - convert(rhs.amount, rhs.unit, targetUnit, {});
+    return new Duration(res, targetUnit);
   }
 
   /**
diff --git a/packages/@aws-cdk/core/test/duration.test.ts b/packages/@aws-cdk/core/test/duration.test.ts
index 68da12881d3ba..c7cf230308634 100644
--- a/packages/@aws-cdk/core/test/duration.test.ts
+++ b/packages/@aws-cdk/core/test/duration.test.ts
@@ -170,8 +170,12 @@ describe('duration', () => {
     expect(Duration.minutes(1).plus(Duration.seconds(30)).toSeconds()).toEqual(Duration.seconds(90).toSeconds());
     expect(Duration.minutes(1).plus(Duration.seconds(30)).toMinutes({ integral: false }))
       .toEqual(Duration.seconds(90).toMinutes({ integral: false }));
+  });
 
-
+  test('subtract two durations', () => {
+    expect(Duration.minutes(1).minus(Duration.seconds(30)).toSeconds()).toEqual(Duration.seconds(30).toSeconds());
+    expect(Duration.minutes(1).minus(Duration.seconds(30)).toMinutes({ integral: false }))
+      .toEqual(Duration.seconds(30).toMinutes({ integral: false }));
   });
 
   test('get unit label from duration', () => {
diff --git a/packages/aws-cdk-lib/README.md b/packages/aws-cdk-lib/README.md
index 40fc7c0d880af..254a58738b26d 100644
--- a/packages/aws-cdk-lib/README.md
+++ b/packages/aws-cdk-lib/README.md
@@ -205,6 +205,13 @@ Duration.days(7)        // 7 days
 Duration.parse('PT5M')  // 5 minutes
 ```
 
+Durations can be added or subtracted together:
+
+```ts
+Duration.minutes(1).plus(Duration.seconds(60)); // 2 minutes
+Duration.minutes(5).minus(Duration.seconds(10)); // 290 secondes
+```
+
 ## Size (Digital Information Quantity)
 
 To make specification of digital storage quantities unambiguous, a class called
@@ -838,7 +845,7 @@ regionTable.findInMap('us-east-2', 'regionName');
 ```
 
 On the other hand, the following code will produce the "Mappings" section shown above,
-since the top-level key is an unresolved token. The call to `findInMap` will return a token that resolves to 
+since the top-level key is an unresolved token. The call to `findInMap` will return a token that resolves to
 `{ "Fn::FindInMap": [ "RegionTable", { "Ref": "AWS::Region" }, "regionName" ] }`.
 
 ```ts

From 56974ac4152bc082470d56dd66e4ef7aad042815 Mon Sep 17 00:00:00 2001
From: Makoto Nagai 
Date: Fri, 29 Oct 2021 14:26:41 +0200
Subject: [PATCH 089/148] fix(lambda-event-sources): dynamo batch size cannot
 be a CfnParameter (#16540)

fixes #16221

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../aws-lambda-event-sources/lib/dynamodb.ts  |  6 ++-
 .../test/dynamo.test.ts                       | 43 +++++++++++++++++++
 2 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/packages/@aws-cdk/aws-lambda-event-sources/lib/dynamodb.ts b/packages/@aws-cdk/aws-lambda-event-sources/lib/dynamodb.ts
index f316ba69cf9ed..3d0fd78c915fc 100644
--- a/packages/@aws-cdk/aws-lambda-event-sources/lib/dynamodb.ts
+++ b/packages/@aws-cdk/aws-lambda-event-sources/lib/dynamodb.ts
@@ -1,6 +1,6 @@
 import * as dynamodb from '@aws-cdk/aws-dynamodb';
 import * as lambda from '@aws-cdk/aws-lambda';
-import { Names } from '@aws-cdk/core';
+import { Names, Token } from '@aws-cdk/core';
 import { StreamEventSource, StreamEventSourceProps } from './stream';
 
 export interface DynamoEventSourceProps extends StreamEventSourceProps {
@@ -15,7 +15,9 @@ export class DynamoEventSource extends StreamEventSource {
   constructor(private readonly table: dynamodb.ITable, props: DynamoEventSourceProps) {
     super(props);
 
-    if (this.props.batchSize !== undefined && (this.props.batchSize < 1 || this.props.batchSize > 1000)) {
+    if (this.props.batchSize !== undefined
+      && !Token.isUnresolved(this.props.batchSize)
+      && (this.props.batchSize < 1 || this.props.batchSize > 1000)) {
       throw new Error(`Maximum batch size must be between 1 and 1000 inclusive (given ${this.props.batchSize})`);
     }
   }
diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/dynamo.test.ts b/packages/@aws-cdk/aws-lambda-event-sources/test/dynamo.test.ts
index 3e90ab5a4ab3b..97bd42c07145f 100644
--- a/packages/@aws-cdk/aws-lambda-event-sources/test/dynamo.test.ts
+++ b/packages/@aws-cdk/aws-lambda-event-sources/test/dynamo.test.ts
@@ -136,6 +136,49 @@ describe('DynamoEventSource', () => {
     });
 
 
+  });
+
+  test('pass validation if batchsize is token', () => {
+    // GIVEN
+    const stack = new cdk.Stack();
+    const fn = new TestFunction(stack, 'Fn');
+    const table = new dynamodb.Table(stack, 'T', {
+      partitionKey: {
+        name: 'id',
+        type: dynamodb.AttributeType.STRING,
+      },
+      stream: dynamodb.StreamViewType.NEW_IMAGE,
+    });
+    const batchSize = new cdk.CfnParameter(stack, 'BatchSize', {
+      type: 'Number',
+      default: 100,
+      minValue: 1,
+      maxValue: 1000,
+    });
+    // WHEN
+    fn.addEventSource(new sources.DynamoEventSource(table, {
+      batchSize: batchSize.valueAsNumber,
+      startingPosition: lambda.StartingPosition.LATEST,
+    }));
+
+    // THEN
+    Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', {
+      'EventSourceArn': {
+        'Fn::GetAtt': [
+          'TD925BC7E',
+          'StreamArn',
+        ],
+      },
+      'FunctionName': {
+        'Ref': 'Fn9270CBC0',
+      },
+      'BatchSize': {
+        'Ref': 'BatchSize',
+      },
+      'StartingPosition': 'LATEST',
+    });
+
+
   });
 
   test('fails if streaming not enabled on table', () => {

From 56033a2a6d4be0444694d9f88260c574a4fa1a1d Mon Sep 17 00:00:00 2001
From: Jonathan Goldwasser 
Date: Fri, 29 Oct 2021 15:20:26 +0200
Subject: [PATCH 090/148] feat(lambda-nodejs): esbuild charset option (#16726)

Support `esbuild` charset option.

Closes #16668


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-lambda-nodejs/README.md |  5 ++-
 .../aws-lambda-nodejs/lib/bundling.ts         |  1 +
 .../@aws-cdk/aws-lambda-nodejs/lib/types.ts   | 38 +++++++++++++++++--
 .../aws-lambda-nodejs/test/bundling.test.ts   |  4 +-
 4 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/packages/@aws-cdk/aws-lambda-nodejs/README.md b/packages/@aws-cdk/aws-lambda-nodejs/README.md
index 6e901612539d8..9bf47f0631d57 100644
--- a/packages/@aws-cdk/aws-lambda-nodejs/README.md
+++ b/packages/@aws-cdk/aws-lambda-nodejs/README.md
@@ -187,8 +187,9 @@ new lambda.NodejsFunction(this, 'my-handler', {
     keepNames: true, // defaults to false
     tsconfig: 'custom-tsconfig.json', // use custom-tsconfig.json instead of default,
     metafile: true, // include meta file, defaults to false
-    banner : '/* comments */', // requires esbuild >= 0.9.0, defaults to none
-    footer : '/* comments */', // requires esbuild >= 0.9.0, defaults to none
+    banner: '/* comments */', // requires esbuild >= 0.9.0, defaults to none
+    footer: '/* comments */', // requires esbuild >= 0.9.0, defaults to none
+    charset: Charset.UTF8, // do not escape non-ASCII characters, defaults to Charset.ASCII
   },
 });
 ```
diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts
index e53e5e092de7c..3bd05a7ccb39d 100644
--- a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts
+++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts
@@ -200,6 +200,7 @@ export class Bundling implements cdk.BundlingOptions {
       ...this.props.metafile ? [`--metafile=${pathJoin(options.outputDir, 'index.meta.json')}`] : [],
       ...this.props.banner ? [`--banner:js=${JSON.stringify(this.props.banner)}`] : [],
       ...this.props.footer ? [`--footer:js=${JSON.stringify(this.props.footer)}`] : [],
+      ...this.props.charset ? [`--charset=${this.props.charset}`] : [],
     ];
 
     let depsCommand = '';
diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts
index 6bd26c846c6fe..55606f66b2507 100644
--- a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts
+++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts
@@ -113,7 +113,7 @@ export interface BundlingOptions {
    * bundle buddy can consume esbuild's metadata format and generates a treemap visualization
    * of the modules in your bundle and how much space each one takes up.
    * @see https://esbuild.github.io/api/#metafile
-   * @default - false
+   * @default false
    */
   readonly metafile?: boolean
 
@@ -124,7 +124,7 @@ export interface BundlingOptions {
    *
    * This is commonly used to insert comments:
    *
-   * @default -  no comments are passed
+   * @default - no comments are passed
    */
   readonly banner? : string
 
@@ -135,10 +135,23 @@ export interface BundlingOptions {
    *
    * This is commonly used to insert comments
    *
-   * @default -  no comments are passed
+   * @default - no comments are passed
    */
   readonly footer? : string
 
+  /**
+   * The charset to use for esbuild's output.
+   *
+   * By default esbuild's output is ASCII-only. Any non-ASCII characters are escaped
+   * using backslash escape sequences. Using escape sequences makes the generated output
+   * slightly bigger, and also makes it harder to read. If you would like for esbuild to print
+   * the original characters without using escape sequences, use `Charset.UTF8`.
+   *
+   * @see https://esbuild.github.io/api/#charset
+   * @default Charset.ASCII
+   */
+  readonly charset?: Charset;
+
   /**
    * Environment variables defined when bundling runs.
    *
@@ -310,3 +323,22 @@ export enum SourceMapMode {
    */
   BOTH = 'both'
 }
+
+/**
+ * Charset for esbuild's output
+ */
+export enum Charset {
+  /**
+   * ASCII
+   *
+   * Any non-ASCII characters are escaped using backslash escape sequences
+   */
+  ASCII = 'ascii',
+
+  /**
+   * UTF-8
+   *
+   * Keep original characters without using escape sequences
+   */
+  UTF8 = 'utf8'
+}
diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts
index 02b6030ae3e12..f4e974c08fdce 100644
--- a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts
+++ b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts
@@ -6,7 +6,7 @@ import { AssetHashType, DockerImage } from '@aws-cdk/core';
 import { version as delayVersion } from 'delay/package.json';
 import { Bundling } from '../lib/bundling';
 import { PackageInstallation } from '../lib/package-installation';
-import { LogLevel, SourceMapMode } from '../lib/types';
+import { Charset, LogLevel, SourceMapMode } from '../lib/types';
 import * as util from '../lib/util';
 
 
@@ -198,6 +198,7 @@ test('esbuild bundling with esbuild options', () => {
     metafile: true,
     banner: '/* comments */',
     footer: '/* comments */',
+    charset: Charset.UTF8,
     forceDockerBundling: true,
     define: {
       'process.env.KEY': JSON.stringify('VALUE'),
@@ -221,6 +222,7 @@ test('esbuild bundling with esbuild options', () => {
           defineInstructions,
           '--log-level=silent --keep-names --tsconfig=/asset-input/lib/custom-tsconfig.ts',
           '--metafile=/asset-output/index.meta.json --banner:js="/* comments */" --footer:js="/* comments */"',
+          '--charset=utf8',
         ].join(' '),
       ],
     }),

From 54f7f5a7774a00d62808c11aeb057850aefb5216 Mon Sep 17 00:00:00 2001
From: AWS CDK Team 
Date: Fri, 29 Oct 2021 15:50:10 +0000
Subject: [PATCH 091/148] chore(release): 1.130.0

---
 CHANGELOG.md    | 44 ++++++++++++++++++++++++++++++++++++++++++++
 version.v1.json |  2 +-
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 511ed1a25dabd..4c9ab93b5e534 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,50 @@
 
 All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
 
+## [1.130.0](https://github.com/aws/aws-cdk/compare/v1.129.0...v1.130.0) (2021-10-29)
+
+
+### Features
+
+* **amplify:** Add support for custom headers in the App ([#17102](https://github.com/aws/aws-cdk/issues/17102)) ([9f3abd7](https://github.com/aws/aws-cdk/commit/9f3abd745c98a65e7314528f40d08ea2ecbe19a6)), closes [#17084](https://github.com/aws/aws-cdk/issues/17084)
+* **aws-route53-targets:** Support for Elastic Beanstalk environment URLs ([#16305](https://github.com/aws/aws-cdk/issues/16305)) ([bc07cb0](https://github.com/aws/aws-cdk/commit/bc07cb0e383aa64280a9c7f8ac4870d296830cf7))
+* **cli:** deployment progress shows stack name ([#16604](https://github.com/aws/aws-cdk/issues/16604)) ([322cf10](https://github.com/aws/aws-cdk/commit/322cf10ef3257b9d20d898882a14de91110a0033))
+* **cloudfront:** add amplify managed cache policy  ([#16880](https://github.com/aws/aws-cdk/issues/16880)) ([8d0c555](https://github.com/aws/aws-cdk/commit/8d0c555d048c07518c89e69951a1e9f21ba99bd7))
+* **codebuild:** add fromEcrRepository to LinuxGpuBuildImage ([#17170](https://github.com/aws/aws-cdk/issues/17170)) ([7585680](https://github.com/aws/aws-cdk/commit/758568007bf82a97ed6edba3ef4717735b224bf9)), closes [#16500](https://github.com/aws/aws-cdk/issues/16500)
+* **core:** Docker tags can be prefixed ([#17028](https://github.com/aws/aws-cdk/issues/17028)) ([d298696](https://github.com/aws/aws-cdk/commit/d298696a7d8978296a34294484cea80f91ebe880))
+* **core:** subtract Durations ([#16734](https://github.com/aws/aws-cdk/issues/16734)) ([7a333b0](https://github.com/aws/aws-cdk/commit/7a333b018c9bb2430165177d3e65614cf1d66519)), closes [#16535](https://github.com/aws/aws-cdk/issues/16535)
+* **ec2:** add c5ad instances ([#16428](https://github.com/aws/aws-cdk/issues/16428)) ([0318253](https://github.com/aws/aws-cdk/commit/0318253b423bb65ca7e6bf65411df767f2734296))
+* **ec2:** add region parameter for UserData via addS3DownloadCommand  ([#16667](https://github.com/aws/aws-cdk/issues/16667)) ([691d377](https://github.com/aws/aws-cdk/commit/691d3771d32002b3cd4cb1221af92762b749e716)), closes [#8287](https://github.com/aws/aws-cdk/issues/8287)
+* **ec2:** add vpcArn to IVpc and Vpc ([#16666](https://github.com/aws/aws-cdk/issues/16666)) ([7b31376](https://github.com/aws/aws-cdk/commit/7b31376e6349440f7b215d6e11c3dd900d50df34)), closes [#16493](https://github.com/aws/aws-cdk/issues/16493)
+* **ec2:** add X2g instances (for RDS) ([#17081](https://github.com/aws/aws-cdk/issues/17081)) ([443a23e](https://github.com/aws/aws-cdk/commit/443a23e8c1e0de97f6ae05a3e451b0407165a447)), closes [/github.com/aws/aws-cdk/issues/16948#issuecomment-946254267](https://github.com/aws//github.com/aws/aws-cdk/issues/16948/issues/issuecomment-946254267) [#16948](https://github.com/aws/aws-cdk/issues/16948)
+* **ec2:** include p4d instance class ([#17147](https://github.com/aws/aws-cdk/issues/17147)) ([6e13adc](https://github.com/aws/aws-cdk/commit/6e13adc281722a491c0708954d7ed637ad45033b))
+* **ec2:** look up VPC from different regions ([#16728](https://github.com/aws/aws-cdk/issues/16728)) ([f1e244b](https://github.com/aws/aws-cdk/commit/f1e244b331f95253030bae0525775683b5a350c4)), closes [#10208](https://github.com/aws/aws-cdk/issues/10208)
+* **ec2:** VPC endpoint for AWS Xray  ([#16788](https://github.com/aws/aws-cdk/issues/16788)) ([c24af54](https://github.com/aws/aws-cdk/commit/c24af54946d3668afa596dbf2a776b7cf21f8a99)), closes [#16306](https://github.com/aws/aws-cdk/issues/16306)
+* **events:** DLQ support for EventBus target  ([#16383](https://github.com/aws/aws-cdk/issues/16383)) ([dbb3f25](https://github.com/aws/aws-cdk/commit/dbb3f25904403bfc020a081e94270f5c16a7606f)), closes [#15954](https://github.com/aws/aws-cdk/issues/15954)
+* **iot:** add the TopicRule L2 construct ([#16681](https://github.com/aws/aws-cdk/issues/16681)) ([86f85ce](https://github.com/aws/aws-cdk/commit/86f85ce10f78b86133f9dab9851e56d03fb28cc0)), closes [#16602](https://github.com/aws/aws-cdk/issues/16602)
+* **iot:** allow setting Actions of TopicRule ([#17110](https://github.com/aws/aws-cdk/issues/17110)) ([0cabb9f](https://github.com/aws/aws-cdk/commit/0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21)), closes [#16681](https://github.com/aws/aws-cdk/issues/16681) [/github.com/aws/aws-cdk/pull/16681#discussion_r733912215](https://github.com/aws//github.com/aws/aws-cdk/pull/16681/issues/discussion_r733912215)
+* **iot:** create new aws-iot-actions module ([#17112](https://github.com/aws/aws-cdk/issues/17112)) ([06838e6](https://github.com/aws/aws-cdk/commit/06838e66db0c9a48e2aa7da1e7707fda335bb62c)), closes [#16681](https://github.com/aws/aws-cdk/issues/16681) [/github.com/aws/aws-cdk/pull/16681#discussion_r733912215](https://github.com/aws//github.com/aws/aws-cdk/pull/16681/issues/discussion_r733912215)
+* **lambda-nodejs:** esbuild charset option ([#16726](https://github.com/aws/aws-cdk/issues/16726)) ([56033a2](https://github.com/aws/aws-cdk/commit/56033a2a6d4be0444694d9f88260c574a4fa1a1d)), closes [#16668](https://github.com/aws/aws-cdk/issues/16668)
+* **lambda-nodejs:** typescript emitDecoratorMetadata support ([#16543](https://github.com/aws/aws-cdk/issues/16543)) ([55d3c50](https://github.com/aws/aws-cdk/commit/55d3c507707192d7aa5ea4a38ee0d1cb58f07e06)), closes [#13767](https://github.com/aws/aws-cdk/issues/13767)
+* **rds:** support backtrackWindow in DatabaseCluster ([#17160](https://github.com/aws/aws-cdk/issues/17160)) ([fcd17e9](https://github.com/aws/aws-cdk/commit/fcd17e9c9a9e1b83a29c140d558f696c0290bfd7)), closes [#9369](https://github.com/aws/aws-cdk/issues/9369) [#9369](https://github.com/aws/aws-cdk/issues/9369)
+* **route53:** Expose VpcEndpointServiceDomainName domain name as a property  ([#16458](https://github.com/aws/aws-cdk/issues/16458)) ([e063fbd](https://github.com/aws/aws-cdk/commit/e063fbd3a31bdce046b2598e4a429c45d016f055))
+* **sns:** addSubscription returns the created Subscription ([#16785](https://github.com/aws/aws-cdk/issues/16785)) ([62f389e](https://github.com/aws/aws-cdk/commit/62f389ea0522cbaefca5ca17080228031d401ce6))
+* **synthetics:** add syn-nodejs-puppeteer-3.3 runtime ([#17132](https://github.com/aws/aws-cdk/issues/17132)) ([8343bec](https://github.com/aws/aws-cdk/commit/8343beccbee06f453b63387f54768b320fe01339))
+
+
+### Bug Fixes
+
+* **cli:** downgrade bootstrap stack error message needs a hint for new-style synthesis ([#16237](https://github.com/aws/aws-cdk/issues/16237)) ([e55301b](https://github.com/aws/aws-cdk/commit/e55301b635374a87822f78870981a9e06e13d99e))
+* **core:** `DefaultSynthesizer` deployments are never skipped ([#17099](https://github.com/aws/aws-cdk/issues/17099)) ([c74b012](https://github.com/aws/aws-cdk/commit/c74b0127af95f8e86b95a0be2f2c6cb30fab1103)), closes [#16959](https://github.com/aws/aws-cdk/issues/16959)
+* **core:** SecretValue.secretsManager fails for tokenized secret-id  ([#16230](https://github.com/aws/aws-cdk/issues/16230)) ([5831456](https://github.com/aws/aws-cdk/commit/5831456465fa44af96a268de56db0e3a8d3c2ea6)), closes [#16166](https://github.com/aws/aws-cdk/issues/16166)
+* **custom-resources:** invalid service name leads to unhelpful error message ([#16718](https://github.com/aws/aws-cdk/issues/16718)) ([354686b](https://github.com/aws/aws-cdk/commit/354686b189377dd1daae7ba616e8fb62488d9855)), closes [#7312](https://github.com/aws/aws-cdk/issues/7312)
+* **custom-resources:** Role Session Name can exceed maximum size ([#16680](https://github.com/aws/aws-cdk/issues/16680)) ([3617b70](https://github.com/aws/aws-cdk/commit/3617b70527516237955b8415fcfc8b58d3e23b3c))
+* **elasticloadbalancingv2:** always set stickiness ([#17111](https://github.com/aws/aws-cdk/issues/17111)) ([0a23953](https://github.com/aws/aws-cdk/commit/0a23953d92df070736f7d036cc2b24e68de4bf64)), closes [#16620](https://github.com/aws/aws-cdk/issues/16620)
+* **lambda-event-sources:** dynamo batch size cannot be a CfnParameter ([#16540](https://github.com/aws/aws-cdk/issues/16540)) ([56974ac](https://github.com/aws/aws-cdk/commit/56974ac4152bc082470d56dd66e4ef7aad042815)), closes [#16221](https://github.com/aws/aws-cdk/issues/16221)
+* **logs:** Apply tags to log retention Lambda  ([#17029](https://github.com/aws/aws-cdk/issues/17029)) ([a6aaa64](https://github.com/aws/aws-cdk/commit/a6aaa64bf9779b984f20d18881b4f6e510ac091a)), closes [#15032](https://github.com/aws/aws-cdk/issues/15032)
+* **rds:** using both Instance imports & exports for Postgres fails deployment ([#17060](https://github.com/aws/aws-cdk/issues/17060)) ([ab627c6](https://github.com/aws/aws-cdk/commit/ab627c69e9edac82b1fd07d2c9ee1b05f7dc3166)), closes [#16757](https://github.com/aws/aws-cdk/issues/16757)
+* **redshift:** cluster uses key ARN instead of key ID ([#17108](https://github.com/aws/aws-cdk/issues/17108)) ([bdf30c6](https://github.com/aws/aws-cdk/commit/bdf30c696b04b26a8e41548839d5c4cf61d471cc)), closes [#17032](https://github.com/aws/aws-cdk/issues/17032)
+
 ## [1.129.0](https://github.com/aws/aws-cdk/compare/v1.128.0...v1.129.0) (2021-10-21)
 
 
diff --git a/version.v1.json b/version.v1.json
index cdb974a76d7f9..cf3002b8d98b8 100644
--- a/version.v1.json
+++ b/version.v1.json
@@ -1,3 +1,3 @@
 {
-  "version": "1.129.0"
+  "version": "1.130.0"
 }
\ No newline at end of file

From c6a38b72157bc44150ad1516de9fb67fbd4f9664 Mon Sep 17 00:00:00 2001
From: Calvin Combs <66279577+comcalvi@users.noreply.github.com>
Date: Fri, 29 Oct 2021 09:43:23 -0700
Subject: [PATCH 092/148] chore (mergify): change ownership of aws-logs,
 aws-groundsstation, and aws-cloudtrail to @comcalvi

---
 .github/workflows/issue-label-assign.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/issue-label-assign.yml b/.github/workflows/issue-label-assign.yml
index f4d9f3b293c48..3309598c4e5e3 100644
--- a/.github/workflows/issue-label-assign.yml
+++ b/.github/workflows/issue-label-assign.yml
@@ -60,7 +60,7 @@ jobs:
            {"area":"@aws-cdk/aws-cloudformation","keywords":["aws-cloudformation","nestedstack"],"labels":["@aws-cdk/aws-cloudformation"],"assignees":["rix0rrr"]},
            {"area":"@aws-cdk/aws-cloudfront","keywords":["aws-cloudfront","cloud front","cachepolicy","cloudfrontwebdistribution"],"labels":["@aws-cdk/aws-cloudfront"],"assignees":["njlynch"]},
            {"area":"@aws-cdk/aws-cloudfront-origins","keywords":["aws-cloudfront-origins","cloudfront origins"],"labels":["@aws-cdk/aws-cloudfront-origins"],"assignees":["njlynch"]},
-           {"area":"@aws-cdk/aws-cloudtrail","keywords":["aws-cloudtrail","cloud trail","trail"],"labels":["@aws-cdk/aws-cloudtrail"],"assignees":["rix0rrr"]},
+           {"area":"@aws-cdk/aws-cloudtrail","keywords":["aws-cloudtrail","cloud trail","trail"],"labels":["@aws-cdk/aws-cloudtrail"],"assignees":["comcalvi"]},
            {"area":"@aws-cdk/aws-cloudwatch","keywords":["aws-cloudwatch","cloud watch","compositealarm","dashboard"],"labels":["@aws-cdk/aws-cloudwatch"],"assignees":["madeline-k"]},
            {"area":"@aws-cdk/aws-cloudwatch-actions","keywords":["aws-cloudwatch-actions","cloudwatch actions","applicationscalingaction","autoscalingaction","ec2action","snsaction"],"labels":["@aws-cdk/aws-cloudwatch-actions"],"assignees":["madeline-k"]},
            {"area":"@aws-cdk/aws-codeartifact","keywords":["aws-codeartifact","code-artifact"],"labels":["@aws-cdk/aws-codeartifact"],"assignees":["njlynch"]},
@@ -120,7 +120,7 @@ jobs:
            {"area":"@aws-cdk/aws-glue","keywords":["aws-glue","glue"],"labels":["@aws-cdk/aws-glue"],"assignees":["kaizen3031593"]},
            {"area":"@aws-cdk/aws-greengrass","keywords":["aws-greengrass","green-grass"],"labels":["@aws-cdk/aws-greengrass"],"assignees":["skinny85"]},
            {"area":"@aws-cdk/aws-greengrassv2","keywords":["(aws-greengrassv2)","(greengrassv2)"],"labels":["@aws-cdk/aws-greengrassv2"],"assignees":["skinny85"]},
-           {"area":"@aws-cdk/aws-groundstation","keywords":["(aws-groundstation)","(groundstation)"],"labels":["@aws-cdk/aws-groundstation"],"assignees":["rix0rrr"]},
+           {"area":"@aws-cdk/aws-groundstation","keywords":["(aws-groundstation)","(groundstation)"],"labels":["@aws-cdk/aws-groundstation"],"assignees":["comcalvi"]},
            {"area":"@aws-cdk/aws-guardduty","keywords":["aws-guardduty","guard-duty"],"labels":["@aws-cdk/aws-guardduty"],"assignees":["rix0rrr"]},
            {"area":"@aws-cdk/aws-iam","keywords":["aws-iam","iam","managedpolicy","policy","role"],"labels":["@aws-cdk/aws-iam"],"assignees":["rix0rrr"]},
            {"area":"@aws-cdk/aws-imagebuilder","keywords":["aws-imagebuilder","imagebuilder"],"labels":["@aws-cdk/aws-imagebuilder"],"assignees":["skinny85"]},
@@ -148,7 +148,7 @@ jobs:
            {"area":"@aws-cdk/aws-lambda-nodejs","keywords":["nodejsfunction","aws-lambda-nodejs","lambda-nodejs"],"labels":["@aws-cdk/aws-lambda-nodejs"],"assignees":["nija-at"]},
            {"area":"@aws-cdk/aws-lambda-python","keywords":["aws-lambda-python","lambda-python","pythonfunction"],"labels":["@aws-cdk/aws-lambda-python"],"assignees":["nija-at"]},
            {"area":"@aws-cdk/aws-licensemanager","keywords":["(aws-licensemanager)","(licensemanager)"],"labels":["@aws-cdk/aws-licensemanager"],"assignees":["njlynch"]},
-           {"area":"@aws-cdk/aws-logs","keywords":["loggroup","aws-logs","logs","logretention"],"labels":["@aws-cdk/aws-logs"],"assignees":["rix0rrr"]},
+           {"area":"@aws-cdk/aws-logs","keywords":["loggroup","aws-logs","logs","logretention"],"labels":["@aws-cdk/aws-logs"],"assignees":["comcalvi"]},
            {"area":"@aws-cdk/aws-logs-destinations","keywords":["aws-logs-destinations","lambdadestination","kinesisdestination","logs-destinations"],"labels":["@aws-cdk/aws-logs-destinations"],"assignees":["rix0rrr"]},
            {"area":"@aws-cdk/aws-lookoutmetrics","keywords":["(aws-lookoutmetrics)","(lookoutmetrics)"],"labels":["@aws-cdk/aws-lookoutmetrics"],"assignees":["comcalvi"]},
            {"area":"@aws-cdk/aws-lookoutvision","keywords":["(aws-lookoutvision)","(lookoutvision)"],"labels":["@aws-cdk/aws-lookoutvision"],"assignees":["comcalvi"]},

From e9a461d6dcbad933fcb9d671a8c5b5ad8f5ece8d Mon Sep 17 00:00:00 2001
From: nom3ad <19239479+nom3ad@users.noreply.github.com>
Date: Mon, 1 Nov 2021 21:22:58 +0530
Subject: [PATCH 093/148] feat(logs): add support for cloudwatch logs resource
 policy  (#17015)

CloudFormation now supports [Cloudwatch logs Resource policies](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-resourcepolicy.html)
This PR adds L2 support for it.

And now its possible to grant access to service principals as follows. Previously this was throwing an error - see #5343

```ts
const eventsTargetLogs = new logs.LogGroup(this, 'EventsTargetLogGroup');
eventsTargetLogs.grantWrite(new iam.ServicePrincipal('events.amazonaws.com')).assertSuccess();
```

In future, following custom resource implementation of `LogGroupResourcePolicy` could be replaced.

https://github.com/aws/aws-cdk/blob/83b8df8c390a27e10bf362f49babfb24ee425506/packages/@aws-cdk/aws-elasticsearch/lib/log-group-resource-policy.ts#L25
https://github.com/aws/aws-cdk/blob/a872e672f8990fc3879413e5d797533d3916e1fd/packages/@aws-cdk/aws-events-targets/lib/log-group-resource-policy.ts#L26
https://github.com/aws/aws-cdk/blob/a872e672f8990fc3879413e5d797533d3916e1fd/packages/@aws-cdk/aws-events-targets/lib/log-group-resource-policy.ts#L26

closes #5343

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-logs/README.md          | 40 ++++++++++++++-
 packages/@aws-cdk/aws-logs/lib/log-group.ts   | 25 +++++++--
 packages/@aws-cdk/aws-logs/lib/policy.ts      | 47 +++++++++++++++++
 .../@aws-cdk/aws-logs/test/loggroup.test.ts   | 51 +++++++++++++++++++
 4 files changed, 157 insertions(+), 6 deletions(-)
 create mode 100644 packages/@aws-cdk/aws-logs/lib/policy.ts

diff --git a/packages/@aws-cdk/aws-logs/README.md b/packages/@aws-cdk/aws-logs/README.md
index 1fcd323ca621c..631bc382365e0 100644
--- a/packages/@aws-cdk/aws-logs/README.md
+++ b/packages/@aws-cdk/aws-logs/README.md
@@ -48,6 +48,44 @@ By default, the log group will be created in the same region as the stack. The `
 log groups in other regions. This is typically useful when controlling retention for log groups auto-created by global services that
 publish their log group to a specific region, such as AWS Chatbot creating a log group in `us-east-1`.
 
+## Resource Policy
+
+CloudWatch Resource Policies allow other AWS services or IAM Principals to put log events into the log groups.
+A resource policy is automatically created when `addToResourcePolicy` is called on the LogGroup for the first time.
+
+`ResourcePolicy` can also be created manually.
+
+```ts
+const logGroup = new LogGroup(this, 'LogGroup');
+const resourcePolicy = new ResourcePolicy(this, 'ResourcePolicy');
+resourcePolicy.document.addStatements(new iam.PolicyStatement({
+    actions: ['logs:CreateLogStream', 'logs:PutLogEvents'],
+    principals: [new iam.ServicePrincipal('es.amazonaws.com')],
+    resources: [logGroup.logGroupArn],
+}));
+```
+
+Or more conveniently, write permissions to the log group can be granted as follows which gives same result as in the above example.
+
+```ts
+const logGroup = new LogGroup(this, 'LogGroup');
+logGroup.grantWrite(iam.ServicePrincipal('es.amazonaws.com'));
+```
+
+Optionally name and policy statements can also be passed on `ResourcePolicy` construction.
+
+```ts
+const policyStatement = new new iam.PolicyStatement({
+    resources: ["*"],
+    actions: ['logs:PutLogEvents'],
+    principals: [new iam.ArnPrincipal('arn:aws:iam::123456789012:user/user-name')],
+});
+const resourcePolicy = new ResourcePolicy(this, 'ResourcePolicy', {
+    policyName: 'myResourcePolicy',
+    policyStatements: [policyStatement],
+});
+```
+
 ## Encrypting Log Groups
 
 By default, log group data is always encrypted in CloudWatch Logs. You have the
@@ -182,7 +220,6 @@ line.
   all of the terms in any of the groups (specified as arrays) matches. This is
   an OR match.
 
-
 Examples:
 
 ```ts
@@ -231,7 +268,6 @@ and then descending into it, such as `$.field` or `$.list[0].field`.
   given JSON patterns match. This makes an OR combination of the given
   patterns.
 
-
 Example:
 
 ```ts
diff --git a/packages/@aws-cdk/aws-logs/lib/log-group.ts b/packages/@aws-cdk/aws-logs/lib/log-group.ts
index 4c74dbf02f3ee..c701f4b5e4c9f 100644
--- a/packages/@aws-cdk/aws-logs/lib/log-group.ts
+++ b/packages/@aws-cdk/aws-logs/lib/log-group.ts
@@ -1,15 +1,16 @@
 import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
 import * as iam from '@aws-cdk/aws-iam';
 import * as kms from '@aws-cdk/aws-kms';
-import { IResource, RemovalPolicy, Resource, Stack, Token } from '@aws-cdk/core';
+import { RemovalPolicy, Resource, Stack, Token } from '@aws-cdk/core';
 import { Construct } from 'constructs';
 import { LogStream } from './log-stream';
 import { CfnLogGroup } from './logs.generated';
 import { MetricFilter } from './metric-filter';
 import { FilterPattern, IFilterPattern } from './pattern';
+import { ResourcePolicy } from './policy';
 import { ILogSubscriptionDestination, SubscriptionFilter } from './subscription-filter';
 
-export interface ILogGroup extends IResource {
+export interface ILogGroup extends iam.IResourceWithPolicy {
   /**
    * The ARN of this log group, with ':*' appended
    *
@@ -93,6 +94,9 @@ abstract class LogGroupBase extends Resource implements ILogGroup {
    */
   public abstract readonly logGroupName: string;
 
+
+  private policy?: ResourcePolicy;
+
   /**
    * Create a new Log Stream for this Log Group
    *
@@ -169,13 +173,13 @@ abstract class LogGroupBase extends Resource implements ILogGroup {
    * Give the indicated permissions on this log group and all streams
    */
   public grant(grantee: iam.IGrantable, ...actions: string[]) {
-    return iam.Grant.addToPrincipal({
+    return iam.Grant.addToPrincipalOrResource({
       grantee,
       actions,
       // A LogGroup ARN out of CloudFormation already includes a ':*' at the end to include the log streams under the group.
       // See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-loggroup.html#w2ab1c21c10c63c43c11
       resourceArns: [this.logGroupArn],
-      scope: this,
+      resource: this,
     });
   }
 
@@ -186,6 +190,19 @@ abstract class LogGroupBase extends Resource implements ILogGroup {
   public logGroupPhysicalName(): string {
     return this.physicalName;
   }
+
+  /**
+   * Adds a statement to the resource policy associated with this log group.
+   * A resource policy will be automatically created upon the first call to `addToResourcePolicy`.
+   * @param statement The policy statement to add
+   */
+  public addToResourcePolicy(statement: iam.PolicyStatement): iam.AddToResourcePolicyResult {
+    if (!this.policy) {
+      this.policy = new ResourcePolicy(this, 'Policy');
+    }
+    this.policy.document.addStatements(statement);
+    return { statementAdded: true, policyDependable: this.policy };
+  }
 }
 
 /**
diff --git a/packages/@aws-cdk/aws-logs/lib/policy.ts b/packages/@aws-cdk/aws-logs/lib/policy.ts
new file mode 100644
index 0000000000000..974f517d48b25
--- /dev/null
+++ b/packages/@aws-cdk/aws-logs/lib/policy.ts
@@ -0,0 +1,47 @@
+import { PolicyDocument, PolicyStatement } from '@aws-cdk/aws-iam';
+import { Resource, Lazy, Names } from '@aws-cdk/core';
+import { Construct } from 'constructs';
+import { CfnResourcePolicy } from './logs.generated';
+
+/**
+ * Properties to define Cloudwatch log group resource policy
+ */
+export interface ResourcePolicyProps {
+  /**
+   * Name of the log group resource policy
+   * @default - Uses a unique id based on the construct path
+   */
+  readonly policyName?: string;
+
+  /**
+   * Initial statements to add to the resource policy
+   *
+   * @default - No statements
+   */
+  readonly policyStatements?: PolicyStatement[];
+}
+
+/**
+ * Creates Cloudwatch log group resource policies
+ */
+export class ResourcePolicy extends Resource {
+  /**
+   * The IAM policy document for this resource policy.
+   */
+  public readonly document = new PolicyDocument();
+
+  constructor(scope: Construct, id: string, props?: ResourcePolicyProps) {
+    super(scope, id);
+    new CfnResourcePolicy(this, 'Resource', {
+      policyName: Lazy.string({
+        produce: () => props?.policyName ?? Names.uniqueId(this),
+      }),
+      policyDocument: Lazy.string({
+        produce: () => JSON.stringify(this.document),
+      }),
+    });
+    if (props?.policyStatements) {
+      this.document.addStatements(...props.policyStatements);
+    }
+  }
+}
diff --git a/packages/@aws-cdk/aws-logs/test/loggroup.test.ts b/packages/@aws-cdk/aws-logs/test/loggroup.test.ts
index 72b3c390a2f96..d7fa5cb600b76 100644
--- a/packages/@aws-cdk/aws-logs/test/loggroup.test.ts
+++ b/packages/@aws-cdk/aws-logs/test/loggroup.test.ts
@@ -335,6 +335,57 @@ describe('log group', () => {
 
   });
 
+  test('grant to service principal', () => {
+    // GIVEN
+    const stack = new Stack();
+    const lg = new LogGroup(stack, 'LogGroup');
+    const sp = new iam.ServicePrincipal('es.amazonaws.com');
+
+    // WHEN
+    lg.grantWrite(sp);
+
+    // THEN
+    expect(stack).toHaveResource('AWS::Logs::ResourcePolicy', {
+      PolicyDocument: {
+        'Fn::Join': [
+          '',
+          [
+            '{"Statement":[{"Action":["logs:CreateLogStream","logs:PutLogEvents"],"Effect":"Allow","Principal":{"Service":"es.amazonaws.com"},"Resource":"',
+            {
+              'Fn::GetAtt': [
+                'LogGroupF5B46931',
+                'Arn',
+              ],
+            },
+            '"}],"Version":"2012-10-17"}',
+          ],
+        ],
+      },
+      PolicyName: 'LogGroupPolicy643B329C',
+    });
+
+  });
+
+
+  test('can add a policy to the log group', () => {
+    // GIVEN
+    const stack = new Stack();
+    const lg = new LogGroup(stack, 'LogGroup');
+
+    // WHEN
+    lg.addToResourcePolicy(new iam.PolicyStatement({
+      resources: ['*'],
+      actions: ['logs:PutLogEvents'],
+      principals: [new iam.ArnPrincipal('arn:aws:iam::123456789012:user/user-name')],
+    }));
+
+    // THEN
+    expect(stack).toHaveResource('AWS::Logs::ResourcePolicy', {
+      PolicyDocument: '{"Statement":[{"Action":"logs:PutLogEvents","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:user/user-name"},"Resource":"*"}],"Version":"2012-10-17"}',
+      PolicyName: 'LogGroupPolicy643B329C',
+    });
+  });
+
   test('correctly returns physical name of the log group', () => {
     // GIVEN
     const stack = new Stack();

From a9aae097daad475dd57bbf4842956327a6d5a220 Mon Sep 17 00:00:00 2001
From: Tatsuya Yamamoto 
Date: Tue, 2 Nov 2021 01:47:28 +0900
Subject: [PATCH 094/148] feat(iot): allow setting `description` and `enabled`
 of TopicRule (#17225)

I'm trying to implement aws-iot L2 Constructs.

This PR is one of steps after following PR:
- https://github.com/aws/aws-cdk/pull/16681#issuecomment-942233029

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-iot/README.md           | 11 +++++++
 packages/@aws-cdk/aws-iot/lib/topic-rule.ts   | 16 ++++++++++
 .../@aws-cdk/aws-iot/test/topic-rule.test.ts  | 30 +++++++++++++++++++
 3 files changed, 57 insertions(+)

diff --git a/packages/@aws-cdk/aws-iot/README.md b/packages/@aws-cdk/aws-iot/README.md
index 6a9640629891a..42ab651f26f81 100644
--- a/packages/@aws-cdk/aws-iot/README.md
+++ b/packages/@aws-cdk/aws-iot/README.md
@@ -59,6 +59,8 @@ const func = new lambda.Function(this, 'MyFunction', {
 });
 
 new iot.TopicRule(this, 'TopicRule', {
+  topicRuleName: 'MyTopicRule', // optional
+  description: 'invokes the lambda finction', // optional
   sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, timestamp() as timestamp FROM 'device/+/data'"),
   actions: [new actions.LambdaFunctionAction(func)],
 });
@@ -72,3 +74,12 @@ const topicRule = new iot.TopicRule(this, 'TopicRule', {
 });
 topicRule.addAction(new actions.LambdaFunctionAction(func))
 ```
+
+If you wanna make the topic rule disable, add property `enabled: false` as following:
+
+```ts
+new iot.TopicRule(this, 'TopicRule', {
+  sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, timestamp() as timestamp FROM 'device/+/data'"),
+  enabled: false,
+});
+```
diff --git a/packages/@aws-cdk/aws-iot/lib/topic-rule.ts b/packages/@aws-cdk/aws-iot/lib/topic-rule.ts
index a8cd21fe2bd96..8860a611e4af3 100644
--- a/packages/@aws-cdk/aws-iot/lib/topic-rule.ts
+++ b/packages/@aws-cdk/aws-iot/lib/topic-rule.ts
@@ -41,6 +41,20 @@ export interface TopicRuleProps {
    */
   readonly actions?: IAction[];
 
+  /**
+   * A textual description of the topic rule.
+   *
+   * @default None
+   */
+  readonly description?: string;
+
+  /**
+   * Specifies whether the rule is enabled.
+   *
+   * @default true
+   */
+  readonly enabled?: boolean
+
   /**
    * A simplified SQL syntax to filter messages received on an MQTT topic and push the data elsewhere.
    *
@@ -102,6 +116,8 @@ export class TopicRule extends Resource implements ITopicRule {
       topicRulePayload: {
         actions: Lazy.any({ produce: () => this.actions }),
         awsIotSqlVersion: sqlConfig.awsIotSqlVersion,
+        description: props.description,
+        ruleDisabled: props.enabled === undefined ? undefined : !props.enabled,
         sql: sqlConfig.sql,
       },
     });
diff --git a/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts b/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts
index 66246e860dddb..6e4a49c234e60 100644
--- a/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts
+++ b/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts
@@ -71,6 +71,36 @@ test('can set physical name', () => {
   });
 });
 
+test('can set description', () => {
+  const stack = new cdk.Stack();
+
+  new iot.TopicRule(stack, 'MyTopicRule', {
+    description: 'test-description',
+    sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"),
+  });
+
+  Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
+    TopicRulePayload: {
+      Description: 'test-description',
+    },
+  });
+});
+
+test('can set ruleDisabled', () => {
+  const stack = new cdk.Stack();
+
+  new iot.TopicRule(stack, 'MyTopicRule', {
+    enabled: false,
+    sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"),
+  });
+
+  Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
+    TopicRulePayload: {
+      RuleDisabled: true,
+    },
+  });
+});
+
 test.each([
   ['fromStringAsVer20151008', iot.IotSql.fromStringAsVer20151008, '2015-10-08'],
   ['fromStringAsVer20160323', iot.IotSql.fromStringAsVer20160323, '2016-03-23'],

From e26f5befc2adedeb524fd263424c7920989b2288 Mon Sep 17 00:00:00 2001
From: Julian Michel 
Date: Mon, 1 Nov 2021 18:42:51 +0100
Subject: [PATCH 095/148] feat(certificatemanager): requesting private
 certificates issued by Private Certificate Authority  (#16315)

Support requesting private certificates issued by Private Certificate Authority.

Similar to the existing construct named `Certificate`, a new construct `PrivateCertificate` was introduced. There are two main differences between them. `PrivateCertificate` has an additional property `certificateAuthority` to specify the Private certificate authority (CA) that will be used to issue the certificate. The validation options are removed because no validation is necessary for private certificates.

Closes #10076.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../@aws-cdk/aws-certificatemanager/README.md |  15 +++
 .../aws-certificatemanager/lib/index.ts       |   1 +
 .../lib/private-certificate.ts                |  66 ++++++++++++
 .../aws-certificatemanager/package.json       |   5 +-
 .../test/private-certificate.test.ts          | 102 ++++++++++++++++++
 5 files changed, 188 insertions(+), 1 deletion(-)
 create mode 100644 packages/@aws-cdk/aws-certificatemanager/lib/private-certificate.ts
 create mode 100644 packages/@aws-cdk/aws-certificatemanager/test/private-certificate.test.ts

diff --git a/packages/@aws-cdk/aws-certificatemanager/README.md b/packages/@aws-cdk/aws-certificatemanager/README.md
index 7068591d9c076..331d40ad27276 100644
--- a/packages/@aws-cdk/aws-certificatemanager/README.md
+++ b/packages/@aws-cdk/aws-certificatemanager/README.md
@@ -113,6 +113,21 @@ new acm.DnsValidatedCertificate(this, 'CrossRegionCertificate', {
 });
 ```
 
+## Requesting private certificates
+
+AWS Certificate Manager can create [private certificates](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-private.html) issued by [Private Certificate Authority (PCA)](https://docs.aws.amazon.com/acm-pca/latest/userguide/PcaWelcome.html). Validation of private certificates is not necessary.
+
+```ts
+import * as acmpca from '@aws-cdk/aws-acmpca';
+
+new acm.PrivateCertificate(stack, 'PrivateCertificate', {
+  domainName: 'test.example.com',
+  subjectAlternativeNames: ['cool.example.com', 'test.example.net'], // optional
+  certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA',
+    'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'),
+});
+```
+
 ## Importing
 
 If you want to import an existing certificate, you can do so from its ARN:
diff --git a/packages/@aws-cdk/aws-certificatemanager/lib/index.ts b/packages/@aws-cdk/aws-certificatemanager/lib/index.ts
index ee15ab71b8d4b..60be9ebed1c5c 100644
--- a/packages/@aws-cdk/aws-certificatemanager/lib/index.ts
+++ b/packages/@aws-cdk/aws-certificatemanager/lib/index.ts
@@ -1,5 +1,6 @@
 export * from './certificate';
 export * from './dns-validated-certificate';
+export * from './private-certificate';
 export * from './util';
 
 // AWS::CertificateManager CloudFormation Resources:
diff --git a/packages/@aws-cdk/aws-certificatemanager/lib/private-certificate.ts b/packages/@aws-cdk/aws-certificatemanager/lib/private-certificate.ts
new file mode 100644
index 0000000000000..366b3ea623ac6
--- /dev/null
+++ b/packages/@aws-cdk/aws-certificatemanager/lib/private-certificate.ts
@@ -0,0 +1,66 @@
+import * as acmpca from '@aws-cdk/aws-acmpca';
+import { Construct } from 'constructs';
+import { ICertificate } from './certificate';
+import { CertificateBase } from './certificate-base';
+import { CfnCertificate } from './certificatemanager.generated';
+
+/**
+ * Properties for your private certificate
+ */
+export interface PrivateCertificateProps {
+  /**
+   * Fully-qualified domain name to request a private certificate for.
+   *
+   * May contain wildcards, such as ``*.domain.com``.
+   */
+  readonly domainName: string;
+
+  /**
+   * Alternative domain names on your private certificate.
+   *
+   * Use this to register alternative domain names that represent the same site.
+   *
+   * @default - No additional FQDNs will be included as alternative domain names.
+   */
+  readonly subjectAlternativeNames?: string[];
+
+  /**
+   * Private certificate authority (CA) that will be used to issue the certificate.
+   */
+  readonly certificateAuthority: acmpca.ICertificateAuthority;
+}
+
+/**
+ * A private certificate managed by AWS Certificate Manager
+ *
+ * @resource AWS::CertificateManager::Certificate
+ */
+export class PrivateCertificate extends CertificateBase implements ICertificate {
+  /**
+   * Import a certificate
+   */
+  public static fromCertificateArn(scope: Construct, id: string, certificateArn: string): ICertificate {
+    class Import extends CertificateBase {
+      public readonly certificateArn = certificateArn;
+    }
+
+    return new Import(scope, id);
+  }
+
+  /**
+   * The certificate's ARN
+   */
+  public readonly certificateArn: string;
+
+  constructor(scope: Construct, id: string, props: PrivateCertificateProps) {
+    super(scope, id);
+
+    const cert = new CfnCertificate(this, 'Resource', {
+      domainName: props.domainName,
+      subjectAlternativeNames: props.subjectAlternativeNames,
+      certificateAuthorityArn: props.certificateAuthority.certificateAuthorityArn,
+    });
+
+    this.certificateArn = cert.ref;
+  }
+}
diff --git a/packages/@aws-cdk/aws-certificatemanager/package.json b/packages/@aws-cdk/aws-certificatemanager/package.json
index 990c09fc3aa55..dae2a8a3a24dc 100644
--- a/packages/@aws-cdk/aws-certificatemanager/package.json
+++ b/packages/@aws-cdk/aws-certificatemanager/package.json
@@ -79,6 +79,7 @@
     "@types/jest": "^26.0.24"
   },
   "dependencies": {
+    "@aws-cdk/aws-acmpca": "0.0.0",
     "@aws-cdk/aws-cloudwatch": "0.0.0",
     "@aws-cdk/aws-iam": "0.0.0",
     "@aws-cdk/aws-lambda": "0.0.0",
@@ -88,6 +89,7 @@
   },
   "homepage": "https://github.com/aws/aws-cdk",
   "peerDependencies": {
+    "@aws-cdk/aws-acmpca": "0.0.0",
     "@aws-cdk/aws-cloudwatch": "0.0.0",
     "@aws-cdk/aws-iam": "0.0.0",
     "@aws-cdk/aws-lambda": "0.0.0",
@@ -101,7 +103,8 @@
   "awslint": {
     "exclude": [
       "props-physical-name:@aws-cdk/aws-certificatemanager.CertificateProps",
-      "props-physical-name:@aws-cdk/aws-certificatemanager.DnsValidatedCertificateProps"
+      "props-physical-name:@aws-cdk/aws-certificatemanager.DnsValidatedCertificateProps",
+      "props-physical-name:@aws-cdk/aws-certificatemanager.PrivateCertificateProps"
     ]
   },
   "stability": "stable",
diff --git a/packages/@aws-cdk/aws-certificatemanager/test/private-certificate.test.ts b/packages/@aws-cdk/aws-certificatemanager/test/private-certificate.test.ts
new file mode 100644
index 0000000000000..e43a4ca005691
--- /dev/null
+++ b/packages/@aws-cdk/aws-certificatemanager/test/private-certificate.test.ts
@@ -0,0 +1,102 @@
+import '@aws-cdk/assert-internal/jest';
+import * as acmpca from '@aws-cdk/aws-acmpca';
+import { Duration, Lazy, Stack } from '@aws-cdk/core';
+import { PrivateCertificate } from '../lib';
+
+test('private certificate authority', () => {
+  const stack = new Stack();
+
+  new PrivateCertificate(stack, 'Certificate', {
+    domainName: 'test.example.com',
+    certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA',
+      'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'),
+  });
+
+  expect(stack).toHaveResource('AWS::CertificateManager::Certificate', {
+    DomainName: 'test.example.com',
+    CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77',
+  });
+});
+
+test('private certificate authority with subjectAlternativeNames', () => {
+  const stack = new Stack();
+
+  new PrivateCertificate(stack, 'Certificate', {
+    domainName: 'test.example.com',
+    subjectAlternativeNames: ['extra.example.com'],
+    certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA',
+      'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'),
+  });
+
+  expect(stack).toHaveResource('AWS::CertificateManager::Certificate', {
+    DomainName: 'test.example.com',
+    SubjectAlternativeNames: ['extra.example.com'],
+    CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77',
+  });
+});
+
+test('private certificate authority with multiple subjectAlternativeNames', () => {
+  const stack = new Stack();
+
+  new PrivateCertificate(stack, 'Certificate', {
+    domainName: 'test.example.com',
+    subjectAlternativeNames: ['*.test.example.com', '*.foo.test.example.com', 'bar.test.example.com'],
+    certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA',
+      'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'),
+  });
+
+  expect(stack).toHaveResource('AWS::CertificateManager::Certificate', {
+    DomainName: 'test.example.com',
+    SubjectAlternativeNames: ['*.test.example.com', '*.foo.test.example.com', 'bar.test.example.com'],
+    CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77',
+  });
+});
+
+test('private certificate authority with tokens', () => {
+  const stack = new Stack();
+
+  const certificateAuthority = Lazy.string({
+    produce: () => 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77',
+  });
+
+  const domainName = Lazy.string({
+    produce: () => 'test.example.com',
+  });
+
+  const domainNameAlternative = Lazy.string({
+    produce: () => 'extra.example.com',
+  });
+
+  new PrivateCertificate(stack, 'Certificate', {
+    domainName,
+    subjectAlternativeNames: [domainNameAlternative],
+    certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA', certificateAuthority),
+  });
+
+  expect(stack).toHaveResource('AWS::CertificateManager::Certificate', {
+    DomainName: 'test.example.com',
+    SubjectAlternativeNames: ['extra.example.com'],
+    CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77',
+  });
+});
+
+test('metricDaysToExpiry', () => {
+  const stack = new Stack();
+
+  const certificate = new PrivateCertificate(stack, 'Certificate', {
+    domainName: 'test.example.com',
+    certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA',
+      'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'),
+  });
+
+  expect(stack.resolve(certificate.metricDaysToExpiry().toMetricConfig())).toEqual({
+    metricStat: {
+      dimensions: [{ name: 'CertificateArn', value: stack.resolve(certificate.certificateArn) }],
+      metricName: 'DaysToExpiry',
+      namespace: 'AWS/CertificateManager',
+      period: Duration.days(1),
+      statistic: 'Minimum',
+    },
+    renderingProperties: expect.anything(),
+  });
+});

From 19b38f5fd2b054f234d4c0b0debe7caa432f561c Mon Sep 17 00:00:00 2001
From: Julian Michel 
Date: Mon, 1 Nov 2021 19:37:58 +0100
Subject: [PATCH 096/148] chore(rds): add Aurora Postgres ver 13.4, 12.8,
 11.13, 10.18 and Mysql ver 8.0.26 (#17247)

Add new RDS versions:

**AuroraPostgresEngineVersion 13.4, 12.8, 11.13, and 10.18**
Announcement: https://aws.amazon.com/about-aws/whats-new/2021/10/amazon-aurora-postgresql-supports-releases/
s3Export and s3Import are supported, see `aws rds describe-db-engine-versions --region us-east-1 --engine aurora-postgresql --engine-version xxx`.

**MysqlEngineVersion 8.0.26**
Announcement: https://aws.amazon.com/about-aws/whats-new/2021/10/amazon-rds-mysql-version-8-0-26-global-transaction-identifiers-gitds-delayed-replication/

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-rds/lib/cluster-engine.ts  | 8 ++++++++
 packages/@aws-cdk/aws-rds/lib/instance-engine.ts | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/packages/@aws-cdk/aws-rds/lib/cluster-engine.ts b/packages/@aws-cdk/aws-rds/lib/cluster-engine.ts
index 606fddd75edbf..cde235257ff8e 100644
--- a/packages/@aws-cdk/aws-rds/lib/cluster-engine.ts
+++ b/packages/@aws-cdk/aws-rds/lib/cluster-engine.ts
@@ -451,6 +451,8 @@ export class AuroraPostgresEngineVersion {
   public static readonly VER_10_14 = AuroraPostgresEngineVersion.of('10.14', '10', { s3Import: true, s3Export: true });
   /** Version "10.16". */
   public static readonly VER_10_16 = AuroraPostgresEngineVersion.of('10.16', '10', { s3Import: true, s3Export: true });
+  /** Version "10.18". */
+  public static readonly VER_10_18 = AuroraPostgresEngineVersion.of('10.18', '10', { s3Import: true, s3Export: true });
   /** Version "11.4". */
   public static readonly VER_11_4 = AuroraPostgresEngineVersion.of('11.4', '11', { s3Import: true });
   /** Version "11.6". */
@@ -463,12 +465,18 @@ export class AuroraPostgresEngineVersion {
   public static readonly VER_11_9 = AuroraPostgresEngineVersion.of('11.9', '11', { s3Import: true, s3Export: true });
   /** Version "11.11". */
   public static readonly VER_11_11 = AuroraPostgresEngineVersion.of('11.11', '11', { s3Import: true, s3Export: true });
+  /** Version "11.13". */
+  public static readonly VER_11_13 = AuroraPostgresEngineVersion.of('11.13', '11', { s3Import: true, s3Export: true });
   /** Version "12.4". */
   public static readonly VER_12_4 = AuroraPostgresEngineVersion.of('12.4', '12', { s3Import: true, s3Export: true });
   /** Version "12.6". */
   public static readonly VER_12_6 = AuroraPostgresEngineVersion.of('12.6', '12', { s3Import: true, s3Export: true });
+  /** Version "12.8". */
+  public static readonly VER_12_8 = AuroraPostgresEngineVersion.of('12.8', '12', { s3Import: true, s3Export: true });
   /** Version "13.3". */
   public static readonly VER_13_3 = AuroraPostgresEngineVersion.of('13.3', '13', { s3Import: true, s3Export: true });
+  /** Version "13.4". */
+  public static readonly VER_13_4 = AuroraPostgresEngineVersion.of('13.4', '13', { s3Import: true, s3Export: true });
 
   /**
    * Create a new AuroraPostgresEngineVersion with an arbitrary version.
diff --git a/packages/@aws-cdk/aws-rds/lib/instance-engine.ts b/packages/@aws-cdk/aws-rds/lib/instance-engine.ts
index dfea03877a0d2..05d045e56c8f3 100644
--- a/packages/@aws-cdk/aws-rds/lib/instance-engine.ts
+++ b/packages/@aws-cdk/aws-rds/lib/instance-engine.ts
@@ -497,6 +497,8 @@ export class MysqlEngineVersion {
   public static readonly VER_8_0_23 = MysqlEngineVersion.of('8.0.23', '8.0');
   /** Version "8.0.25". */
   public static readonly VER_8_0_25 = MysqlEngineVersion.of('8.0.25', '8.0');
+  /** Version "8.0.26". */
+  public static readonly VER_8_0_26 = MysqlEngineVersion.of('8.0.26', '8.0');
 
   /**
    * Create a new MysqlEngineVersion with an arbitrary version.

From 73eb185ab7c11b50511c671e02cf2039c297bd61 Mon Sep 17 00:00:00 2001
From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com>
Date: Mon, 1 Nov 2021 15:31:49 -0400
Subject: [PATCH 097/148] docs(rds): make examples compile (#17146)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-rds/README.md           | 121 +++++++++++-------
 .../aws-rds/rosetta/default.ts-fixture        |  18 +++
 2 files changed, 91 insertions(+), 48 deletions(-)
 create mode 100644 packages/@aws-cdk/aws-rds/rosetta/default.ts-fixture

diff --git a/packages/@aws-cdk/aws-rds/README.md b/packages/@aws-cdk/aws-rds/README.md
index cad785735dfb6..42283697f6181 100644
--- a/packages/@aws-cdk/aws-rds/README.md
+++ b/packages/@aws-cdk/aws-rds/README.md
@@ -12,7 +12,7 @@
 
 
 
-```ts
+```ts nofixture
 import * as rds from '@aws-cdk/aws-rds';
 ```
 
@@ -23,6 +23,7 @@ always launch a database in a VPC. Use the `vpcSubnets` attribute to control whe
 your instances will be launched privately or publicly:
 
 ```ts
+declare const vpc: ec2.Vpc;
 const cluster = new rds.DatabaseCluster(this, 'Database', {
   engine: rds.DatabaseClusterEngine.auroraMysql({ version: rds.AuroraMysqlEngineVersion.VER_2_08_1 }),
   credentials: rds.Credentials.fromGeneratedSecret('clusteradmin'), // Optional - will default to 'admin' username and generated password
@@ -52,7 +53,8 @@ Your cluster will be empty by default. To add a default database upon constructi
 Use `DatabaseClusterFromSnapshot` to create a cluster from a snapshot:
 
 ```ts
-new rds.DatabaseClusterFromSnapshot(stack, 'Database', {
+declare const vpc: ec2.Vpc;
+new rds.DatabaseClusterFromSnapshot(this, 'Database', {
   engine: rds.DatabaseClusterEngine.aurora({ version: rds.AuroraEngineVersion.VER_1_22_2 }),
   instanceProps: {
     vpc,
@@ -68,6 +70,7 @@ always launch a database in a VPC. Use the `vpcSubnets` attribute to control whe
 your instances will be launched privately or publicly:
 
 ```ts
+declare const vpc: ec2.Vpc;
 const instance = new rds.DatabaseInstance(this, 'Instance', {
   engine: rds.DatabaseInstanceEngine.oracleSe2({ version: rds.OracleEngineVersion.VER_19_0_0_0_2020_04_R1 }),
   // optional, defaults to m5.large
@@ -75,7 +78,7 @@ const instance = new rds.DatabaseInstance(this, 'Instance', {
   credentials: rds.Credentials.fromGeneratedSecret('syscdk'), // Optional - will default to 'admin' username and generated password
   vpc,
   vpcSubnets: {
-    subnetType: ec2.SubnetType.PRIVATE
+    subnetType: ec2.SubnetType.PRIVATE,
   }
 });
 ```
@@ -95,6 +98,7 @@ This is the upper limit to which RDS can automatically scale the storage. More i
 Example for max storage configuration:
 
 ```ts
+declare const vpc: ec2.Vpc;
 const instance = new rds.DatabaseInstance(this, 'Instance', {
   engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3 }),
   // optional, defaults to m5.large
@@ -108,7 +112,8 @@ Use `DatabaseInstanceFromSnapshot` and `DatabaseInstanceReadReplica` to create a
 a source database respectively:
 
 ```ts
-new rds.DatabaseInstanceFromSnapshot(stack, 'Instance', {
+declare const vpc: ec2.Vpc;
+new rds.DatabaseInstanceFromSnapshot(this, 'Instance', {
   snapshotIdentifier: 'my-snapshot',
   engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3 }),
   // optional, defaults to m5.large
@@ -116,7 +121,8 @@ new rds.DatabaseInstanceFromSnapshot(stack, 'Instance', {
   vpc,
 });
 
-new rds.DatabaseInstanceReadReplica(stack, 'ReadReplica', {
+declare const sourceInstance: rds.DatabaseInstance;
+new rds.DatabaseInstanceReadReplica(this, 'ReadReplica', {
   sourceDatabaseInstance: sourceInstance,
   instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE),
   vpc,
@@ -136,8 +142,9 @@ The default value depends on `vpcSubnets`.
 It will be `true` if `vpcSubnets` is `subnetType: SubnetType.PUBLIC`, `false` otherwise.
 
 ```ts
+declare const vpc: ec2.Vpc;
 // Setting public accessibility for DB instance
-new rds.DatabaseInstance(stack, 'Instance', {
+new rds.DatabaseInstance(this, 'Instance', {
   engine: rds.DatabaseInstanceEngine.mysql({
     version: rds.MysqlEngineVersion.VER_8_0_19,
   }),
@@ -149,15 +156,14 @@ new rds.DatabaseInstance(stack, 'Instance', {
 });
 
 // Setting public accessibility for DB cluster
-new rds.DatabaseCluster(stack, 'DatabaseCluster', {
-  engine: DatabaseClusterEngine.AURORA,
+new rds.DatabaseCluster(this, 'DatabaseCluster', {
+  engine: rds.DatabaseClusterEngine.AURORA,
   instanceProps: {
     vpc,
     vpcSubnets: {
       subnetType: ec2.SubnetType.PRIVATE,
     },
     publiclyAccessible: true,
-    copyTagsToSnapshot: true, // whether to save the cluster tags when creating the snapshot. Default is 'true'
   },
 });
 ```
@@ -168,6 +174,8 @@ To define Amazon CloudWatch event rules for database instances, use the `onEvent
 method:
 
 ```ts
+declare const instance: rds.DatabaseInstance;
+declare const fn: lambda.Function;
 const rule = instance.onEvent('InstanceEvent', { target: new targets.LambdaFunction(fn) });
 ```
 
@@ -179,6 +187,7 @@ An alternative username (and password) may be specified for the admin user inste
 The following examples use a `DatabaseInstance`, but the same usage is applicable to `DatabaseCluster`.
 
 ```ts
+declare const vpc: ec2.Vpc;
 const engine = rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3 });
 new rds.DatabaseInstance(this, 'InstanceWithUsername', {
   engine,
@@ -203,7 +212,9 @@ new rds.DatabaseInstance(this, 'InstanceWithSecretLogin', {
 Secrets generated by `fromGeneratedSecret()` can be customized:
 
 ```ts
-const myKey = kms.Key(this, 'MyKey');
+declare const vpc: ec2.Vpc;
+const engine = rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3 });
+const myKey = new kms.Key(this, 'MyKey');
 
 new rds.DatabaseInstance(this, 'InstanceWithCustomizedSecret', {
   engine,
@@ -211,7 +222,7 @@ new rds.DatabaseInstance(this, 'InstanceWithCustomizedSecret', {
   credentials: rds.Credentials.fromGeneratedSecret('postgres', {
     secretName: 'my-cool-name',
     encryptionKey: myKey,
-    excludeCharacters: ['!&*^#@()'],
+    excludeCharacters: '!&*^#@()',
     replicaRegions: [{ region: 'eu-west-1' }, { region: 'eu-west-2' }],
   }),
 });
@@ -223,19 +234,22 @@ To control who can access the cluster or instance, use the `.connections` attrib
 a default port, so you don't need to specify the port:
 
 ```ts
-cluster.connections.allowFromAnyIpv4('Open to the world');
+declare const cluster: rds.DatabaseCluster;
+cluster.connections.allowFromAnyIpv4(ec2.Port.allTraffic(), 'Open to the world');
 ```
 
 The endpoints to access your database cluster will be available as the `.clusterEndpoint` and `.readerEndpoint`
 attributes:
 
 ```ts
+declare const cluster: rds.DatabaseCluster;
 const writeAddress = cluster.clusterEndpoint.socketAddress;   // "HOSTNAME:PORT"
 ```
 
 For an instance database:
 
 ```ts
+declare const instance: rds.DatabaseInstance;
 const address = instance.instanceEndpoint.socketAddress;   // "HOSTNAME:PORT"
 ```
 
@@ -244,6 +258,9 @@ const address = instance.instanceEndpoint.socketAddress;   // "HOSTNAME:PORT"
 When the master password is generated and stored in AWS Secrets Manager, it can be rotated automatically:
 
 ```ts
+import * as cdk from '@aws-cdk/core';
+
+declare const instance: rds.DatabaseInstance;
 instance.addRotationSingleUser({
   automaticallyAfter: cdk.Duration.days(7), // defaults to 30 days
   excludeCharacters: '!@#$%^&*', // defaults to the set " %+~`#$&*()|[]{}:;<>?!'/@\"\\"
@@ -255,6 +272,8 @@ instance.addRotationSingleUser({
 The multi user rotation scheme is also available:
 
 ```ts
+declare const instance: rds.DatabaseInstance;
+declare const myImportedSecret: rds.DatabaseSecret;
 instance.addRotationMultiUser('MyUser', {
   secret: myImportedSecret, // This secret must have the `masterarn` key
 });
@@ -263,6 +282,7 @@ instance.addRotationMultiUser('MyUser', {
 It's also possible to create user credentials together with the instance/cluster and add rotation:
 
 ```ts
+declare const instance: rds.DatabaseInstance;
 const myUserSecret = new rds.DatabaseSecret(this, 'MyUserSecret', {
   username: 'myuser',
   secretName: 'my-user-secret', // optional, defaults to a CloudFormation-generated name
@@ -290,30 +310,32 @@ and a list of supported versions and limitations.
 The following example shows enabling IAM authentication for a database instance and granting connection access to an IAM role.
 
 ```ts
-const instance = new rds.DatabaseInstance(stack, 'Instance', {
+declare const vpc: ec2.Vpc;
+const instance = new rds.DatabaseInstance(this, 'Instance', {
   engine: rds.DatabaseInstanceEngine.mysql({ version: rds.MysqlEngineVersion.VER_8_0_19 }),
   vpc,
   iamAuthentication: true, // Optional - will be automatically set if you call grantConnect().
 });
-const role = new Role(stack, 'DBRole', { assumedBy: new AccountPrincipal(stack.account) });
+const role = new iam.Role(this, 'DBRole', { assumedBy: new iam.AccountPrincipal(this.account) });
 instance.grantConnect(role); // Grant the role connection access to the DB.
 ```
 
 The following example shows granting connection access for RDS Proxy to an IAM role.
 
 ```ts
-const cluster = new rds.DatabaseCluster(stack, 'Database', {
+declare const vpc: ec2.Vpc;
+const cluster = new rds.DatabaseCluster(this, 'Database', {
   engine: rds.DatabaseClusterEngine.AURORA,
   instanceProps: { vpc },
 });
 
-const proxy = new rds.DatabaseProxy(stack, 'Proxy', {
+const proxy = new rds.DatabaseProxy(this, 'Proxy', {
   proxyTarget: rds.ProxyTarget.fromCluster(cluster),
   secrets: [cluster.secret!],
   vpc,
 });
 
-const role = new Role(stack, 'DBProxyRole', { assumedBy: new AccountPrincipal(stack.account) });
+const role = new iam.Role(this, 'DBProxyRole', { assumedBy: new iam.AccountPrincipal(this.account) });
 proxy.grantConnect(role, 'admin'); // Grant the role connection access to the DB Proxy for database user 'admin'.
 ```
 
@@ -330,13 +352,14 @@ The following example shows enabling domain support for a database instance and
 Directory Services.
 
 ```ts
-const role = new iam.Role(stack, 'RDSDirectoryServicesRole', {
+declare const vpc: ec2.Vpc;
+const role = new iam.Role(this, 'RDSDirectoryServicesRole', {
   assumedBy: new iam.ServicePrincipal('rds.amazonaws.com'),
   managedPolicies: [
     iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonRDSDirectoryServiceAccess'),
   ],
 });
-const instance = new rds.DatabaseInstance(stack, 'Instance', {
+const instance = new rds.DatabaseInstance(this, 'Instance', {
   engine: rds.DatabaseInstanceEngine.mysql({ version: rds.MysqlEngineVersion.VER_8_0_19 }),
   vpc,
   domain: 'd-????????', // The ID of the domain for the instance to join.
@@ -356,13 +379,15 @@ Database instances and clusters both expose metrics (`cloudwatch.Metric`):
 
 ```ts
 // The number of database connections in use (average over 5 minutes)
+declare const instance: rds.DatabaseInstance;
 const dbConnections = instance.metricDatabaseConnections();
 
 // Average CPU utilization over 5 minutes
+declare const cluster: rds.DatabaseCluster;
 const cpuUtilization = cluster.metricCPUUtilization();
 
 // The average amount of time taken per disk I/O operation (average over 1 minute)
-const readLatency = instance.metric('ReadLatency', { statistic: 'Average', periodSec: 60 });
+const readLatency = instance.metric('ReadLatency', { statistic: 'Average', period: Duration.seconds(60) });
 ```
 
 ## Enabling S3 integration
@@ -388,10 +413,14 @@ The following snippet sets up a database cluster with different S3 buckets where
 ```ts
 import * as s3 from '@aws-cdk/aws-s3';
 
+declare const vpc: ec2.Vpc;
 const importBucket = new s3.Bucket(this, 'importbucket');
 const exportBucket = new s3.Bucket(this, 'exportbucket');
 new rds.DatabaseCluster(this, 'dbcluster', {
-  // ...
+  engine: rds.DatabaseClusterEngine.AURORA,
+  instanceProps: {
+    vpc,
+  },
   s3ImportBuckets: [importBucket],
   s3ExportBuckets: [exportBucket],
 });
@@ -405,18 +434,13 @@ connections to the database and improve scalability of the application. Learn mo
 The following code configures an RDS Proxy for a `DatabaseInstance`.
 
 ```ts
-import * as cdk from '@aws-cdk/core';
-import * as ec2 from '@aws-cdk/aws-ec2';
-import * as rds from '@aws-cdk/aws-rds';
-import * as secrets from '@aws-cdk/aws-secretsmanager';
-
-const vpc: ec2.IVpc = ...;
-const securityGroup: ec2.ISecurityGroup = ...;
-const secrets: secrets.ISecret[] = [...];
-const dbInstance: rds.IDatabaseInstance = ...;
+declare const vpc: ec2.Vpc;
+declare const securityGroup: ec2.SecurityGroup;
+declare const secrets: secretsmanager.Secret[];
+declare const dbInstance: rds.DatabaseInstance;
 
 const proxy = dbInstance.addProxy('proxy', {
-    connectionBorrowTimeout: cdk.Duration.seconds(30),
+    borrowTimeout: Duration.seconds(30),
     maxConnectionsPercent: 50,
     secrets,
     vpc,
@@ -430,12 +454,18 @@ store the data in highly durable storage, and manage the data with the CloudWatc
 instances and clusters; the types of logs available depend on the database type and engine being used.
 
 ```ts
+import * as logs from '@aws-cdk/aws-logs';
+declare const myLogsPublishingRole: iam.Role;
+declare const vpc: ec2.Vpc;
+
 // Exporting logs from a cluster
 const cluster = new rds.DatabaseCluster(this, 'Database', {
   engine: rds.DatabaseClusterEngine.aurora({
     version: rds.AuroraEngineVersion.VER_1_17_9, // different version class for each engine type
+  }),
+  instanceProps: {
+    vpc,
   },
-  // ...
   cloudwatchLogsExports: ['error', 'general', 'slowquery', 'audit'], // Export all available MySQL-based logs
   cloudwatchLogsRetention: logs.RetentionDays.THREE_MONTHS, // Optional - default is to never expire logs
   cloudwatchLogsRetentionRole: myLogsPublishingRole, // Optional - a role will be created if not provided
@@ -447,7 +477,7 @@ const instance = new rds.DatabaseInstance(this, 'Instance', {
   engine: rds.DatabaseInstanceEngine.postgres({
     version: rds.PostgresEngineVersion.VER_12_3,
   }),
-  // ...
+  vpc,
   cloudwatchLogsExports: ['postgresql'], // Export the PostgreSQL logs
   // ...
 });
@@ -460,9 +490,10 @@ Amazon RDS uses option groups to enable and configure these features. An option
 that are available for a particular Amazon RDS DB instance.
 
 ```ts
-const vpc: ec2.IVpc = ...;
-const securityGroup: ec2.ISecurityGroup = ...;
-new rds.OptionGroup(stack, 'Options', {
+declare const vpc: ec2.Vpc;
+declare const securityGroup: ec2.SecurityGroup;
+
+new rds.OptionGroup(this, 'Options', {
   engine: rds.DatabaseInstanceEngine.oracleSe2({
     version: rds.OracleEngineVersion.VER_19,
   }),
@@ -489,10 +520,7 @@ Aurora Serverless clusters can specify scaling properties which will be used to
 automatically scale the database cluster seamlessly based on the workload.
 
 ```ts
-import * as ec2 from '@aws-cdk/aws-ec2';
-import * as rds from '@aws-cdk/aws-rds';
-
-const vpc = new ec2.Vpc(this, 'myrdsvpc');
+declare const vpc: ec2.Vpc;
 
 const cluster = new rds.ServerlessCluster(this, 'AnotherCluster', {
   engine: rds.DatabaseClusterEngine.AURORA_POSTGRESQL,
@@ -532,11 +560,7 @@ You can access your Aurora Serverless DB cluster using the built-in Data API. Th
 The following example shows granting Data API access to a Lamba function.
 
 ```ts
-import * as ec2 from '@aws-cdk/aws-ec2';
-import * as lambda from '@aws-cdk/aws-lambda';
-import * as rds from '@aws-cdk/aws-rds';
-
-const vpc = new ec2.Vpc(this, 'MyVPC');
+declare const vpc: ec2.Vpc;
 
 const cluster = new rds.ServerlessCluster(this, 'AnotherCluster', {
   engine: rds.DatabaseClusterEngine.AURORA_MYSQL,
@@ -544,16 +568,17 @@ const cluster = new rds.ServerlessCluster(this, 'AnotherCluster', {
   enableDataApi: true, // Optional - will be automatically set if you call grantDataApiAccess()
 });
 
+declare const code: lambda.Code;
 const fn = new lambda.Function(this, 'MyFunction', {
   runtime: lambda.Runtime.NODEJS_12_X,
   handler: 'index.handler',
-  code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')),
+  code,
   environment: {
     CLUSTER_ARN: cluster.clusterArn,
-    SECRET_ARN: cluster.secret.secretArn,
+    SECRET_ARN: cluster.secret!.secretArn,
   },
 });
-cluster.grantDataApiAccess(fn)
+cluster.grantDataApiAccess(fn);
 ```
 
 **Note**: To invoke the Data API, the resource will need to read the secret associated with the cluster.
diff --git a/packages/@aws-cdk/aws-rds/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-rds/rosetta/default.ts-fixture
new file mode 100644
index 0000000000000..7e78fde1372a1
--- /dev/null
+++ b/packages/@aws-cdk/aws-rds/rosetta/default.ts-fixture
@@ -0,0 +1,18 @@
+// Fixture with packages imported, but nothing else
+import { Duration, SecretValue, Stack } from '@aws-cdk/core';
+import { Construct } from 'constructs';
+import ec2 = require('@aws-cdk/aws-ec2');
+import rds = require('@aws-cdk/aws-rds');
+import targets = require('@aws-cdk/aws-events-targets');
+import lambda = require('@aws-cdk/aws-lambda');
+import kms = require('@aws-cdk/aws-kms');
+import iam = require('@aws-cdk/aws-iam');
+import secretsmanager = require('@aws-cdk/aws-secretsmanager');
+
+class Fixture extends Stack {
+  constructor(scope: Construct, id: string) {
+    super(scope, id);
+
+    /// here
+  }
+}

From 25cea1807539a8d45f3f4ff8b775b3417387d6fe Mon Sep 17 00:00:00 2001
From: Robert Djurasaj 
Date: Mon, 1 Nov 2021 14:27:15 -0600
Subject: [PATCH 098/148] feat(ec2): add c6i instances (#17237)

New C6I instances just got released:

https://aws.amazon.com/blogs/aws/new-amazon-ec2-c6i-instances-powered-by-the-latest-generation-intel-xeon-scalable-processors/

Docs have already been updated:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-instancetype

Screen Shot 2021-10-29 at 3 11 00 PM


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-ec2/lib/instance-types.ts | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts
index a2c5ccdadc760..1fc4e02f25daa 100644
--- a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts
+++ b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts
@@ -208,6 +208,16 @@ export enum InstanceClass {
    */
   C5 = 'c5',
 
+  /**
+   * Compute optimized instances, 6th generation
+   */
+  COMPUTE6_INTEL = 'c6i',
+
+  /**
+   * Compute optimized instances, 6th generation
+   */
+  C6I = 'c6i',
+
   /**
    * Compute optimized instances with local NVME drive, 5th generation
    */

From d6585253067a0e4013d2a2d41a3d3adfd40d823c Mon Sep 17 00:00:00 2001
From: Nick Lynch 
Date: Mon, 1 Nov 2021 21:21:16 +0000
Subject: [PATCH 099/148] chore: use fixed deprecated list for strip-deprecated
 (#17260)

This is a continuation (and the final piece!) of https://github.com/aws/jsii/pull/3085 and https://github.com/aws/aws-cdk/pull/17120.

Changes cdk-build to use the fixed deprecated list, rather than stripping all
deprecated elements. This will enable us to deprecate new elements going forward
without stripping them from v2 and breaking customers.

closes #16566


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 tools/@aws-cdk/cdk-build-tools/lib/package-info.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/@aws-cdk/cdk-build-tools/lib/package-info.ts b/tools/@aws-cdk/cdk-build-tools/lib/package-info.ts
index 5b79a2d675a0a..b264d3043b1b6 100644
--- a/tools/@aws-cdk/cdk-build-tools/lib/package-info.ts
+++ b/tools/@aws-cdk/cdk-build-tools/lib/package-info.ts
@@ -99,7 +99,7 @@ export function packageCompiler(compilers: CompilerOverrides, options?: CDKBuild
   if (isJsii()) {
     const args = ['--silence-warnings=reserved-word'];
     if (options?.stripDeprecated) {
-      args.push('--strip-deprecated');
+      args.push(`--strip-deprecated ${path.join(__dirname, '..', '..', '..', '..', 'deprecated_apis.txt')}`);
     }
     return [compilers.jsii || require.resolve('jsii/bin/jsii'), ...args];
   } else {

From 606a2d3e6ba23c184cd6ef989f68122f16627565 Mon Sep 17 00:00:00 2001
From: Eli Polonsky 
Date: Tue, 2 Nov 2021 00:15:13 +0200
Subject: [PATCH 100/148] chore: simplify auto approve mechanism (#17264)

Currently, PR's are auto approved if they either:

1. Contain the `pr/auto-approve` label.
2. Created by `dependabot`
3. Created by `aws-cdk-automation`

This is somewhat convoluted, and complicates the responsibility of the `auto-approve` workflow.
In addition, this makes it impossible to formulate a single GitHub query to lookup all automated PR's that we expect to be approved and merged without human intervention.

This PR switches to a simpler mechanism, by which the `auto-approve` workflow will **only** approve PR's that contain the appropriate label, forcing all PR creators to add the label if they wish to be auto-approved.

This means we can now use a simple `label:pr/auto-approve` query to find all those automated PR's.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .github/workflows/auto-approve.yml |  6 +-----
 .github/workflows/pr-labeler.yml   | 17 +++++++++++++++++
 2 files changed, 18 insertions(+), 5 deletions(-)
 create mode 100644 .github/workflows/pr-labeler.yml

diff --git a/.github/workflows/auto-approve.yml b/.github/workflows/auto-approve.yml
index 6e186b15f078f..ed29d53382d1f 100644
--- a/.github/workflows/auto-approve.yml
+++ b/.github/workflows/auto-approve.yml
@@ -7,11 +7,7 @@ on:
 
 jobs:
   auto-approve:
-    if: >
-       github.event.pull_request.user.login == 'dependabot[bot]'
-        || github.event.pull_request.user.login == 'dependabot-preview[bot]'
-        || (contains(github.event.pull_request.labels.*.name, 'pr/auto-approve')
-            && github.event.pull_request.user.login == 'aws-cdk-automation')
+    if: contains(github.event.pull_request.labels.*.name, 'pr/auto-approve')
     runs-on: ubuntu-latest
     permissions:
       pull-requests: write
diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml
new file mode 100644
index 0000000000000..b8a816623a9e0
--- /dev/null
+++ b/.github/workflows/pr-labeler.yml
@@ -0,0 +1,17 @@
+# Apply various labels on PRs
+
+name: pr-labeler
+on:
+  pull_request:
+    types: [ opened ]
+
+jobs:
+  auto-approve:
+    if: github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'dependabot-preview[bot]'
+    runs-on: ubuntu-latest
+    permissions:
+      pull-requests: write
+    steps:
+    - run: gh pr edit ${{ github.event.pull_request.number }} --add-label "pr/auto-approve" -R ${{ github.repository }}
+      env:
+        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

From 135f7d33db5e96c3af4a8691c13b419e7b14ceae Mon Sep 17 00:00:00 2001
From: Julian Michel 
Date: Tue, 2 Nov 2021 00:09:24 +0100
Subject: [PATCH 101/148] feat(docdb): add the ability to exclude characters
 when generating passwords (#17262)

Add property `excludeCharaters` to provide the ability to exclude characters when generating passwords in DocumentDB.

Requested in #15732.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-docdb/README.md         |  1 +
 packages/@aws-cdk/aws-docdb/lib/cluster.ts    |  1 +
 .../@aws-cdk/aws-docdb/lib/database-secret.ts |  9 ++++++-
 packages/@aws-cdk/aws-docdb/lib/props.ts      |  7 ++++++
 .../@aws-cdk/aws-docdb/test/cluster.test.ts   | 25 ++++++++++++++++++-
 5 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/packages/@aws-cdk/aws-docdb/README.md b/packages/@aws-cdk/aws-docdb/README.md
index 6f7ed89e28e11..12f8e08a08387 100644
--- a/packages/@aws-cdk/aws-docdb/README.md
+++ b/packages/@aws-cdk/aws-docdb/README.md
@@ -21,6 +21,7 @@ your instances will be launched privately or publicly:
 const cluster = new DatabaseCluster(this, 'Database', {
     masterUser: {
         username: 'myuser' // NOTE: 'admin' is reserved by DocumentDB
+        excludeCharacters: '\"@/:', // optional, defaults to the set "\"@/"
     },
     instanceType: ec2.InstanceType.of(ec2.InstanceClass.R5, ec2.InstanceSize.LARGE),
     vpcSubnets: {
diff --git a/packages/@aws-cdk/aws-docdb/lib/cluster.ts b/packages/@aws-cdk/aws-docdb/lib/cluster.ts
index 56b5a724dd439..c2b4c7c9737a2 100644
--- a/packages/@aws-cdk/aws-docdb/lib/cluster.ts
+++ b/packages/@aws-cdk/aws-docdb/lib/cluster.ts
@@ -352,6 +352,7 @@ export class DatabaseCluster extends DatabaseClusterBase {
       secret = new DatabaseSecret(this, 'Secret', {
         username: props.masterUser.username,
         encryptionKey: props.masterUser.kmsKey,
+        excludeCharacters: props.masterUser.excludeCharacters,
       });
     }
 
diff --git a/packages/@aws-cdk/aws-docdb/lib/database-secret.ts b/packages/@aws-cdk/aws-docdb/lib/database-secret.ts
index 605609b4b6ab2..8f1bca671da6d 100644
--- a/packages/@aws-cdk/aws-docdb/lib/database-secret.ts
+++ b/packages/@aws-cdk/aws-docdb/lib/database-secret.ts
@@ -32,6 +32,13 @@ export interface DatabaseSecretProps {
    * @default - no master secret information will be included
    */
   readonly masterSecret?: ISecret;
+
+  /**
+   * Characters to not include in the generated password.
+   *
+   * @default "\"@/"
+   */
+  readonly excludeCharacters?: string;
 }
 
 /**
@@ -61,7 +68,7 @@ export class DatabaseSecret extends Secret {
           masterarn: props.masterSecret?.secretArn,
         }),
         generateStringKey: 'password',
-        excludeCharacters: '"@/',
+        excludeCharacters: props.excludeCharacters ?? '"@/',
       },
     });
   }
diff --git a/packages/@aws-cdk/aws-docdb/lib/props.ts b/packages/@aws-cdk/aws-docdb/lib/props.ts
index 9cd24b1fce1bc..d02f8768973a9 100644
--- a/packages/@aws-cdk/aws-docdb/lib/props.ts
+++ b/packages/@aws-cdk/aws-docdb/lib/props.ts
@@ -53,6 +53,13 @@ export interface Login {
    * @default default master key
    */
   readonly kmsKey?: kms.IKey;
+
+  /**
+   * Specifies characters to not include in generated passwords.
+   *
+   * @default "\"@/"
+   */
+  readonly excludeCharacters?: string;
 }
 
 /**
diff --git a/packages/@aws-cdk/aws-docdb/test/cluster.test.ts b/packages/@aws-cdk/aws-docdb/test/cluster.test.ts
index cb1f8653509df..6628520118c84 100644
--- a/packages/@aws-cdk/aws-docdb/test/cluster.test.ts
+++ b/packages/@aws-cdk/aws-docdb/test/cluster.test.ts
@@ -1,4 +1,4 @@
-import { expect as expectCDK, haveResource, ResourcePart, arrayWith } from '@aws-cdk/assert-internal';
+import { expect as expectCDK, haveResource, ResourcePart, arrayWith, haveResourceLike, objectLike } from '@aws-cdk/assert-internal';
 import * as ec2 from '@aws-cdk/aws-ec2';
 import * as kms from '@aws-cdk/aws-kms';
 import * as cdk from '@aws-cdk/core';
@@ -293,6 +293,29 @@ describe('DatabaseCluster', () => {
     }));
   });
 
+  test('creates a secret with excludeCharacters', () => {
+    // GIVEN
+    const stack = testStack();
+    const vpc = new ec2.Vpc(stack, 'VPC');
+
+    // WHEN
+    new DatabaseCluster(stack, 'Database', {
+      masterUser: {
+        username: 'admin',
+        excludeCharacters: '"@/()[]',
+      },
+      instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL),
+      vpc,
+    });
+
+    // THEN
+    expectCDK(stack).to(haveResourceLike('AWS::SecretsManager::Secret', {
+      GenerateSecretString: objectLike({
+        ExcludeCharacters: '\"@/()[]',
+      }),
+    }));
+  });
+
   test('create an encrypted cluster with custom KMS key', () => {
     // GIVEN
     const stack = testStack();

From 1ab9b265e9899ffcd093b3600d658c8a6519cc69 Mon Sep 17 00:00:00 2001
From: Yuto Osawa <7953650+tandfy@users.noreply.github.com>
Date: Tue, 2 Nov 2021 09:03:29 +0900
Subject: [PATCH 102/148] feat(synthetics): add static cron method to schedule
 class (#17250)

closes #16402

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-synthetics/README.md    |  8 ++-
 .../@aws-cdk/aws-synthetics/lib/schedule.ts   | 72 +++++++++++++++++++
 .../aws-synthetics/test/canary.test.ts        | 21 ++++++
 .../aws-synthetics/test/schedule.test.ts      | 26 +++++++
 4 files changed, 124 insertions(+), 3 deletions(-)
 create mode 100644 packages/@aws-cdk/aws-synthetics/test/schedule.test.ts

diff --git a/packages/@aws-cdk/aws-synthetics/README.md b/packages/@aws-cdk/aws-synthetics/README.md
index 7f7665e02238c..013205a4ce3e4 100644
--- a/packages/@aws-cdk/aws-synthetics/README.md
+++ b/packages/@aws-cdk/aws-synthetics/README.md
@@ -97,13 +97,15 @@ object to the `schedule` property.
 Configure a run rate of up to 60 minutes with `Schedule.rate`:
 
 ```ts
-Schedule.rate(Duration.minutes(5)), // Runs every 5 minutes.
+Schedule.rate(Duration.minutes(5)) // Runs every 5 minutes.
 ```
 
-You can also specify a [cron expression](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_cron.html) via `Schedule.expression`:
+You can also specify a [cron expression](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_cron.html) with `Schedule.cron`:
 
 ```ts
-Schedule.expression('cron(0 0,8,16 * * ? *)'), // Run at 12am, 8am, 4pm UTC every day
+Schedule.cron({
+  hour: '0,8,16' // Run at 12am, 8am, 4pm UTC every day
+})
 ```
 
 If you want the canary to run just once upon deployment, you can use `Schedule.once()`.
diff --git a/packages/@aws-cdk/aws-synthetics/lib/schedule.ts b/packages/@aws-cdk/aws-synthetics/lib/schedule.ts
index 3bd92c81b4d0b..248b44e4c59cb 100644
--- a/packages/@aws-cdk/aws-synthetics/lib/schedule.ts
+++ b/packages/@aws-cdk/aws-synthetics/lib/schedule.ts
@@ -42,9 +42,81 @@ export class Schedule {
     return new Schedule(`rate(${minutes} minutes)`);
   }
 
+  /**
+   * Create a schedule from a set of cron fields
+   */
+  public static cron(options: CronOptions): Schedule {
+    if (options.weekDay !== undefined && options.day !== undefined) {
+      throw new Error('Cannot supply both \'day\' and \'weekDay\', use at most one');
+    }
+
+    const minute = fallback(options.minute, '*');
+    const hour = fallback(options.hour, '*');
+    const month = fallback(options.month, '*');
+
+    // Weekday defaults to '?' if not supplied. If it is supplied, day must become '?'
+    const day = fallback(options.day, options.weekDay !== undefined ? '?' : '*');
+    const weekDay = fallback(options.weekDay, '?');
+
+    // '*' is only allowed in the year field
+    const year = '*';
+
+    return new Schedule(`cron(${minute} ${hour} ${day} ${month} ${weekDay} ${year})`);
+  }
+
   private constructor(
     /**
      * The Schedule expression
      */
     public readonly expressionString: string) {}
 }
+
+
+/**
+ * Options to configure a cron expression
+ *
+ * All fields are strings so you can use complex expressions. Absence of
+ * a field implies '*' or '?', whichever one is appropriate.
+ *
+ * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_cron.html
+ */
+export interface CronOptions {
+  /**
+   * The minute to run this rule at
+   *
+   * @default - Every minute
+   */
+  readonly minute?: string;
+
+  /**
+   * The hour to run this rule at
+   *
+   * @default - Every hour
+   */
+  readonly hour?: string;
+
+  /**
+   * The day of the month to run this rule at
+   *
+   * @default - Every day of the month
+   */
+  readonly day?: string;
+
+  /**
+   * The month to run this rule at
+   *
+   * @default - Every month
+   */
+  readonly month?: string;
+
+  /**
+   * The day of the week to run this rule at
+   *
+   * @default - Any day of the week
+   */
+  readonly weekDay?: string;
+}
+
+function fallback(x: string | undefined, def: string): string {
+  return x ?? def;
+}
diff --git a/packages/@aws-cdk/aws-synthetics/test/canary.test.ts b/packages/@aws-cdk/aws-synthetics/test/canary.test.ts
index 27491d01b2850..83ba173562834 100644
--- a/packages/@aws-cdk/aws-synthetics/test/canary.test.ts
+++ b/packages/@aws-cdk/aws-synthetics/test/canary.test.ts
@@ -292,6 +292,27 @@ test('Schedule can be set to 1 minute', () => {
   });
 });
 
+test('Schedule can be set with Cron', () => {
+  // GIVEN
+  const stack = new Stack();
+
+  // WHEN
+  new synthetics.Canary(stack, 'Canary', {
+    schedule: synthetics.Schedule.cron({ minute: '30' }),
+    test: synthetics.Test.custom({
+      handler: 'index.handler',
+      code: synthetics.Code.fromInline('/* Synthetics handler code */'),
+    }),
+    runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_3,
+  });
+
+  // THEN
+  Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', {
+    Schedule: Match.objectLike({ Expression: 'cron(30 * * * ? *)' }),
+  });
+});
+
+
 test('Schedule can be set with Expression', () => {
   // GIVEN
   const stack = new Stack();
diff --git a/packages/@aws-cdk/aws-synthetics/test/schedule.test.ts b/packages/@aws-cdk/aws-synthetics/test/schedule.test.ts
new file mode 100644
index 0000000000000..664f27774b61f
--- /dev/null
+++ b/packages/@aws-cdk/aws-synthetics/test/schedule.test.ts
@@ -0,0 +1,26 @@
+import * as synthetics from '../lib';
+
+describe('cron', () => {
+  test('day and weekDay are mutex: given week day', () => {
+    expect(synthetics.Schedule.cron({
+      weekDay: 'MON-FRI',
+    }).expressionString).toEqual('cron(* * ? * MON-FRI *)');
+  });
+
+  test('day and weekDay are mutex: given month day', () => {
+    expect(synthetics.Schedule.cron({
+      day: '1',
+    }).expressionString).toEqual('cron(* * 1 * ? *)');
+  });
+
+  test('day and weekDay are mutex: given neither', () => {
+    expect(synthetics.Schedule.cron({}).expressionString).toEqual('cron(* * * * ? *)');
+  });
+
+  test('day and weekDay are mutex: throw if given both', () => {
+    expect(() => synthetics.Schedule.cron({
+      day: '1',
+      weekDay: 'MON',
+    })).toThrow('Cannot supply both \'day\' and \'weekDay\', use at most one');
+  });
+});

From 864c50ed2f3ae133af0cffd17ed77a6cf32ac6f4 Mon Sep 17 00:00:00 2001
From: Nick Lynch 
Date: Tue, 2 Nov 2021 15:54:59 +0000
Subject: [PATCH 103/148] fix(cli): cdk ls --long outputs less-friendly stack
 IDs for nested assemblies (#17263)

Since #14379, `cdk ls` has outputted friendlier stack names for nested
assemblies (e.g., with pipelines). However, `cdk ls --long` still outputs the
less-friendly stack IDs.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/aws-cdk/lib/cdk-toolkit.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/aws-cdk/lib/cdk-toolkit.ts b/packages/aws-cdk/lib/cdk-toolkit.ts
index 6bc109dd37822..65aa443190a57 100644
--- a/packages/aws-cdk/lib/cdk-toolkit.ts
+++ b/packages/aws-cdk/lib/cdk-toolkit.ts
@@ -282,7 +282,7 @@ export class CdkToolkit {
       const long = [];
       for (const stack of stacks.stackArtifacts) {
         long.push({
-          id: stack.id,
+          id: stack.hierarchicalId,
           name: stack.stackName,
           environment: stack.environment,
         });

From d4952c3cbe12e7c8c27e1bca7f9d8536d93fd3cb Mon Sep 17 00:00:00 2001
From: Peter Woodworth <44349620+peterwoodworth@users.noreply.github.com>
Date: Tue, 2 Nov 2021 10:35:39 -0700
Subject: [PATCH 104/148] fix(ec2): functions addIngressRule and addEgressRule
 detect unresolved tokens as duplicates (#17221)

fixes #17201

The issue is when the same security group uses these functions, so I added a private counter to `SecurityGroupBase`. However, to modify this private counter, `determineRuleScope` and `renderPeer` need to be member functions. These originally weren't member functions for a reason, and that's because `SecurityGroup` also uses these functions.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../@aws-cdk/aws-ec2/lib/security-group.ts    | 152 +++++++++---------
 .../aws-ec2/test/security-group.test.ts       |  24 +++
 2 files changed, 104 insertions(+), 72 deletions(-)

diff --git a/packages/@aws-cdk/aws-ec2/lib/security-group.ts b/packages/@aws-cdk/aws-ec2/lib/security-group.ts
index 54695f2d17b71..692df3629ebbf 100644
--- a/packages/@aws-cdk/aws-ec2/lib/security-group.ts
+++ b/packages/@aws-cdk/aws-ec2/lib/security-group.ts
@@ -68,6 +68,8 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup {
   public readonly connections: Connections = new Connections({ securityGroups: [this] });
   public readonly defaultPort?: Port;
 
+  private peerAsTokenCount: number = 0;
+
   constructor(scope: Construct, id: string, props?: ResourceProps) {
     super(scope, id, props);
 
@@ -83,7 +85,7 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup {
       description = `from ${peer.uniqueId}:${connection}`;
     }
 
-    const [scope, id] = determineRuleScope(this, peer, connection, 'from', remoteRule);
+    const [scope, id] = this.determineRuleScope(peer, connection, 'from', remoteRule);
 
     // Skip duplicates
     if (scope.node.tryFindChild(id) === undefined) {
@@ -101,7 +103,7 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup {
       description = `to ${peer.uniqueId}:${connection}`;
     }
 
-    const [scope, id] = determineRuleScope(this, peer, connection, 'to', remoteRule);
+    const [scope, id] = this.determineRuleScope(peer, connection, 'to', remoteRule);
 
     // Skip duplicates
     if (scope.node.tryFindChild(id) === undefined) {
@@ -121,75 +123,82 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup {
   public toEgressRuleConfig(): any {
     return { destinationSecurityGroupId: this.securityGroupId };
   }
-}
 
-/**
- * Determine where to parent a new ingress/egress rule
- *
- * A SecurityGroup rule is parented under the group it's related to, UNLESS
- * we're in a cross-stack scenario with another Security Group. In that case,
- * we respect the 'remoteRule' flag and will parent under the other security
- * group.
- *
- * This is necessary to avoid cyclic dependencies between stacks, since both
- * ingress and egress rules will reference both security groups, and a naive
- * parenting will lead to the following situation:
- *
- *   โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—         โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
- *   โ•‘  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ•‘         โ•‘    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ•‘
- *   โ•‘  โ”‚  GroupA   โ”‚โ—€โ”€โ”€โ”€โ”€โ•ฌโ”€โ”   โ”Œโ”€โ”€โ”€โ•ฌโ”€โ”€โ”€โ–ถโ”‚  GroupB   โ”‚   โ•‘
- *   โ•‘  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ•‘ โ”‚   โ”‚   โ•‘    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ•‘
- *   โ•‘        โ–ฒ           โ•‘ โ”‚   โ”‚   โ•‘          โ–ฒ         โ•‘
- *   โ•‘        โ”‚           โ•‘ โ”‚   โ”‚   โ•‘          โ”‚         โ•‘
- *   โ•‘        โ”‚           โ•‘ โ”‚   โ”‚   โ•‘          โ”‚         โ•‘
- *   โ•‘  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ•‘ โ””โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ•ฌโ”€โ”€โ”€โ”€โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ•‘
- *   โ•‘  โ”‚  EgressA  โ”‚โ”€โ”€โ”€โ”€โ”€โ•ฌโ”€โ”€โ”€โ”€โ”€โ”˜   โ•‘    โ”‚ IngressB  โ”‚   โ•‘
- *   โ•‘  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ•‘         โ•‘    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ•‘
- *   โ•‘                    โ•‘         โ•‘                    โ•‘
- *   โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•         โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
- *
- * By having the ability to switch the parent, we avoid the cyclic reference by
- * keeping all rules in a single stack.
- *
- * If this happens, we also have to change the construct ID, because
- * otherwise we might have two objects with the same ID if we have
- * multiple reversed security group relationships.
- *
- *   โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
- *   โ•‘โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                      โ•‘
- *   โ•‘โ”‚  GroupB   โ”‚                      โ•‘
- *   โ•‘โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                      โ•‘
- *   โ•‘      โ–ฒ                            โ•‘
- *   โ•‘      โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ•‘
- *   โ•‘      โ”œโ”€โ”€โ”€โ”€"from A"โ”€โ”€โ”‚ IngressB  โ”‚ โ•‘
- *   โ•‘      โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ•‘
- *   โ•‘      โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ•‘
- *   โ•‘      โ”œโ”€โ”€โ”€โ”€โ”€"to B"โ”€โ”€โ”€โ”‚  EgressA  โ”‚ โ•‘
- *   โ•‘      โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ•‘
- *   โ•‘      โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ•‘
- *   โ•‘      โ””โ”€โ”€โ”€โ”€โ”€"to B"โ”€โ”€โ”€โ”‚  EgressC  โ”‚ โ•‘  <-- oops
- *   โ•‘                     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ•‘
- *   โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
- */
-function determineRuleScope(
-  group: SecurityGroupBase,
-  peer: IPeer,
-  connection: Port,
-  fromTo: 'from' | 'to',
-  remoteRule?: boolean): [SecurityGroupBase, string] {
-
-  if (remoteRule && SecurityGroupBase.isSecurityGroup(peer) && differentStacks(group, peer)) {
-    // Reversed
-    const reversedFromTo = fromTo === 'from' ? 'to' : 'from';
-    return [peer, `${group.uniqueId}:${connection} ${reversedFromTo}`];
-  } else {
-    // Regular (do old ID escaping to in order to not disturb existing deployments)
-    return [group, `${fromTo} ${renderPeer(peer)}:${connection}`.replace('/', '_')];
+  /**
+   * Determine where to parent a new ingress/egress rule
+   *
+   * A SecurityGroup rule is parented under the group it's related to, UNLESS
+   * we're in a cross-stack scenario with another Security Group. In that case,
+   * we respect the 'remoteRule' flag and will parent under the other security
+   * group.
+   *
+   * This is necessary to avoid cyclic dependencies between stacks, since both
+   * ingress and egress rules will reference both security groups, and a naive
+   * parenting will lead to the following situation:
+   *
+   *   โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—         โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
+   *   โ•‘  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ•‘         โ•‘    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ•‘
+   *   โ•‘  โ”‚  GroupA   โ”‚โ—€โ”€โ”€โ”€โ”€โ•ฌโ”€โ”   โ”Œโ”€โ”€โ”€โ•ฌโ”€โ”€โ”€โ–ถโ”‚  GroupB   โ”‚   โ•‘
+   *   โ•‘  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ•‘ โ”‚   โ”‚   โ•‘    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ•‘
+   *   โ•‘        โ–ฒ           โ•‘ โ”‚   โ”‚   โ•‘          โ–ฒ         โ•‘
+   *   โ•‘        โ”‚           โ•‘ โ”‚   โ”‚   โ•‘          โ”‚         โ•‘
+   *   โ•‘        โ”‚           โ•‘ โ”‚   โ”‚   โ•‘          โ”‚         โ•‘
+   *   โ•‘  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ•‘ โ””โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ•ฌโ”€โ”€โ”€โ”€โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ•‘
+   *   โ•‘  โ”‚  EgressA  โ”‚โ”€โ”€โ”€โ”€โ”€โ•ฌโ”€โ”€โ”€โ”€โ”€โ”˜   โ•‘    โ”‚ IngressB  โ”‚   โ•‘
+   *   โ•‘  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ•‘         โ•‘    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ•‘
+   *   โ•‘                    โ•‘         โ•‘                    โ•‘
+   *   โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•         โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
+   *
+   * By having the ability to switch the parent, we avoid the cyclic reference by
+   * keeping all rules in a single stack.
+   *
+   * If this happens, we also have to change the construct ID, because
+   * otherwise we might have two objects with the same ID if we have
+   * multiple reversed security group relationships.
+   *
+   *   โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
+   *   โ•‘โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                      โ•‘
+   *   โ•‘โ”‚  GroupB   โ”‚                      โ•‘
+   *   โ•‘โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                      โ•‘
+   *   โ•‘      โ–ฒ                            โ•‘
+   *   โ•‘      โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ•‘
+   *   โ•‘      โ”œโ”€โ”€โ”€โ”€"from A"โ”€โ”€โ”‚ IngressB  โ”‚ โ•‘
+   *   โ•‘      โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ•‘
+   *   โ•‘      โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ•‘
+   *   โ•‘      โ”œโ”€โ”€โ”€โ”€โ”€"to B"โ”€โ”€โ”€โ”‚  EgressA  โ”‚ โ•‘
+   *   โ•‘      โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ•‘
+   *   โ•‘      โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ•‘
+   *   โ•‘      โ””โ”€โ”€โ”€โ”€โ”€"to B"โ”€โ”€โ”€โ”‚  EgressC  โ”‚ โ•‘  <-- oops
+   *   โ•‘                     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ•‘
+   *   โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
+   */
+
+  protected determineRuleScope(
+    peer: IPeer,
+    connection: Port,
+    fromTo: 'from' | 'to',
+    remoteRule?: boolean): [SecurityGroupBase, string] {
+
+    if (remoteRule && SecurityGroupBase.isSecurityGroup(peer) && differentStacks(this, peer)) {
+      // Reversed
+      const reversedFromTo = fromTo === 'from' ? 'to' : 'from';
+      return [peer, `${this.uniqueId}:${connection} ${reversedFromTo}`];
+    } else {
+      // Regular (do old ID escaping to in order to not disturb existing deployments)
+      return [this, `${fromTo} ${this.renderPeer(peer)}:${connection}`.replace('/', '_')];
+    }
   }
-}
 
-function renderPeer(peer: IPeer) {
-  return Token.isUnresolved(peer.uniqueId) ? '{IndirectPeer}' : peer.uniqueId;
+  private renderPeer(peer: IPeer) {
+    if (Token.isUnresolved(peer.uniqueId)) {
+      // Need to return a unique value each time a peer
+      // is an unresolved token, else the duplicate skipper
+      // in `sg.addXxxRule` can detect unique rules as duplicates
+      return this.peerAsTokenCount++ ? `'{IndirectPeer${this.peerAsTokenCount}}'` : '{IndirectPeer}';
+    } else {
+      return peer.uniqueId;
+    }
+  }
 }
 
 function differentStacks(group1: SecurityGroupBase, group2: SecurityGroupBase) {
@@ -565,13 +574,12 @@ export class SecurityGroup extends SecurityGroupBase {
    */
   private removeNoTrafficRule() {
     if (this.disableInlineRules) {
-      const [scope, id] = determineRuleScope(
-        this,
+      const [scope, id] = this.determineRuleScope(
         NO_TRAFFIC_PEER,
         NO_TRAFFIC_PORT,
         'to',
-        false);
-
+        false,
+      );
       scope.node.tryRemoveChild(id);
     } else {
       const i = this.directEgressRules.findIndex(r => egressRulesEqual(r, MATCH_NO_TRAFFIC));
diff --git a/packages/@aws-cdk/aws-ec2/test/security-group.test.ts b/packages/@aws-cdk/aws-ec2/test/security-group.test.ts
index 09ccc6cdc682e..70dbe64cef335 100644
--- a/packages/@aws-cdk/aws-ec2/test/security-group.test.ts
+++ b/packages/@aws-cdk/aws-ec2/test/security-group.test.ts
@@ -208,6 +208,30 @@ describe('security group', () => {
 
   });
 
+  test('can add multiple rules using tokens on same security group', () => {
+    // GIVEN
+    const stack = new Stack(undefined, 'TestStack', { env: { account: '12345678', region: 'dummy' } });
+    const vpc = new Vpc(stack, 'VPC');
+    const sg = new SecurityGroup(stack, 'SG', { vpc });
+
+    const p1 = Lazy.string({ produce: () => 'dummyid1' });
+    const p2 = Lazy.string({ produce: () => 'dummyid2' });
+    const peer1 = Peer.prefixList(p1);
+    const peer2 = Peer.prefixList(p2);
+
+    // WHEN
+    sg.addIngressRule(peer1, Port.tcp(5432), 'Rule 1');
+    sg.addIngressRule(peer2, Port.tcp(5432), 'Rule 2');
+
+    // THEN -- no crash
+    expect(stack).toHaveResourceLike('AWS::EC2::SecurityGroupIngress', {
+      Description: 'Rule 1',
+    });
+    expect(stack).toHaveResourceLike('AWS::EC2::SecurityGroupIngress', {
+      Description: 'Rule 2',
+    });
+  });
+
   test('if tokens are used in ports, `canInlineRule` should be false to avoid cycles', () => {
     // GIVEN
     const p1 = Lazy.number({ produce: () => 80 });

From f8d0ef550df07e43aeab35dde4406c92f7551ed0 Mon Sep 17 00:00:00 2001
From: arcrank 
Date: Tue, 2 Nov 2021 14:30:17 -0400
Subject: [PATCH 105/148] feat(servicecatalog): allow creating a CFN Product
 Version with CDK code (#17144)

Add ability to define a product version entirely within CDK as opposed to referencing templates or local assets.
The service catalog `ProductStack` is similar to `NestedStacks` that do not deploy themselves but rather are referenced
by the parent stacks.  The resources defined in your product are added to the product stack like any other cdk app.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*



Co-authored-by: Dillon Ponzo 
---
 .../@aws-cdk/aws-servicecatalog/README.md     |  39 +++++-
 .../lib/cloudformation-template.ts            |  26 ++++
 .../@aws-cdk/aws-servicecatalog/lib/index.ts  |   1 +
 .../lib/private/product-stack-synthesizer.ts  |  34 ++++++
 .../aws-servicecatalog/lib/product-stack.ts   |  77 ++++++++++++
 .../@aws-cdk/aws-servicecatalog/package.json  |   3 +-
 .../rosetta/basic-portfolio.ts-fixture        |   6 +-
 .../test/integ.product.expected.json          | 114 ++++++++++++++++++
 .../aws-servicecatalog/test/integ.product.ts  |  15 +++
 .../test/product-stack.test.ts                |  88 ++++++++++++++
 .../aws-servicecatalog/test/product.test.ts   |  88 ++++++++++++++
 11 files changed, 485 insertions(+), 6 deletions(-)
 create mode 100644 packages/@aws-cdk/aws-servicecatalog/lib/private/product-stack-synthesizer.ts
 create mode 100644 packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts
 create mode 100644 packages/@aws-cdk/aws-servicecatalog/test/product-stack.test.ts

diff --git a/packages/@aws-cdk/aws-servicecatalog/README.md b/packages/@aws-cdk/aws-servicecatalog/README.md
index 4bb6885c601eb..2d7694d3e84b6 100644
--- a/packages/@aws-cdk/aws-servicecatalog/README.md
+++ b/packages/@aws-cdk/aws-servicecatalog/README.md
@@ -30,6 +30,8 @@ enables organizations to create and manage catalogs of products for their end us
   - [Granting access to a portfolio](#granting-access-to-a-portfolio)
   - [Sharing a portfolio with another AWS account](#sharing-a-portfolio-with-another-aws-account)
 - [Product](#product)
+  - [Creating a product from a local asset](#creating-a-product-from-local-asset)
+  - [Creating a product from a stack](#creating-a-product-from-a-stack)
   - [Adding a product to a portfolio](#adding-a-product-to-a-portfolio)
 - [TagOptions](#tag-options)
 - [Constraints](#constraints)
@@ -125,10 +127,12 @@ const product = new servicecatalog.CloudFormationProduct(this, 'MyFirstProduct',
       cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromUrl(
         'https://raw.githubusercontent.com/awslabs/aws-cloudformation-templates/master/aws/services/ServiceCatalog/Product.yaml'),
     },
-  ]
+  ],
 });
 ```
 
+### Creating a product from a local asset
+
 A `CloudFormationProduct` can also be created using a Cloudformation template from an Asset.
 Assets are files that are uploaded to an S3 Bucket before deployment.
 `CloudFormationTemplate.fromAsset` can be utilized to create a Product by passing the path to a local template file on your disk:
@@ -149,7 +153,38 @@ const product = new servicecatalog.CloudFormationProduct(this, 'MyFirstProduct',
       productVersionName: "v2",
       cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromAsset(path.join(__dirname, 'development-environment.template.json')),
     },
-  ]
+  ],
+});
+```
+
+### Creating a product from a stack
+
+You can define a service catalog `CloudFormationProduct` entirely within CDK using a service catalog `ProductStack`.
+A separate child stack for your product is created and you can add resources like you would for any other CDK stack,
+such as an S3 Bucket, IAM roles, and EC2 instances. This stack is passed in as a product version to your
+product.  This will not create a separate stack during deployment. 
+
+```ts
+import * as s3 from '@aws-cdk/aws-s3';
+import * as cdk from '@aws-cdk/core';
+
+class S3BucketProduct extends servicecatalog.ProductStack {
+  constructor(scope: cdk.Construct, id: string) {
+    super(scope, id);
+
+    new s3.Bucket(this, 'BucketProduct');
+  }
+}
+
+const product = new servicecatalog.CloudFormationProduct(this, 'MyFirstProduct', {
+  productName: "My Product",
+  owner: "Product Owner",
+  productVersions: [
+    {
+      productVersionName: "v1",
+      cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new S3BucketProduct(this, 'S3BucketProduct')),
+    },
+  ],
 });
 ```
 
diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/cloudformation-template.ts b/packages/@aws-cdk/aws-servicecatalog/lib/cloudformation-template.ts
index be0cb9adf2022..4086db6655fda 100644
--- a/packages/@aws-cdk/aws-servicecatalog/lib/cloudformation-template.ts
+++ b/packages/@aws-cdk/aws-servicecatalog/lib/cloudformation-template.ts
@@ -1,5 +1,6 @@
 import * as s3_assets from '@aws-cdk/aws-s3-assets';
 import { hashValues } from './private/util';
+import { ProductStack } from './product-stack';
 
 // keep this import separate from other imports to reduce chance for merge conflicts with v2-main
 // eslint-disable-next-line no-duplicate-imports, import/order
@@ -26,6 +27,13 @@ export abstract class CloudFormationTemplate {
     return new CloudFormationAssetTemplate(path, options);
   }
 
+  /**
+   * Creates a product with the resources defined in the given product stack.
+   */
+  public static fromProductStack(productStack: ProductStack): CloudFormationTemplate {
+    return new CloudFormationProductStackTemplate(productStack);
+  }
+
   /**
    * Called when the product is initialized to allow this object to bind
    * to the stack, add resources and have fun.
@@ -88,3 +96,21 @@ class CloudFormationAssetTemplate extends CloudFormationTemplate {
     };
   }
 }
+
+/**
+ * Template from a CDK defined product stack.
+ */
+class CloudFormationProductStackTemplate extends CloudFormationTemplate {
+  /**
+   * @param stack A service catalog product stack.
+  */
+  constructor(public readonly productStack: ProductStack) {
+    super();
+  }
+
+  public bind(_scope: Construct): CloudFormationTemplateConfig {
+    return {
+      httpUrl: this.productStack._getTemplateUrl(),
+    };
+  }
+}
diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/index.ts b/packages/@aws-cdk/aws-servicecatalog/lib/index.ts
index 8a7b0f0ff9ac6..cc26e880fdd2e 100644
--- a/packages/@aws-cdk/aws-servicecatalog/lib/index.ts
+++ b/packages/@aws-cdk/aws-servicecatalog/lib/index.ts
@@ -3,6 +3,7 @@ export * from './constraints';
 export * from './cloudformation-template';
 export * from './portfolio';
 export * from './product';
+export * from './product-stack';
 export * from './tag-options';
 
 // AWS::ServiceCatalog CloudFormation Resources:
diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/private/product-stack-synthesizer.ts b/packages/@aws-cdk/aws-servicecatalog/lib/private/product-stack-synthesizer.ts
new file mode 100644
index 0000000000000..4840a7e756fe5
--- /dev/null
+++ b/packages/@aws-cdk/aws-servicecatalog/lib/private/product-stack-synthesizer.ts
@@ -0,0 +1,34 @@
+import * as cdk from '@aws-cdk/core';
+
+/**
+ * Deployment environment for an AWS Service Catalog product stack.
+ *
+ * Interoperates with the StackSynthesizer of the parent stack.
+ */
+export class ProductStackSynthesizer extends cdk.StackSynthesizer {
+  private stack?: cdk.Stack;
+
+  public bind(stack: cdk.Stack): void {
+    if (this.stack !== undefined) {
+      throw new Error('A Stack Synthesizer can only be bound once, create a new instance to use with a different Stack');
+    }
+    this.stack = stack;
+  }
+
+  public addFileAsset(_asset: cdk.FileAssetSource): cdk.FileAssetLocation {
+    throw new Error('Service Catalog Product Stacks cannot use Assets');
+  }
+
+  public addDockerImageAsset(_asset: cdk.DockerImageAssetSource): cdk.DockerImageAssetLocation {
+    throw new Error('Service Catalog Product Stacks cannot use Assets');
+  }
+
+  public synthesize(session: cdk.ISynthesisSession): void {
+    if (!this.stack) {
+      throw new Error('You must call bindStack() first');
+    }
+    // Synthesize the template, but don't emit as a cloud assembly artifact.
+    // It will be registered as an S3 asset of its parent instead.
+    this.synthesizeStackTemplate(this.stack, session);
+  }
+}
diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts b/packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts
new file mode 100644
index 0000000000000..b96224a8b2c60
--- /dev/null
+++ b/packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts
@@ -0,0 +1,77 @@
+import * as crypto from 'crypto';
+import * as fs from 'fs';
+import * as path from 'path';
+import * as cdk from '@aws-cdk/core';
+import { ProductStackSynthesizer } from './private/product-stack-synthesizer';
+
+// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
+// eslint-disable-next-line no-duplicate-imports, import/order
+import { Construct } from 'constructs';
+
+/**
+ * A Service Catalog product stack, which is similar in form to a Cloudformation nested stack.
+ * You can add the resources to this stack that you want to define for your service catalog product.
+ *
+ * This stack will not be treated as an independent deployment
+ * artifact (won't be listed in "cdk list" or deployable through "cdk deploy"),
+ * but rather only synthesized as a template and uploaded as an asset to S3.
+ *
+ */
+export class ProductStack extends cdk.Stack {
+  public readonly templateFile: string;
+  private _templateUrl?: string;
+  private _parentStack: cdk.Stack;
+
+  constructor(scope: Construct, id: string) {
+    super(scope, id, {
+      synthesizer: new ProductStackSynthesizer(),
+    });
+
+    this._parentStack = findParentStack(scope);
+
+    // this is the file name of the synthesized template file within the cloud assembly
+    this.templateFile = `${cdk.Names.uniqueId(this)}.product.template.json`;
+  }
+
+  /**
+   * Fetch the template URL.
+   *
+   * @internal
+   */
+  public _getTemplateUrl(): string {
+    return cdk.Lazy.uncachedString({ produce: () => this._templateUrl });
+  }
+
+  /**
+   * Synthesize the product stack template, overrides the `super` class method.
+   *
+   * Defines an asset at the parent stack which represents the template of this
+   * product stack.
+   *
+   * @internal
+   */
+  public _synthesizeTemplate(session: cdk.ISynthesisSession): void {
+    const cfn = JSON.stringify(this._toCloudFormation(), undefined, 2);
+    const templateHash = crypto.createHash('sha256').update(cfn).digest('hex');
+
+    this._templateUrl = this._parentStack.synthesizer.addFileAsset({
+      packaging: cdk.FileAssetPackaging.FILE,
+      sourceHash: templateHash,
+      fileName: this.templateFile,
+    }).httpUrl;
+
+    fs.writeFileSync(path.join(session.assembly.outdir, this.templateFile), cfn);
+  }
+}
+
+/**
+ * Validates the scope for a product stack, which must be defined within the scope of another `Stack`.
+ */
+function findParentStack(scope: Construct): cdk.Stack {
+  try {
+    const parentStack = cdk.Stack.of(scope);
+    return parentStack as cdk.Stack;
+  } catch (e) {
+    throw new Error('Product stacks must be defined within scope of another non-product stack');
+  }
+}
diff --git a/packages/@aws-cdk/aws-servicecatalog/package.json b/packages/@aws-cdk/aws-servicecatalog/package.json
index de3bfcfb667a5..3d96fbe55edcc 100644
--- a/packages/@aws-cdk/aws-servicecatalog/package.json
+++ b/packages/@aws-cdk/aws-servicecatalog/package.json
@@ -104,7 +104,8 @@
       "resource-attribute:@aws-cdk/aws-servicecatalog.CloudFormationProduct.cloudFormationProductProvisioningArtifactNames",
       "props-physical-name:@aws-cdk/aws-servicecatalog.CloudFormationProductProps",
       "resource-attribute:@aws-cdk/aws-servicecatalog.Portfolio.portfolioName",
-      "props-physical-name:@aws-cdk/aws-servicecatalog.PortfolioProps"
+      "props-physical-name:@aws-cdk/aws-servicecatalog.PortfolioProps",
+      "props-physical-name:@aws-cdk/aws-servicecatalog.ProductStack"
     ]
   },
   "maturity": "experimental",
diff --git a/packages/@aws-cdk/aws-servicecatalog/rosetta/basic-portfolio.ts-fixture b/packages/@aws-cdk/aws-servicecatalog/rosetta/basic-portfolio.ts-fixture
index d8925e6645aa7..3029872ea1f0d 100644
--- a/packages/@aws-cdk/aws-servicecatalog/rosetta/basic-portfolio.ts-fixture
+++ b/packages/@aws-cdk/aws-servicecatalog/rosetta/basic-portfolio.ts-fixture
@@ -1,9 +1,9 @@
 // Fixture with packages imported, but nothing else
-import { Construct, Stack } from '@aws-cdk/core';
+import * as cdk from '@aws-cdk/core';
 import * as servicecatalog from '@aws-cdk/aws-servicecatalog';
 
-class Fixture extends Stack {
-  constructor(scope: Construct, id: string) {
+class Fixture extends cdk.Stack {
+  constructor(scope: cdk.Construct, id: string) {
     super(scope, id);
 
     const portfolio = new servicecatalog.Portfolio(this, "MyFirstPortfolio", {
diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.expected.json b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.expected.json
index 786fdcad0f8fc..f54d640e1d0ca 100644
--- a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.expected.json
+++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.expected.json
@@ -113,6 +113,108 @@
                 ]
               }
             }
+          },
+          {
+            "DisableTemplateValidation": false,
+            "Info": {
+              "LoadTemplateFromURL": {
+                "Fn::Join": [
+                  "",
+                  [
+                    "https://s3.",
+                    {
+                      "Ref": "AWS::Region"
+                    },
+                    ".",
+                    {
+                      "Ref": "AWS::URLSuffix"
+                    },
+                    "/",
+                    {
+                      "Ref": "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3BucketB4751C98"
+                    },
+                    "/",
+                    {
+                      "Fn::Select": [
+                        0,
+                        {
+                          "Fn::Split": [
+                            "||",
+                            {
+                              "Ref": "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3VersionKeyEB38C6F9"
+                            }
+                          ]
+                        }
+                      ]
+                    },
+                    {
+                      "Fn::Select": [
+                        1,
+                        {
+                          "Fn::Split": [
+                            "||",
+                            {
+                              "Ref": "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3VersionKeyEB38C6F9"
+                            }
+                          ]
+                        }
+                      ]
+                    }
+                  ]
+                ]
+              }
+            }
+          },
+          {
+            "DisableTemplateValidation": false,
+            "Info": {
+              "LoadTemplateFromURL": {
+                "Fn::Join": [
+                  "",
+                  [
+                    "https://s3.",
+                    {
+                      "Ref": "AWS::Region"
+                    },
+                    ".",
+                    {
+                      "Ref": "AWS::URLSuffix"
+                    },
+                    "/",
+                    {
+                      "Ref": "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3BucketB4751C98"
+                    },
+                    "/",
+                    {
+                      "Fn::Select": [
+                        0,
+                        {
+                          "Fn::Split": [
+                            "||",
+                            {
+                              "Ref": "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3VersionKeyEB38C6F9"
+                            }
+                          ]
+                        }
+                      ]
+                    },
+                    {
+                      "Fn::Select": [
+                        1,
+                        {
+                          "Fn::Split": [
+                            "||",
+                            {
+                              "Ref": "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3VersionKeyEB38C6F9"
+                            }
+                          ]
+                        }
+                      ]
+                    }
+                  ]
+                ]
+              }
+            }
           }
         ]
       }
@@ -142,6 +244,18 @@
     "AssetParameters6412a5f4524c6b41d26fbeee226c68c2dad735393940a51008d77e6f8b1038f5ArtifactHashDC26AFAC": {
       "Type": "String",
       "Description": "Artifact hash for asset \"6412a5f4524c6b41d26fbeee226c68c2dad735393940a51008d77e6f8b1038f5\""
+    },
+    "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3BucketB4751C98": {
+      "Type": "String",
+      "Description": "S3 bucket for asset \"dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f\""
+    },
+    "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3VersionKeyEB38C6F9": {
+      "Type": "String",
+      "Description": "S3 key for asset version \"dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f\""
+    },
+    "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fArtifactHash5C1F9228": {
+      "Type": "String",
+      "Description": "Artifact hash for asset \"dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f\""
     }
   }
 }
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.ts b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.ts
index 5c4192cc9b25c..7a88c98a466d1 100644
--- a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.ts
+++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.ts
@@ -1,10 +1,19 @@
 import * as path from 'path';
+import * as sns from '@aws-cdk/aws-sns';
 import * as cdk from '@aws-cdk/core';
 import * as servicecatalog from '../lib';
 
 const app = new cdk.App();
 const stack = new cdk.Stack(app, 'integ-servicecatalog-product');
 
+class TestProductStack extends servicecatalog.ProductStack {
+  constructor(scope: any, id: string) {
+    super(scope, id);
+
+    new sns.Topic(this, 'TopicProduct');
+  }
+}
+
 new servicecatalog.CloudFormationProduct(stack, 'TestProduct', {
   productName: 'testProduct',
   owner: 'testOwner',
@@ -20,6 +29,12 @@ new servicecatalog.CloudFormationProduct(stack, 'TestProduct', {
     {
       cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromAsset(path.join(__dirname, 'product2.template.json')),
     },
+    {
+      cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new TestProductStack(stack, 'SNSTopicProduct1')),
+    },
+    {
+      cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new TestProductStack(stack, 'SNSTopicProduct2')),
+    },
   ],
 });
 
diff --git a/packages/@aws-cdk/aws-servicecatalog/test/product-stack.test.ts b/packages/@aws-cdk/aws-servicecatalog/test/product-stack.test.ts
new file mode 100644
index 0000000000000..e024421d724dc
--- /dev/null
+++ b/packages/@aws-cdk/aws-servicecatalog/test/product-stack.test.ts
@@ -0,0 +1,88 @@
+import * as fs from 'fs';
+import * as path from 'path';
+import * as s3_assets from '@aws-cdk/aws-s3-assets';
+import * as sns from '@aws-cdk/aws-sns';
+import * as cdk from '@aws-cdk/core';
+import * as servicecatalog from '../lib';
+
+/* eslint-disable quote-props */
+describe('ProductStack', () => {
+  test('fails to add asset to a product stack', () => {
+    // GIVEN
+    const app = new cdk.App();
+    const mainStack = new cdk.Stack(app, 'MyStack');
+    const productStack = new servicecatalog.ProductStack(mainStack, 'MyProductStack');
+
+    // THEN
+    expect(() => {
+      new s3_assets.Asset(productStack, 'testAsset', {
+        path: path.join(__dirname, 'product1.template.json'),
+      });
+    }).toThrow(/Service Catalog Product Stacks cannot use Assets/);
+  }),
+
+  test('fails if defined at root', () => {
+    // GIVEN
+    const app = new cdk.App();
+
+    // THEN
+    expect(() => {
+      new servicecatalog.ProductStack(app, 'ProductStack');
+    }).toThrow(/must be defined within scope of another non-product stack/);
+  }),
+
+  test('fails if defined without a parent stack', () => {
+    // GIVEN
+    const app = new cdk.App();
+    const group = new cdk.Construct(app, 'group');
+
+    // THEN
+    expect(() => {
+      new servicecatalog.ProductStack(group, 'ProductStack');
+    }).toThrow(/must be defined within scope of another non-product stack/);
+  }),
+
+  test('can be defined as a direct child or an indirect child of a Stack', () => {
+    // GIVEN
+    const parent = new cdk.Stack();
+
+    // THEN
+    expect(() => {
+      new servicecatalog.ProductStack(parent, 'direct');
+    }).not.toThrow();
+  });
+
+  test('product stack is not synthesized as a stack artifact into the assembly', () => {
+    // GIVEN
+    const app = new cdk.App();
+    const parentStack = new cdk.Stack(app, 'ParentStack');
+    new servicecatalog.ProductStack(parentStack, 'ProductStack');
+
+    // WHEN
+    const assembly = app.synth();
+
+    // THEN
+    expect(assembly.artifacts.length).toEqual(2);
+  });
+
+  test('the template of the product stack is synthesized into the cloud assembly', () => {
+    // GIVEN
+    const app = new cdk.App();
+    const parent = new cdk.Stack(app, 'ParentStack');
+    const productStack = new servicecatalog.ProductStack(parent, 'ProductStack');
+    new sns.Topic(productStack, 'SNSTopicProduct');
+
+    // WHEN
+    const assembly = app.synth();
+
+    // THEN
+    const template = JSON.parse(fs.readFileSync(path.join(assembly.directory, productStack.templateFile), 'utf-8'));
+    expect(template).toEqual({
+      Resources: {
+        SNSTopicProduct20605D98: {
+          Type: 'AWS::SNS::Topic',
+        },
+      },
+    });
+  });
+});
diff --git a/packages/@aws-cdk/aws-servicecatalog/test/product.test.ts b/packages/@aws-cdk/aws-servicecatalog/test/product.test.ts
index f3e485b30e951..f399a79dcdb83 100644
--- a/packages/@aws-cdk/aws-servicecatalog/test/product.test.ts
+++ b/packages/@aws-cdk/aws-servicecatalog/test/product.test.ts
@@ -1,5 +1,6 @@
 import * as path from 'path';
 import { Match, Template } from '@aws-cdk/assertions';
+import * as sns from '@aws-cdk/aws-sns';
 import * as cdk from '@aws-cdk/core';
 import * as servicecatalog from '../lib';
 
@@ -101,6 +102,93 @@ describe('Product', () => {
     expect(synthesized.assets.length).toEqual(2);
   }),
 
+  test('product test from product stack', () => {
+    const productStack = new servicecatalog.ProductStack(stack, 'ProductStack');
+
+    new sns.Topic(productStack, 'SNSTopicProductStack');
+
+    new servicecatalog.CloudFormationProduct(stack, 'MyProduct', {
+      productName: 'testProduct',
+      owner: 'testOwner',
+      productVersions: [
+        {
+          productVersionName: 'v1',
+          cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(productStack),
+        },
+      ],
+    });
+
+    const assembly = app.synth();
+    expect(assembly.artifacts.length).toEqual(2);
+    expect(assembly.stacks[0].assets.length).toBe(1);
+    expect(assembly.stacks[0].assets[0].path).toEqual('ProductStack.product.template.json');
+  }),
+
+  test('multiple product versions from product stack', () => {
+    const productStackVersion1 = new servicecatalog.ProductStack(stack, 'ProductStackV1');
+    const productStackVersion2 = new servicecatalog.ProductStack(stack, 'ProductStackV2');
+
+    new sns.Topic(productStackVersion1, 'SNSTopicProductStack1');
+
+    new sns.Topic(productStackVersion2, 'SNSTopicProductStack2', {
+      displayName: 'a test',
+    });
+
+    new servicecatalog.CloudFormationProduct(stack, 'MyProduct', {
+      productName: 'testProduct',
+      owner: 'testOwner',
+      productVersions: [
+        {
+          productVersionName: 'v1',
+          cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(productStackVersion1),
+        },
+        {
+          productVersionName: 'v2',
+          cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(productStackVersion2),
+        },
+      ],
+    });
+
+    const assembly = app.synth();
+
+    expect(assembly.stacks[0].assets.length).toBe(2);
+    expect(assembly.stacks[0].assets[0].path).toEqual('ProductStackV1.product.template.json');
+    expect(assembly.stacks[0].assets[1].path).toEqual('ProductStackV2.product.template.json');
+  }),
+
+  test('identical product versions from product stack creates one asset', () => {
+    class TestProductStack extends servicecatalog.ProductStack {
+      constructor(scope: any, id: string) {
+        super(scope, id);
+
+        new sns.Topic(this, 'TopicProduct');
+      }
+    }
+
+    new servicecatalog.CloudFormationProduct(stack, 'MyProduct', {
+      productName: 'testProduct',
+      owner: 'testOwner',
+      productVersions: [
+        {
+          productVersionName: 'v1',
+          cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new TestProductStack(stack, 'v1')),
+        },
+        {
+          productVersionName: 'v2',
+          cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new TestProductStack(stack, 'v2')),
+        },
+        {
+          productVersionName: 'v3',
+          cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new TestProductStack(stack, 'v3')),
+        },
+      ],
+    });
+
+    const assembly = app.synth();
+
+    expect(assembly.stacks[0].assets.length).toBe(1);
+  }),
+
   test('product test from multiple sources', () => {
     new servicecatalog.CloudFormationProduct(stack, 'MyProduct', {
       productName: 'testProduct',

From 1e2218941af13297b6ddaf02a1d8e07606ed3058 Mon Sep 17 00:00:00 2001
From: Adam Ruka 
Date: Tue, 2 Nov 2021 12:24:16 -0700
Subject: [PATCH 106/148] chore: add the new aws-iot-actions module to the
 assignment GitHub Action  (#17259)

We've created a new module in https://github.com/aws/aws-cdk/pull/17112, so now we need to add it to our assignment GitHub Action.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .github/workflows/issue-label-assign.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.github/workflows/issue-label-assign.yml b/.github/workflows/issue-label-assign.yml
index 3309598c4e5e3..4cc8f06bbbf5e 100644
--- a/.github/workflows/issue-label-assign.yml
+++ b/.github/workflows/issue-label-assign.yml
@@ -126,6 +126,7 @@ jobs:
            {"area":"@aws-cdk/aws-imagebuilder","keywords":["aws-imagebuilder","imagebuilder"],"labels":["@aws-cdk/aws-imagebuilder"],"assignees":["skinny85"]},
            {"area":"@aws-cdk/aws-inspector","keywords":["aws-inspector","inspector"],"labels":["@aws-cdk/aws-inspector"],"assignees":["skinny85"]},
            {"area":"@aws-cdk/aws-iot","keywords":["internet-of-things","aws-iot","iot"],"labels":["@aws-cdk/aws-iot"],"assignees":["skinny85"]},
+           {"area":"@aws-cdk/aws-iot-actions","keywords":["aws-iot-actions","iot-actions",],"labels":["@aws-cdk/aws-iot-actions"],"assignees":["skinny85"]},
            {"area":"@aws-cdk/aws-iot1click","keywords":["aws-iot1click","iot1click"],"labels":["@aws-cdk/aws-iot1click"],"assignees":["skinny85"]},
            {"area":"@aws-cdk/aws-iotanalytics","keywords":["aws-iotanalytics","iotanalytics"],"labels":["@aws-cdk/aws-iotanalytics"],"assignees":["skinny85"]},
            {"area":"@aws-cdk/aws-iotevents","keywords":["aws-iotevents","iotevents"],"labels":["@aws-cdk/aws-iotevents"],"assignees":["skinny85"]},

From a7c869e6d57932389df572cd7f104a4c9ea8f8a5 Mon Sep 17 00:00:00 2001
From: Tatsuya Yamamoto 
Date: Wed, 3 Nov 2021 05:18:35 +0900
Subject: [PATCH 107/148] feat(iot-actions): Add the action to put CloudWatch
 Logs (#17228)

I'm trying to implement aws-iot L2 Constructs.

This PR is one of steps after following PR:
- https://github.com/aws/aws-cdk/pull/16681#issuecomment-942233029

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-iot-actions/README.md   |  18 ++
 .../lib/cloudwatch-logs-action.ts             |  49 +++++
 .../@aws-cdk/aws-iot-actions/lib/index.ts     |   1 +
 .../aws-iot-actions/lib/private/role.ts       |  27 +++
 .../@aws-cdk/aws-iot-actions/package.json     |   2 +
 .../cloudwatch-logs-action.test.ts            | 199 ++++++++++++++++++
 ...integ.cloudwatch-logs-action.expected.json |  92 ++++++++
 .../integ.cloudwatch-logs-action.ts           |  25 +++
 8 files changed, 413 insertions(+)
 create mode 100644 packages/@aws-cdk/aws-iot-actions/lib/cloudwatch-logs-action.ts
 create mode 100644 packages/@aws-cdk/aws-iot-actions/lib/private/role.ts
 create mode 100644 packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/cloudwatch-logs-action.test.ts
 create mode 100644 packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.expected.json
 create mode 100644 packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.ts

diff --git a/packages/@aws-cdk/aws-iot-actions/README.md b/packages/@aws-cdk/aws-iot-actions/README.md
index 67d9b2924dd53..b18182a80a9ad 100644
--- a/packages/@aws-cdk/aws-iot-actions/README.md
+++ b/packages/@aws-cdk/aws-iot-actions/README.md
@@ -48,3 +48,21 @@ new iot.TopicRule(this, 'TopicRule', {
   actions: [new actions.LambdaFunctionAction(func)],
 });
 ```
+
+## Put logs to CloudWatch Logs
+
+The code snippet below creates an AWS IoT Rule that put logs to CloudWatch Logs
+when it is triggered.
+
+```ts
+import * as iot from '@aws-cdk/aws-iot';
+import * as actions from '@aws-cdk/aws-iot-actions';
+import * as logs from '@aws-cdk/aws-logs';
+
+const logGroup = new logs.LogGroup(this, 'MyLogGroup');
+
+new iot.TopicRule(this, 'TopicRule', {
+  sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id FROM 'device/+/data'"),
+  actions: [new actions.CloudWatchLogsAction(logGroup)],
+});
+```
diff --git a/packages/@aws-cdk/aws-iot-actions/lib/cloudwatch-logs-action.ts b/packages/@aws-cdk/aws-iot-actions/lib/cloudwatch-logs-action.ts
new file mode 100644
index 0000000000000..dda14de887774
--- /dev/null
+++ b/packages/@aws-cdk/aws-iot-actions/lib/cloudwatch-logs-action.ts
@@ -0,0 +1,49 @@
+import * as iam from '@aws-cdk/aws-iam';
+import * as iot from '@aws-cdk/aws-iot';
+import * as logs from '@aws-cdk/aws-logs';
+import { singletonActionRole } from './private/role';
+
+/**
+ * Configuration properties of an action for CloudWatch Logs.
+ */
+export interface CloudWatchLogsActionProps {
+  /**
+   * The IAM role that allows access to the CloudWatch log group.
+   *
+   * @default a new role will be created
+   */
+  readonly role?: iam.IRole;
+}
+
+/**
+ * The action to send data to Amazon CloudWatch Logs
+ */
+export class CloudWatchLogsAction implements iot.IAction {
+  private readonly role?: iam.IRole;
+
+  /**
+   * @param logGroup The CloudWatch log group to which the action sends data
+   * @param props Optional properties to not use default
+   */
+  constructor(
+    private readonly logGroup: logs.ILogGroup,
+    props: CloudWatchLogsActionProps = {},
+  ) {
+    this.role = props.role;
+  }
+
+  bind(rule: iot.ITopicRule): iot.ActionConfig {
+    const role = this.role ?? singletonActionRole(rule);
+    this.logGroup.grantWrite(role);
+    this.logGroup.grant(role, 'logs:DescribeLogStreams');
+
+    return {
+      configuration: {
+        cloudwatchLogs: {
+          logGroupName: this.logGroup.logGroupName,
+          roleArn: role.roleArn,
+        },
+      },
+    };
+  }
+}
diff --git a/packages/@aws-cdk/aws-iot-actions/lib/index.ts b/packages/@aws-cdk/aws-iot-actions/lib/index.ts
index 751863744ffe2..ef917fd0e2181 100644
--- a/packages/@aws-cdk/aws-iot-actions/lib/index.ts
+++ b/packages/@aws-cdk/aws-iot-actions/lib/index.ts
@@ -1 +1,2 @@
+export * from './cloudwatch-logs-action';
 export * from './lambda-function-action';
diff --git a/packages/@aws-cdk/aws-iot-actions/lib/private/role.ts b/packages/@aws-cdk/aws-iot-actions/lib/private/role.ts
new file mode 100644
index 0000000000000..78c72b914f56b
--- /dev/null
+++ b/packages/@aws-cdk/aws-iot-actions/lib/private/role.ts
@@ -0,0 +1,27 @@
+import * as iam from '@aws-cdk/aws-iam';
+import { IConstruct, PhysicalName } from '@aws-cdk/core';
+
+// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
+// eslint-disable-next-line no-duplicate-imports, import/order
+import { Construct } from '@aws-cdk/core';
+
+/**
+ * Obtain the Role for the TopicRule
+ *
+ * If a role already exists, it will be returned. This ensures that if a rule have multiple
+ * actions, they will share a role.
+ * @internal
+ */
+export function singletonActionRole(scope: IConstruct): iam.IRole {
+  const id = 'TopicRuleActionRole';
+  const existing = scope.node.tryFindChild(id) as iam.IRole;
+  if (existing) {
+    return existing;
+  };
+
+  const role = new iam.Role(scope as Construct, id, {
+    roleName: PhysicalName.GENERATE_IF_NEEDED,
+    assumedBy: new iam.ServicePrincipal('iot.amazonaws.com'),
+  });
+  return role;
+}
diff --git a/packages/@aws-cdk/aws-iot-actions/package.json b/packages/@aws-cdk/aws-iot-actions/package.json
index 3b66b73a1562e..d60ae4c5e1376 100644
--- a/packages/@aws-cdk/aws-iot-actions/package.json
+++ b/packages/@aws-cdk/aws-iot-actions/package.json
@@ -82,6 +82,7 @@
     "@aws-cdk/aws-iam": "0.0.0",
     "@aws-cdk/aws-iot": "0.0.0",
     "@aws-cdk/aws-lambda": "0.0.0",
+    "@aws-cdk/aws-logs": "0.0.0",
     "@aws-cdk/core": "0.0.0",
     "constructs": "^3.3.69"
   },
@@ -90,6 +91,7 @@
     "@aws-cdk/aws-iam": "0.0.0",
     "@aws-cdk/aws-iot": "0.0.0",
     "@aws-cdk/aws-lambda": "0.0.0",
+    "@aws-cdk/aws-logs": "0.0.0",
     "@aws-cdk/core": "0.0.0",
     "constructs": "^3.3.69"
   },
diff --git a/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/cloudwatch-logs-action.test.ts b/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/cloudwatch-logs-action.test.ts
new file mode 100644
index 0000000000000..4e25f43367c31
--- /dev/null
+++ b/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/cloudwatch-logs-action.test.ts
@@ -0,0 +1,199 @@
+import { Template } from '@aws-cdk/assertions';
+import * as iam from '@aws-cdk/aws-iam';
+import * as iot from '@aws-cdk/aws-iot';
+import * as logs from '@aws-cdk/aws-logs';
+import * as cdk from '@aws-cdk/core';
+import * as actions from '../../lib';
+
+test('Default cloudwatch logs action', () => {
+  // GIVEN
+  const stack = new cdk.Stack();
+  const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
+    sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id FROM 'device/+/data'"),
+  });
+  const logGroup = new logs.LogGroup(stack, 'MyLogGroup');
+
+  // WHEN
+  topicRule.addAction(
+    new actions.CloudWatchLogsAction(logGroup),
+  );
+
+  // THEN
+  Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
+    TopicRulePayload: {
+      Actions: [
+        {
+          CloudwatchLogs: {
+            LogGroupName: { Ref: 'MyLogGroup5C0DAD85' },
+            RoleArn: {
+              'Fn::GetAtt': [
+                'MyTopicRuleTopicRuleActionRoleCE2D05DA',
+                'Arn',
+              ],
+            },
+          },
+        },
+      ],
+    },
+  });
+
+  Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', {
+    AssumeRolePolicyDocument: {
+      Statement: [
+        {
+          Action: 'sts:AssumeRole',
+          Effect: 'Allow',
+          Principal: {
+            Service: 'iot.amazonaws.com',
+          },
+        },
+      ],
+      Version: '2012-10-17',
+    },
+  });
+
+  Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', {
+    PolicyDocument: {
+      Statement: [
+        {
+          Action: ['logs:CreateLogStream', 'logs:PutLogEvents'],
+          Effect: 'Allow',
+          Resource: {
+            'Fn::GetAtt': ['MyLogGroup5C0DAD85', 'Arn'],
+          },
+        },
+        {
+          Action: 'logs:DescribeLogStreams',
+          Effect: 'Allow',
+          Resource: {
+            'Fn::GetAtt': ['MyLogGroup5C0DAD85', 'Arn'],
+          },
+        },
+      ],
+      Version: '2012-10-17',
+    },
+    PolicyName: 'MyTopicRuleTopicRuleActionRoleDefaultPolicy54A701F7',
+    Roles: [
+      { Ref: 'MyTopicRuleTopicRuleActionRoleCE2D05DA' },
+    ],
+  });
+});
+
+test('can set role', () => {
+  // GIVEN
+  const stack = new cdk.Stack();
+  const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
+    sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id FROM 'device/+/data'"),
+  });
+  const logGroup = new logs.LogGroup(stack, 'MyLogGroup');
+  const role = iam.Role.fromRoleArn(stack, 'MyRole', 'arn:aws:iam::123456789012:role/ForTest');
+
+  // WHEN
+  topicRule.addAction(
+    new actions.CloudWatchLogsAction(logGroup, {
+      role,
+    }),
+  );
+
+  // THEN
+  Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
+    TopicRulePayload: {
+      Actions: [
+        {
+          CloudwatchLogs: {
+            LogGroupName: { Ref: 'MyLogGroup5C0DAD85' },
+            RoleArn: 'arn:aws:iam::123456789012:role/ForTest',
+          },
+        },
+      ],
+    },
+  });
+});
+
+test('The specified role is added a policy needed for sending data to logs', () => {
+  // GIVEN
+  const stack = new cdk.Stack();
+  const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
+    sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id FROM 'device/+/data'"),
+  });
+  const logGroup = new logs.LogGroup(stack, 'MyLogGroup');
+  const role = iam.Role.fromRoleArn(stack, 'MyRole', 'arn:aws:iam::123456789012:role/ForTest');
+
+  // WHEN
+  topicRule.addAction(
+    new actions.CloudWatchLogsAction(logGroup, {
+      role,
+    }),
+  );
+
+  // THEN
+  Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', {
+    PolicyDocument: {
+      Statement: [
+        {
+          Action: ['logs:CreateLogStream', 'logs:PutLogEvents'],
+          Effect: 'Allow',
+          Resource: {
+            'Fn::GetAtt': ['MyLogGroup5C0DAD85', 'Arn'],
+          },
+        },
+        {
+          Action: 'logs:DescribeLogStreams',
+          Effect: 'Allow',
+          Resource: {
+            'Fn::GetAtt': ['MyLogGroup5C0DAD85', 'Arn'],
+          },
+        },
+      ],
+      Version: '2012-10-17',
+    },
+    PolicyName: 'MyRolePolicy64AB00A5',
+    Roles: ['ForTest'],
+  });
+});
+
+
+test('When multiple actions are omitted role property, the actions use same one role', () => {
+  // GIVEN
+  // GIVEN
+  const stack = new cdk.Stack();
+  const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
+    sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id FROM 'device/+/data'"),
+  });
+  const logGroup1 = new logs.LogGroup(stack, 'MyLogGroup1');
+  const logGroup2 = new logs.LogGroup(stack, 'MyLogGroup2');
+
+  // WHEN
+  topicRule.addAction(new actions.CloudWatchLogsAction(logGroup1));
+  topicRule.addAction(new actions.CloudWatchLogsAction(logGroup2));
+
+  // THEN
+  Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
+    TopicRulePayload: {
+      Actions: [
+        {
+          CloudwatchLogs: {
+            LogGroupName: { Ref: 'MyLogGroup14A6E382A' },
+            RoleArn: {
+              'Fn::GetAtt': [
+                'MyTopicRuleTopicRuleActionRoleCE2D05DA',
+                'Arn',
+              ],
+            },
+          },
+        },
+        {
+          CloudwatchLogs: {
+            LogGroupName: { Ref: 'MyLogGroup279D6359D' },
+            RoleArn: {
+              'Fn::GetAtt': [
+                'MyTopicRuleTopicRuleActionRoleCE2D05DA',
+                'Arn',
+              ],
+            },
+          },
+        },
+      ],
+    },
+  });
+});
diff --git a/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.expected.json b/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.expected.json
new file mode 100644
index 0000000000000..7d1748a084c77
--- /dev/null
+++ b/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.expected.json
@@ -0,0 +1,92 @@
+{
+  "Resources": {
+    "TopicRule40A4EA44": {
+      "Type": "AWS::IoT::TopicRule",
+      "Properties": {
+        "TopicRulePayload": {
+          "Actions": [
+            {
+              "CloudwatchLogs": {
+                "LogGroupName": {
+                  "Ref": "MyLogGroup5C0DAD85"
+                },
+                "RoleArn": {
+                  "Fn::GetAtt": [
+                    "TopicRuleTopicRuleActionRole246C4F77",
+                    "Arn"
+                  ]
+                }
+              }
+            }
+          ],
+          "AwsIotSqlVersion": "2016-03-23",
+          "Sql": "SELECT topic(2) as device_id FROM 'device/+/data'"
+        }
+      }
+    },
+    "TopicRuleTopicRuleActionRole246C4F77": {
+      "Type": "AWS::IAM::Role",
+      "Properties": {
+        "AssumeRolePolicyDocument": {
+          "Statement": [
+            {
+              "Action": "sts:AssumeRole",
+              "Effect": "Allow",
+              "Principal": {
+                "Service": "iot.amazonaws.com"
+              }
+            }
+          ],
+          "Version": "2012-10-17"
+        }
+      }
+    },
+    "TopicRuleTopicRuleActionRoleDefaultPolicy99ADD687": {
+      "Type": "AWS::IAM::Policy",
+      "Properties": {
+        "PolicyDocument": {
+          "Statement": [
+            {
+              "Action": [
+                "logs:CreateLogStream",
+                "logs:PutLogEvents"
+              ],
+              "Effect": "Allow",
+              "Resource": {
+                "Fn::GetAtt": [
+                  "MyLogGroup5C0DAD85",
+                  "Arn"
+                ]
+              }
+            },
+            {
+              "Action": "logs:DescribeLogStreams",
+              "Effect": "Allow",
+              "Resource": {
+                "Fn::GetAtt": [
+                  "MyLogGroup5C0DAD85",
+                  "Arn"
+                ]
+              }
+            }
+          ],
+          "Version": "2012-10-17"
+        },
+        "PolicyName": "TopicRuleTopicRuleActionRoleDefaultPolicy99ADD687",
+        "Roles": [
+          {
+            "Ref": "TopicRuleTopicRuleActionRole246C4F77"
+          }
+        ]
+      }
+    },
+    "MyLogGroup5C0DAD85": {
+      "Type": "AWS::Logs::LogGroup",
+      "Properties": {
+        "RetentionInDays": 731
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
+    }
+  }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.ts b/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.ts
new file mode 100644
index 0000000000000..802f485b77e37
--- /dev/null
+++ b/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.ts
@@ -0,0 +1,25 @@
+/// !cdk-integ pragma:ignore-assets
+import * as iot from '@aws-cdk/aws-iot';
+import * as logs from '@aws-cdk/aws-logs';
+import * as cdk from '@aws-cdk/core';
+import * as actions from '../../lib';
+
+const app = new cdk.App();
+
+class TestStack extends cdk.Stack {
+  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
+    super(scope, id, props);
+
+    const topicRule = new iot.TopicRule(this, 'TopicRule', {
+      sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id FROM 'device/+/data'"),
+    });
+
+    const logGroup = new logs.LogGroup(this, 'MyLogGroup', {
+      removalPolicy: cdk.RemovalPolicy.DESTROY,
+    });
+    topicRule.addAction(new actions.CloudWatchLogsAction(logGroup));
+  }
+}
+
+new TestStack(app, 'test-stack');
+app.synth();

From ca9320bbc22934a0f708364a6426f3977ea67f5a Mon Sep 17 00:00:00 2001
From: Rico Huijbers 
Date: Tue, 2 Nov 2021 22:14:18 +0100
Subject: [PATCH 108/148] chore: bootstrap stack too old for integ tests
 (#17277)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The integ tests try to be clever to save time, and rebootstrap an
account and region pair only if the bootstrap stack does not exist
yet.

This is not good enough if the **version** of the bootstrap stack
changes though (no rebootstrapping will happen), and the following
error will occur:

```
โŒ  cdktest-0n94n0po827f-test-2 failed: Error: cdktest-0n94n0po827f-test-2: This CDK deployment requires bootstrap stack version '6', found '4'. Please run 'cdk bootstrap'.
```

Instead, always bootstrap every account/region pair at least once
per run. It will take some time, but in most cases we'll be able to
short-circuit the CFN deployment, so it will take ~2s instead of
~20 per case.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/aws-cdk/test/integ/helpers/cdk.ts | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/packages/aws-cdk/test/integ/helpers/cdk.ts b/packages/aws-cdk/test/integ/helpers/cdk.ts
index edf996ba36ed6..340aae771f275 100644
--- a/packages/aws-cdk/test/integ/helpers/cdk.ts
+++ b/packages/aws-cdk/test/integ/helpers/cdk.ts
@@ -541,11 +541,12 @@ let sanityChecked: boolean | undefined;
  * by hand so let's just mass-automate it.
  */
 async function ensureBootstrapped(fixture: TestFixture) {
-  // Use the default name for the bootstrap stack
-  if (await fixture.aws.stackStatus('CDKToolkit') === undefined) {
-    // use whatever version of bootstrap is the default for this particular version of the CLI
-    await fixture.cdk(['bootstrap', `aws://${await fixture.aws.account()}/${fixture.aws.region}`]);
-  }
+  // use whatever version of bootstrap is the default for this particular version of the CLI
+  const envSpecifier = `aws://${await fixture.aws.account()}/${fixture.aws.region}`;
+  if (ALREADY_BOOTSTRAPPED_IN_THIS_RUN.has(envSpecifier)) { return; }
+
+  await fixture.cdk(['bootstrap', envSpecifier]);
+  ALREADY_BOOTSTRAPPED_IN_THIS_RUN.add(envSpecifier);
 }
 
 /**
@@ -689,3 +690,5 @@ const installNpm7 = memoize0(async (): Promise => {
 
   return path.join(installDir, 'node_modules', '.bin', 'npm');
 });
+
+const ALREADY_BOOTSTRAPPED_IN_THIS_RUN = new Set();
\ No newline at end of file

From 30e96da2f185b8e1bc0dcdfeedf45c170d480165 Mon Sep 17 00:00:00 2001
From: Eli Polonsky 
Date: Wed, 3 Nov 2021 02:05:09 +0200
Subject: [PATCH 109/148] chore: integ tests breaking on lambda node runtime
 (#17282)

Looks like lambda stopped supporting node 10 for new functions:

```console
The runtime parameter of nodejs10.x is no longer supported for creating or updating AWS Lambda functions. We recommend you use the new runtime (nodejs14.x) while creating or updating functions
```

Switch to 12.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/aws-cdk/test/integ/cli/app/app.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/aws-cdk/test/integ/cli/app/app.js b/packages/aws-cdk/test/integ/cli/app/app.js
index 450662ac268e0..f0e332eb351fa 100644
--- a/packages/aws-cdk/test/integ/cli/app/app.js
+++ b/packages/aws-cdk/test/integ/cli/app/app.js
@@ -195,7 +195,7 @@ class LambdaStack extends cdk.Stack {
 
     const fn = new lambda.Function(this, 'my-function', {
       code: lambda.Code.asset(path.join(__dirname, 'lambda')),
-      runtime: lambda.Runtime.NODEJS_10_X,
+      runtime: lambda.Runtime.NODEJS_12_X,
       handler: 'index.handler'
     });
 

From 02d53725fa4b7675d65bf8946379033a9cf8df59 Mon Sep 17 00:00:00 2001
From: Rico Huijbers 
Date: Wed, 3 Nov 2021 10:42:24 +0100
Subject: [PATCH 110/148] chore(cli): integ tests install matching framework
 version (#17276)

If the regression tests are running in straight up integ test mode,
and not regression mode, they don't run with a `FRAMEWORK_VERSION` set.

The end result is that they install the version `*` of every library,
which always resolves to the v1 version.

If we're running in straight-up integ test mode, copy the framework
version from the CLI.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/aws-cdk/test/integ/run-against-dist    | 5 +++++
 packages/aws-cdk/test/integ/run-against-release | 7 +++++++
 2 files changed, 12 insertions(+)

diff --git a/packages/aws-cdk/test/integ/run-against-dist b/packages/aws-cdk/test/integ/run-against-dist
index ed17ddee88243..0cd683b112dca 100755
--- a/packages/aws-cdk/test/integ/run-against-dist
+++ b/packages/aws-cdk/test/integ/run-against-dist
@@ -24,6 +24,11 @@ if [[ ! -f $dist_root/build.json ]]; then
 fi
 
 export CANDIDATE_VERSION=$(node -p "require('${dist_root}/build.json').version")
+
+# FRAMEWORK_VERSION is the version that will be 'npm install'ed by the tests
+if [[ "${FRAMEWORK_VERSION}" = "" ]]; then
+  export FRAMEWORK_VERSION=${CANDIDATE_VERSION}
+fi
 export TEST_RUNNER=dist
 
 serve_npm_packages
diff --git a/packages/aws-cdk/test/integ/run-against-release b/packages/aws-cdk/test/integ/run-against-release
index 0865bd331a25d..b3ebe1e4fc409 100755
--- a/packages/aws-cdk/test/integ/run-against-release
+++ b/packages/aws-cdk/test/integ/run-against-release
@@ -13,6 +13,13 @@ mkdir -p $npmws
 
 # Install the CLI and put it on the PATH
 (cd $npmws && npm install aws-cdk)
+
+# FRAMEWORK_VERSION is the version that will be 'npm install'ed by the tests
+if [[ "${FRAMEWORK_VERSION}" = "" ]]; then
+  cli_version=$(cd $npmws && node -p "require('aws-cdk/package.json').version")
+  export FRAMEWORK_VERSION=${cli_version}
+fi
+
 export PATH=$npmws/node_modules/.bin:$PATH
 export TEST_RUNNER=release
 

From 58090a0608a244fa0204974ee659d5c793e85dcc Mon Sep 17 00:00:00 2001
From: Eli Polonsky 
Date: Wed, 3 Nov 2021 13:09:33 +0200
Subject: [PATCH 111/148] chore: regression suite patch for lambda runtime
 deprecation  (#17297)

Follow up on https://github.com/aws/aws-cdk/pull/17282

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../cli-regression-patches/v1.130.0/NOTES.md  |   4 +
 .../v1.130.0/app/app.js                       | 378 ++++++++++++++++++
 2 files changed, 382 insertions(+)
 create mode 100644 packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md
 create mode 100644 packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/app/app.js

diff --git a/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md
new file mode 100644
index 0000000000000..9a9338f4d04fb
--- /dev/null
+++ b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md
@@ -0,0 +1,4 @@
+On november 2nd 2021, lambda started deprecating the nodejs10.x runtime. This meant we can no longer create functions with this runtime.
+Our integration tests use this runtime for one of its stacks.
+
+This patch brings https://github.com/aws/aws-cdk/pull/17282 into the regression suite.
\ No newline at end of file
diff --git a/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/app/app.js b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/app/app.js
new file mode 100644
index 0000000000000..f0e332eb351fa
--- /dev/null
+++ b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/app/app.js
@@ -0,0 +1,378 @@
+const path = require('path');
+
+var constructs = require('constructs');
+if (process.env.PACKAGE_LAYOUT_VERSION === '1') {
+  var cdk = require('@aws-cdk/core');
+  var ec2 = require('@aws-cdk/aws-ec2');
+  var ssm = require('@aws-cdk/aws-ssm');
+  var iam = require('@aws-cdk/aws-iam');
+  var sns = require('@aws-cdk/aws-sns');
+  var lambda = require('@aws-cdk/aws-lambda');
+  var docker = require('@aws-cdk/aws-ecr-assets');
+} else {
+  var cdk = require('aws-cdk-lib');
+  var {
+    aws_ec2: ec2,
+    aws_ssm: ssm,
+    aws_iam: iam,
+    aws_sns: sns,
+    aws_lambda: lambda,
+    aws_ecr_assets: docker
+  } = require('aws-cdk-lib');
+}
+
+const { Annotations } = cdk;
+const { StackWithNestedStack, StackWithNestedStackUsingParameters } = require('./nested-stack');
+
+const stackPrefix = process.env.STACK_NAME_PREFIX;
+if (!stackPrefix) {
+  throw new Error(`the STACK_NAME_PREFIX environment variable is required`);
+}
+
+class MyStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+    new sns.Topic(this, 'topic');
+
+    if (cdk.AvailabilityZoneProvider) { // <= 0.34.0
+      new cdk.AvailabilityZoneProvider(this).availabilityZones;
+    } else if (cdk.Context) { // <= 0.35.0
+      cdk.Context.getAvailabilityZones(this);
+    } else {
+      this.availabilityZones;
+    }
+
+    const parameterName = '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2';
+    getSsmParameterValue(this, parameterName);
+  }
+}
+
+function getSsmParameterValue(scope, parameterName) {
+  return ssm.StringParameter.valueFromLookup(scope, parameterName);
+}
+
+class YourStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+    new sns.Topic(this, 'topic1');
+    new sns.Topic(this, 'topic2');
+  }
+}
+
+class StackUsingContext extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+    new cdk.CfnResource(this, 'Handle', {
+      type: 'AWS::CloudFormation::WaitConditionHandle'
+    });
+
+    new cdk.CfnOutput(this, 'Output', {
+      value: this.availabilityZones,
+    });
+  }
+}
+
+class ParameterStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    new sns.Topic(this, 'TopicParameter', {
+      topicName: new cdk.CfnParameter(this, 'TopicNameParam').valueAsString
+    });
+  }
+}
+
+class OtherParameterStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    new sns.Topic(this, 'TopicParameter', {
+      topicName: new cdk.CfnParameter(this, 'OtherTopicNameParam').valueAsString
+    });
+  }
+}
+
+class MultiParameterStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    new sns.Topic(this, 'TopicParameter', {
+      displayName: new cdk.CfnParameter(this, 'DisplayNameParam').valueAsString
+    });
+    new sns.Topic(this, 'OtherTopicParameter', {
+      displayName: new cdk.CfnParameter(this, 'OtherDisplayNameParam').valueAsString
+    });
+  }
+}
+
+class OutputsStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    const topic =  new sns.Topic(this, 'MyOutput', {
+      topicName: `${cdk.Stack.of(this).stackName}MyTopic`
+    });
+
+    new cdk.CfnOutput(this, 'TopicName', {
+      value: topic.topicName
+    })
+  }
+}
+
+class AnotherOutputsStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    const topic = new sns.Topic(this, 'MyOtherOutput', {
+      topicName: `${cdk.Stack.of(this).stackName}MyOtherTopic`
+    });
+
+    new cdk.CfnOutput(this, 'TopicName', {
+      value: topic.topicName
+    });
+  }
+}
+
+class IamStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    new iam.Role(this, 'SomeRole', {
+      assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com')
+    });
+  }
+}
+
+class ProvidingStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    this.topic = new sns.Topic(this, 'BogusTopic'); // Some filler
+  }
+}
+
+class StackWithError extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    this.topic = new sns.Topic(this, 'BogusTopic'); // Some filler
+    Annotations.of(this).addError('This is an error');
+  }
+}
+
+class StageWithError extends cdk.Stage {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    new StackWithError(this, 'Stack');
+  }
+}
+
+class ConsumingStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    new sns.Topic(this, 'BogusTopic');  // Some filler
+    new cdk.CfnOutput(this, 'IConsumedSomething', { value: props.providingStack.topic.topicArn });
+  }
+}
+
+class MissingSSMParameterStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    const parameterName = constructs.Node.of(this).tryGetContext('test:ssm-parameter-name');
+    if (parameterName) {
+      const param = getSsmParameterValue(this, parameterName);
+      new iam.Role(this, 'PhonyRole', { assumedBy: new iam.AccountPrincipal(param) });
+    }
+  }
+}
+
+class LambdaStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    const fn = new lambda.Function(this, 'my-function', {
+      code: lambda.Code.asset(path.join(__dirname, 'lambda')),
+      runtime: lambda.Runtime.NODEJS_12_X,
+      handler: 'index.handler'
+    });
+
+    new cdk.CfnOutput(this, 'FunctionArn', { value: fn.functionArn });
+  }
+}
+
+class DockerStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    new docker.DockerImageAsset(this, 'image', {
+      directory: path.join(__dirname, 'docker')
+    });
+
+    // Add at least a single resource (WaitConditionHandle), otherwise this stack will never
+    // be deployed (and its assets never built)
+    new cdk.CfnResource(this, 'Handle', {
+      type: 'AWS::CloudFormation::WaitConditionHandle'
+    });
+  }
+}
+
+class DockerStackWithCustomFile extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    new docker.DockerImageAsset(this, 'image', {
+      directory: path.join(__dirname, 'docker'),
+      file: 'Dockerfile.Custom'
+    });
+
+    // Add at least a single resource (WaitConditionHandle), otherwise this stack will never
+    // be deployed (and its assets never built)
+    new cdk.CfnResource(this, 'Handle', {
+      type: 'AWS::CloudFormation::WaitConditionHandle'
+    });
+  }
+}
+
+class FailedStack extends cdk.Stack {
+
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    // fails on 'Property PolicyDocument cannot be empty'.
+    new cdk.CfnResource(this, 'EmptyPolicy', {
+      type: 'AWS::IAM::Policy'
+    })
+
+  }
+
+}
+
+const VPC_TAG_NAME = 'custom-tag';
+const VPC_TAG_VALUE = `${stackPrefix}-bazinga!`;
+
+class DefineVpcStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    const vpc = new ec2.Vpc(this, 'VPC', {
+      maxAzs: 1,
+    })
+    cdk.Aspects.of(vpc).add(new cdk.Tag(VPC_TAG_NAME, VPC_TAG_VALUE));
+  }
+}
+
+class ImportVpcStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    ec2.Vpc.fromLookup(this, 'DefaultVPC', { isDefault: true });
+    ec2.Vpc.fromLookup(this, 'ByTag', { tags: { [VPC_TAG_NAME]: VPC_TAG_VALUE } });
+  }
+}
+
+class ConditionalResourceStack extends cdk.Stack {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    if (!process.env.NO_RESOURCE) {
+      new iam.User(this, 'User');
+    }
+  }
+}
+
+class SomeStage extends cdk.Stage {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    new YourStack(this, 'StackInStage');
+  }
+}
+
+class StageUsingContext extends cdk.Stage {
+  constructor(parent, id, props) {
+    super(parent, id, props);
+
+    new StackUsingContext(this, 'StackInStage');
+  }
+}
+
+const app = new cdk.App();
+
+const defaultEnv = {
+  account: process.env.CDK_DEFAULT_ACCOUNT,
+  region: process.env.CDK_DEFAULT_REGION
+};
+
+// Sometimes we don't want to synthesize all stacks because it will impact the results
+const stackSet = process.env.INTEG_STACK_SET || 'default';
+
+switch (stackSet) {
+  case 'default':
+    // Deploy all does a wildcard ${stackPrefix}-test-*
+    new MyStack(app, `${stackPrefix}-test-1`, { env: defaultEnv });
+    new YourStack(app, `${stackPrefix}-test-2`);
+    // Deploy wildcard with parameters does ${stackPrefix}-param-test-*
+    new ParameterStack(app, `${stackPrefix}-param-test-1`);
+    new OtherParameterStack(app, `${stackPrefix}-param-test-2`);
+    // Deploy stack with multiple parameters
+    new MultiParameterStack(app, `${stackPrefix}-param-test-3`);
+    // Deploy stack with outputs does ${stackPrefix}-outputs-test-*
+    new OutputsStack(app, `${stackPrefix}-outputs-test-1`);
+    new AnotherOutputsStack(app, `${stackPrefix}-outputs-test-2`);
+    // Not included in wildcard
+    new IamStack(app, `${stackPrefix}-iam-test`, { env: defaultEnv });
+    const providing = new ProvidingStack(app, `${stackPrefix}-order-providing`);
+    new ConsumingStack(app, `${stackPrefix}-order-consuming`, { providingStack: providing });
+
+    new MissingSSMParameterStack(app, `${stackPrefix}-missing-ssm-parameter`, { env: defaultEnv });
+
+    new LambdaStack(app, `${stackPrefix}-lambda`);
+    new DockerStack(app, `${stackPrefix}-docker`);
+    new DockerStackWithCustomFile(app, `${stackPrefix}-docker-with-custom-file`);
+    new FailedStack(app, `${stackPrefix}-failed`)
+
+    if (process.env.ENABLE_VPC_TESTING) { // Gating so we don't do context fetching unless that's what we are here for
+      const env = { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION };
+      if (process.env.ENABLE_VPC_TESTING === 'DEFINE')
+        new DefineVpcStack(app, `${stackPrefix}-define-vpc`, { env });
+      if (process.env.ENABLE_VPC_TESTING === 'IMPORT')
+      new ImportVpcStack(app, `${stackPrefix}-import-vpc`, { env });
+    }
+
+    new ConditionalResourceStack(app, `${stackPrefix}-conditional-resource`)
+
+    new StackWithNestedStack(app, `${stackPrefix}-with-nested-stack`);
+    new StackWithNestedStackUsingParameters(app, `${stackPrefix}-with-nested-stack-using-parameters`);
+
+    new YourStack(app, `${stackPrefix}-termination-protection`, {
+      terminationProtection: process.env.TERMINATION_PROTECTION !== 'FALSE' ? true : false,
+    });
+
+    new SomeStage(app, `${stackPrefix}-stage`);
+    break;
+
+  case 'stage-using-context':
+    // Cannot be combined with other test stacks, because we use this to test
+    // that stage context is propagated up and causes synth to fail when combined
+    // with '--no-lookups'.
+
+    // Needs a dummy stack at the top level because the CLI will fail otherwise
+    new YourStack(app, `${stackPrefix}-toplevel`, { env: defaultEnv });
+    new StageUsingContext(app, `${stackPrefix}-stage-using-context`, {
+      env: defaultEnv,
+    });
+    break;
+
+  case 'stage-with-errors':
+    const stage = new StageWithError(app, `${stackPrefix}-stage-with-errors`);
+    stage.synth({ validateOnSynthesis: true });
+    break;
+
+  default:
+    throw new Error(`Unrecognized INTEG_STACK_SET: '${stackSet}'`);
+}
+
+app.synth();

From b98c42eba121c63ea53434326e52954ab3a9d64a Mon Sep 17 00:00:00 2001
From: Rico Huijbers 
Date: Wed, 3 Nov 2021 13:04:24 +0100
Subject: [PATCH 112/148] chore: integ test trying to downgrade bootstrap stack
 (#17298)

This is a follow-up to #17277: we switched to *always* bootstrapping
the environment using the default settings, to automatically upgrade
whenever an upgrade was available.

However, if we run the integ test using a v1 CLI, the default bootstrap
stack will be the legacy bootstrap, and we would actually be trying
to *downgrade* it. Instead, always use the modern bootstrap stack.

Since legacy apps can be deployed to the modern bootstrap stack, this
is not an issue, and if a test actually needs the legacy stack to test
something, it will explicitly try to create a fresh legacy bootstrap
stack.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/aws-cdk/test/integ/helpers/cdk.ts | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/packages/aws-cdk/test/integ/helpers/cdk.ts b/packages/aws-cdk/test/integ/helpers/cdk.ts
index 340aae771f275..12e60efe243f7 100644
--- a/packages/aws-cdk/test/integ/helpers/cdk.ts
+++ b/packages/aws-cdk/test/integ/helpers/cdk.ts
@@ -541,11 +541,21 @@ let sanityChecked: boolean | undefined;
  * by hand so let's just mass-automate it.
  */
 async function ensureBootstrapped(fixture: TestFixture) {
-  // use whatever version of bootstrap is the default for this particular version of the CLI
+  // Always use the modern bootstrap stack, otherwise we may get the error
+  // "refusing to downgrade from version 7 to version 0" when bootstrapping with default
+  // settings using a v1 CLI.
+  //
+  // It doesn't matter for tests: when they want to test something about an actual legacy
+  // bootstrap stack, they'll create a bootstrap stack with a non-default name to test that exact property.
   const envSpecifier = `aws://${await fixture.aws.account()}/${fixture.aws.region}`;
   if (ALREADY_BOOTSTRAPPED_IN_THIS_RUN.has(envSpecifier)) { return; }
 
-  await fixture.cdk(['bootstrap', envSpecifier]);
+  await fixture.cdk(['bootstrap', envSpecifier], {
+    modEnv: {
+      // Even for v1, use new bootstrap
+      CDK_NEW_BOOTSTRAP: '1',
+    },
+  });
   ALREADY_BOOTSTRAPPED_IN_THIS_RUN.add(envSpecifier);
 }
 

From 0a6499d056d8eb14a5aca0a33c43cfee2aa862b2 Mon Sep 17 00:00:00 2001
From: Rico Huijbers 
Date: Wed, 3 Nov 2021 13:58:22 +0100
Subject: [PATCH 113/148] chore: fix invalid JSON in assignment JSON (#17299)

The JSON is currently breaking GitHub actions.

![image](https://user-images.githubusercontent.com/524162/140036931-deccb6eb-9acb-4286-886b-4aabf63aecdb.png)


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .github/workflows/issue-label-assign.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/issue-label-assign.yml b/.github/workflows/issue-label-assign.yml
index 4cc8f06bbbf5e..17b33b8455c95 100644
--- a/.github/workflows/issue-label-assign.yml
+++ b/.github/workflows/issue-label-assign.yml
@@ -126,7 +126,7 @@ jobs:
            {"area":"@aws-cdk/aws-imagebuilder","keywords":["aws-imagebuilder","imagebuilder"],"labels":["@aws-cdk/aws-imagebuilder"],"assignees":["skinny85"]},
            {"area":"@aws-cdk/aws-inspector","keywords":["aws-inspector","inspector"],"labels":["@aws-cdk/aws-inspector"],"assignees":["skinny85"]},
            {"area":"@aws-cdk/aws-iot","keywords":["internet-of-things","aws-iot","iot"],"labels":["@aws-cdk/aws-iot"],"assignees":["skinny85"]},
-           {"area":"@aws-cdk/aws-iot-actions","keywords":["aws-iot-actions","iot-actions",],"labels":["@aws-cdk/aws-iot-actions"],"assignees":["skinny85"]},
+           {"area":"@aws-cdk/aws-iot-actions","keywords":["aws-iot-actions","iot-actions"],"labels":["@aws-cdk/aws-iot-actions"],"assignees":["skinny85"]},
            {"area":"@aws-cdk/aws-iot1click","keywords":["aws-iot1click","iot1click"],"labels":["@aws-cdk/aws-iot1click"],"assignees":["skinny85"]},
            {"area":"@aws-cdk/aws-iotanalytics","keywords":["aws-iotanalytics","iotanalytics"],"labels":["@aws-cdk/aws-iotanalytics"],"assignees":["skinny85"]},
            {"area":"@aws-cdk/aws-iotevents","keywords":["aws-iotevents","iotevents"],"labels":["@aws-cdk/aws-iotevents"],"assignees":["skinny85"]},

From b240201de40055049ff02be7d0b865bd51b9fcad Mon Sep 17 00:00:00 2001
From: AWS CDK Automation
 <43080478+aws-cdk-automation@users.noreply.github.com>
Date: Wed, 3 Nov 2021 19:23:20 +0530
Subject: [PATCH 114/148] chore: npm-check-updates && yarn upgrade (#17294)

Ran npm-check-updates and yarn upgrade to keep the `yarn.lock` file up-to-date.
---
 package.json                                  |  10 +-
 packages/@aws-cdk/app-delivery/package.json   |   2 +-
 .../aws-apigatewayv2-authorizers/package.json |   2 +-
 .../aws-applicationautoscaling/package.json   |   2 +-
 .../aws-autoscaling-common/package.json       |   2 +-
 .../package.json                              |   4 +-
 .../@aws-cdk/aws-cloudformation/package.json  |   2 +-
 .../aws-codepipeline-actions/package.json     |   2 +-
 .../aws-global-table-coordinator/package.json |   2 +-
 packages/@aws-cdk/aws-dynamodb/package.json   |   2 +-
 packages/@aws-cdk/aws-ec2/package.json        |   2 +-
 packages/@aws-cdk/aws-eks/package.json        |   2 +-
 packages/@aws-cdk/aws-iam/package.json        |   2 +-
 .../@aws-cdk/aws-lambda-nodejs/package.json   |   2 +-
 packages/@aws-cdk/aws-lambda/package.json     |   4 +-
 packages/@aws-cdk/aws-logs/package.json       |   4 +-
 .../aws-route53-targets/jest.config.js        |  10 +-
 packages/@aws-cdk/aws-route53/package.json    |   2 +-
 packages/@aws-cdk/aws-s3/package.json         |   2 +-
 packages/@aws-cdk/aws-ses/package.json        |   2 +-
 .../cloud-assembly-schema/package.json        |   2 +-
 .../@aws-cdk/cloudformation-diff/package.json |   2 +-
 packages/@aws-cdk/core/package.json           |   6 +-
 .../@aws-cdk/custom-resources/package.json    |   4 +-
 packages/@aws-cdk/cx-api/package.json         |   2 +-
 .../lib/example-resource.ts                   |   6 +-
 .../test/example-resource.test.ts             |  42 +
 .../rewrite-imports/package.json              |   2 +-
 packages/aws-cdk-migration/package.json       |   2 +-
 packages/aws-cdk/package.json                 |   8 +-
 packages/awslint/package.json                 |   4 +-
 packages/cdk-assets/package.json              |   4 +-
 packages/cdk-dasm/package.json                |   2 +-
 packages/decdk/package.json                   |   4 +-
 .../cdk-build-tools/config/jest.config.js     |   1 +
 tools/@aws-cdk/cdk-build-tools/package.json   |   8 +-
 tools/@aws-cdk/cdk-release/package.json       |   2 +-
 tools/@aws-cdk/cfn2ts/package.json            |   2 +-
 tools/@aws-cdk/eslint-plugin/package.json     |   2 +-
 tools/@aws-cdk/pkglint/package.json           |   4 +-
 tools/@aws-cdk/prlint/package.json            |   4 +-
 tools/@aws-cdk/yarn-cling/package.json        |   2 +-
 yarn.lock                                     | 909 +++++++++---------
 43 files changed, 564 insertions(+), 522 deletions(-)

diff --git a/package.json b/package.json
index 7a521b7db98e1..e0f41dbbeabf1 100644
--- a/package.json
+++ b/package.json
@@ -20,13 +20,13 @@
     "fs-extra": "^9.1.0",
     "graceful-fs": "^4.2.8",
     "jest-junit": "^12.3.0",
-    "jsii-diff": "^1.41.0",
-    "jsii-pacmak": "^1.41.0",
-    "jsii-reflect": "^1.41.0",
-    "jsii-rosetta": "^1.41.0",
+    "jsii-diff": "^1.42.0",
+    "jsii-pacmak": "^1.42.0",
+    "jsii-reflect": "^1.42.0",
+    "jsii-rosetta": "^1.42.0",
     "lerna": "^4.0.0",
     "patch-package": "^6.4.7",
-    "standard-version": "^9.3.1",
+    "standard-version": "^9.3.2",
     "typescript": "~3.9.10"
   },
   "resolutions": {
diff --git a/packages/@aws-cdk/app-delivery/package.json b/packages/@aws-cdk/app-delivery/package.json
index ef9a52c744e36..fe89215e39094 100644
--- a/packages/@aws-cdk/app-delivery/package.json
+++ b/packages/@aws-cdk/app-delivery/package.json
@@ -66,7 +66,7 @@
     "@aws-cdk/cdk-integ-tools": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
     "@types/jest": "^26.0.24",
-    "fast-check": "^2.18.0",
+    "fast-check": "^2.19.0",
     "jest": "^26.6.3"
   },
   "repository": {
diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/package.json b/packages/@aws-cdk/aws-apigatewayv2-authorizers/package.json
index 13c9a7d48efd3..01d8903715957 100644
--- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/package.json
+++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/package.json
@@ -78,7 +78,7 @@
     "@aws-cdk/cdk-build-tools": "0.0.0",
     "@aws-cdk/cdk-integ-tools": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/jest": "^26.0.24"
   },
   "dependencies": {
diff --git a/packages/@aws-cdk/aws-applicationautoscaling/package.json b/packages/@aws-cdk/aws-applicationautoscaling/package.json
index e0fb58dda98e7..64308f0005133 100644
--- a/packages/@aws-cdk/aws-applicationautoscaling/package.json
+++ b/packages/@aws-cdk/aws-applicationautoscaling/package.json
@@ -77,7 +77,7 @@
     "@aws-cdk/cfn2ts": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
     "@types/jest": "^26.0.24",
-    "fast-check": "^2.18.0",
+    "fast-check": "^2.19.0",
     "jest": "^26.6.3"
   },
   "dependencies": {
diff --git a/packages/@aws-cdk/aws-autoscaling-common/package.json b/packages/@aws-cdk/aws-autoscaling-common/package.json
index 2253a1669614f..f12569cbbc76d 100644
--- a/packages/@aws-cdk/aws-autoscaling-common/package.json
+++ b/packages/@aws-cdk/aws-autoscaling-common/package.json
@@ -69,7 +69,7 @@
     "@aws-cdk/cdk-integ-tools": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
     "@types/jest": "^26.0.24",
-    "fast-check": "^2.18.0",
+    "fast-check": "^2.19.0",
     "jest": "^26.6.3"
   },
   "dependencies": {
diff --git a/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package.json b/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package.json
index 6c6198071796b..af5f69aa16046 100644
--- a/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package.json
+++ b/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package.json
@@ -29,7 +29,7 @@
   },
   "license": "Apache-2.0",
   "devDependencies": {
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/sinon": "^9.0.11",
     "@aws-cdk/cdk-build-tools": "0.0.0",
     "aws-sdk": "^2.596.0",
@@ -43,7 +43,7 @@
     "jest": "^26.6.3",
     "lambda-tester": "^3.6.0",
     "sinon": "^9.2.4",
-    "nock": "^13.1.3",
+    "nock": "^13.1.4",
     "ts-jest": "^26.5.6"
   }
 }
diff --git a/packages/@aws-cdk/aws-cloudformation/package.json b/packages/@aws-cdk/aws-cloudformation/package.json
index 3a8c455bf4557..39e73c2be2948 100644
--- a/packages/@aws-cdk/aws-cloudformation/package.json
+++ b/packages/@aws-cdk/aws-cloudformation/package.json
@@ -79,7 +79,7 @@
     "@aws-cdk/cdk-integ-tools": "0.0.0",
     "@aws-cdk/cfn2ts": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/jest": "^26.0.24",
     "jest": "^26.6.3"
   },
diff --git a/packages/@aws-cdk/aws-codepipeline-actions/package.json b/packages/@aws-cdk/aws-codepipeline-actions/package.json
index 6f08ecc470c28..bfc1de1719831 100644
--- a/packages/@aws-cdk/aws-codepipeline-actions/package.json
+++ b/packages/@aws-cdk/aws-codepipeline-actions/package.json
@@ -76,7 +76,7 @@
     "@aws-cdk/cx-api": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
     "@types/jest": "^26.0.24",
-    "@types/lodash": "^4.14.175",
+    "@types/lodash": "^4.14.176",
     "jest": "^26.6.3",
     "lodash": "^4.17.21"
   },
diff --git a/packages/@aws-cdk/aws-dynamodb-global/lambda-packages/aws-global-table-coordinator/package.json b/packages/@aws-cdk/aws-dynamodb-global/lambda-packages/aws-global-table-coordinator/package.json
index 8e4e5cd1e6ff8..ee17747324574 100644
--- a/packages/@aws-cdk/aws-dynamodb-global/lambda-packages/aws-global-table-coordinator/package.json
+++ b/packages/@aws-cdk/aws-dynamodb-global/lambda-packages/aws-global-table-coordinator/package.json
@@ -39,6 +39,6 @@
     "eslint-plugin-standard": "^4.1.0",
     "jest": "^26.6.3",
     "lambda-tester": "^3.6.0",
-    "nock": "^13.1.3"
+    "nock": "^13.1.4"
   }
 }
diff --git a/packages/@aws-cdk/aws-dynamodb/package.json b/packages/@aws-cdk/aws-dynamodb/package.json
index ba59f3f99b223..8fb374922fa25 100644
--- a/packages/@aws-cdk/aws-dynamodb/package.json
+++ b/packages/@aws-cdk/aws-dynamodb/package.json
@@ -77,7 +77,7 @@
     "@aws-cdk/cdk-integ-tools": "0.0.0",
     "@aws-cdk/cfn2ts": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/jest": "^26.0.24",
     "@types/sinon": "^9.0.11",
     "aws-sdk": "^2.848.0",
diff --git a/packages/@aws-cdk/aws-ec2/package.json b/packages/@aws-cdk/aws-ec2/package.json
index 6cf7d368e25a2..8eaa9d1e5d64a 100644
--- a/packages/@aws-cdk/aws-ec2/package.json
+++ b/packages/@aws-cdk/aws-ec2/package.json
@@ -79,7 +79,7 @@
     "@aws-cdk/cloud-assembly-schema": "0.0.0",
     "@aws-cdk/cx-api": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/jest": "^26.0.24",
     "jest": "^26.6.3"
   },
diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json
index 7864034ff146b..e5c7869f9bc13 100644
--- a/packages/@aws-cdk/aws-eks/package.json
+++ b/packages/@aws-cdk/aws-eks/package.json
@@ -77,7 +77,7 @@
     "@aws-cdk/cdk-integ-tools": "0.0.0",
     "@aws-cdk/cfn2ts": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/jest": "^26.0.24",
     "@types/sinon": "^9.0.11",
     "@types/yaml": "1.9.6",
diff --git a/packages/@aws-cdk/aws-iam/package.json b/packages/@aws-cdk/aws-iam/package.json
index 0e951bb0cdf2c..338e97338adfa 100644
--- a/packages/@aws-cdk/aws-iam/package.json
+++ b/packages/@aws-cdk/aws-iam/package.json
@@ -77,7 +77,7 @@
     "@aws-cdk/cdk-integ-tools": "0.0.0",
     "@aws-cdk/cfn2ts": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/jest": "^26.0.24",
     "@types/sinon": "^9.0.11",
     "jest": "^26.6.3",
diff --git a/packages/@aws-cdk/aws-lambda-nodejs/package.json b/packages/@aws-cdk/aws-lambda-nodejs/package.json
index 185aeed69b3ec..fc627ab9e0227 100644
--- a/packages/@aws-cdk/aws-lambda-nodejs/package.json
+++ b/packages/@aws-cdk/aws-lambda-nodejs/package.json
@@ -71,7 +71,7 @@
     "@aws-cdk/pkglint": "0.0.0",
     "@types/jest": "^26.0.24",
     "delay": "5.0.0",
-    "esbuild": "^0.13.5"
+    "esbuild": "^0.13.12"
   },
   "dependencies": {
     "@aws-cdk/aws-lambda": "0.0.0",
diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json
index f139f180e7420..1a4baf8ea0d80 100644
--- a/packages/@aws-cdk/aws-lambda/package.json
+++ b/packages/@aws-cdk/aws-lambda/package.json
@@ -82,9 +82,9 @@
     "@aws-cdk/cfn2ts": "0.0.0",
     "@aws-cdk/cfnspec": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/jest": "^26.0.24",
-    "@types/lodash": "^4.14.175",
+    "@types/lodash": "^4.14.176",
     "jest": "^26.6.3",
     "lodash": "^4.17.21"
   },
diff --git a/packages/@aws-cdk/aws-logs/package.json b/packages/@aws-cdk/aws-logs/package.json
index a21e787888c1c..fa78fe76b2c9f 100644
--- a/packages/@aws-cdk/aws-logs/package.json
+++ b/packages/@aws-cdk/aws-logs/package.json
@@ -77,13 +77,13 @@
     "@aws-cdk/cdk-integ-tools": "0.0.0",
     "@aws-cdk/cfn2ts": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/jest": "^26.0.24",
     "@types/sinon": "^9.0.11",
     "aws-sdk": "^2.848.0",
     "aws-sdk-mock": "^5.4.0",
     "jest": "^26.6.3",
-    "nock": "^13.1.3",
+    "nock": "^13.1.4",
     "sinon": "^9.2.4"
   },
   "dependencies": {
diff --git a/packages/@aws-cdk/aws-route53-targets/jest.config.js b/packages/@aws-cdk/aws-route53-targets/jest.config.js
index 3a2fd93a1228a..53d601eeeff94 100644
--- a/packages/@aws-cdk/aws-route53-targets/jest.config.js
+++ b/packages/@aws-cdk/aws-route53-targets/jest.config.js
@@ -1,2 +1,10 @@
 const baseConfig = require('@aws-cdk/cdk-build-tools/config/jest.config');
-module.exports = baseConfig;
+module.exports = {
+  ...baseConfig,
+  coverageThreshold: {
+    global: {
+      branches: 70,
+      statements: 80,
+    }
+  }
+};
diff --git a/packages/@aws-cdk/aws-route53/package.json b/packages/@aws-cdk/aws-route53/package.json
index 2fc93edef1b21..9354619e6db4e 100644
--- a/packages/@aws-cdk/aws-route53/package.json
+++ b/packages/@aws-cdk/aws-route53/package.json
@@ -77,7 +77,7 @@
     "@aws-cdk/cdk-integ-tools": "0.0.0",
     "@aws-cdk/cfn2ts": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/jest": "^26.0.24",
     "aws-sdk": "^2.848.0",
     "jest": "^26.6.3"
diff --git a/packages/@aws-cdk/aws-s3/package.json b/packages/@aws-cdk/aws-s3/package.json
index 3117d2919f6a6..afb95aeaa0d2e 100644
--- a/packages/@aws-cdk/aws-s3/package.json
+++ b/packages/@aws-cdk/aws-s3/package.json
@@ -77,7 +77,7 @@
     "@aws-cdk/cdk-integ-tools": "0.0.0",
     "@aws-cdk/cfn2ts": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/jest": "^26.0.24",
     "jest": "^26.6.3"
   },
diff --git a/packages/@aws-cdk/aws-ses/package.json b/packages/@aws-cdk/aws-ses/package.json
index a2a797e38b8cb..492108f1f04d9 100644
--- a/packages/@aws-cdk/aws-ses/package.json
+++ b/packages/@aws-cdk/aws-ses/package.json
@@ -77,7 +77,7 @@
     "@aws-cdk/cdk-integ-tools": "0.0.0",
     "@aws-cdk/cfn2ts": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/jest": "^26.0.24",
     "jest": "^26.6.3"
   },
diff --git a/packages/@aws-cdk/cloud-assembly-schema/package.json b/packages/@aws-cdk/cloud-assembly-schema/package.json
index 11226b0f1521a..06499db17d01e 100644
--- a/packages/@aws-cdk/cloud-assembly-schema/package.json
+++ b/packages/@aws-cdk/cloud-assembly-schema/package.json
@@ -64,7 +64,7 @@
     "@aws-cdk/pkglint": "0.0.0",
     "@types/jest": "^26.0.24",
     "@types/mock-fs": "^4.13.1",
-    "@types/semver": "^7.3.8",
+    "@types/semver": "^7.3.9",
     "jest": "^26.6.3",
     "mock-fs": "^4.14.0",
     "typescript-json-schema": "^0.51.0"
diff --git a/packages/@aws-cdk/cloudformation-diff/package.json b/packages/@aws-cdk/cloudformation-diff/package.json
index 3a3ad220ff70f..d101afe2b69d2 100644
--- a/packages/@aws-cdk/cloudformation-diff/package.json
+++ b/packages/@aws-cdk/cloudformation-diff/package.json
@@ -36,7 +36,7 @@
     "@aws-cdk/pkglint": "0.0.0",
     "@types/jest": "^26.0.24",
     "@types/string-width": "^4.0.1",
-    "fast-check": "^2.18.0",
+    "fast-check": "^2.19.0",
     "jest": "^26.6.3",
     "ts-jest": "^26.5.6"
   },
diff --git a/packages/@aws-cdk/core/package.json b/packages/@aws-cdk/core/package.json
index f7cd653ca7e7f..45e4232abb477 100644
--- a/packages/@aws-cdk/core/package.json
+++ b/packages/@aws-cdk/core/package.json
@@ -171,14 +171,14 @@
     "@aws-cdk/cdk-build-tools": "0.0.0",
     "@aws-cdk/cfn2ts": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/fs-extra": "^8.1.2",
     "@types/jest": "^26.0.24",
-    "@types/lodash": "^4.14.175",
+    "@types/lodash": "^4.14.176",
     "@types/minimatch": "^3.0.5",
     "@types/node": "^10.17.60",
     "@types/sinon": "^9.0.11",
-    "fast-check": "^2.18.0",
+    "fast-check": "^2.19.0",
     "jest": "^26.6.3",
     "lodash": "^4.17.21",
     "sinon": "^9.2.4",
diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json
index 698596d6ae0c0..f30e67b0a5838 100644
--- a/packages/@aws-cdk/custom-resources/package.json
+++ b/packages/@aws-cdk/custom-resources/package.json
@@ -80,14 +80,14 @@
     "@aws-cdk/cdk-integ-tools": "0.0.0",
     "@aws-cdk/cfn2ts": "0.0.0",
     "@aws-cdk/pkglint": "0.0.0",
-    "@types/aws-lambda": "^8.10.84",
+    "@types/aws-lambda": "^8.10.85",
     "@types/fs-extra": "^8.1.2",
     "@types/jest": "^26.0.24",
     "@types/sinon": "^9.0.11",
     "aws-sdk": "^2.848.0",
     "aws-sdk-mock": "^5.4.0",
     "fs-extra": "^9.1.0",
-    "nock": "^13.1.3",
+    "nock": "^13.1.4",
     "sinon": "^9.2.4"
   },
   "dependencies": {
diff --git a/packages/@aws-cdk/cx-api/package.json b/packages/@aws-cdk/cx-api/package.json
index 0a92e1c3492b6..6ed3341b1a082 100644
--- a/packages/@aws-cdk/cx-api/package.json
+++ b/packages/@aws-cdk/cx-api/package.json
@@ -70,7 +70,7 @@
     "@aws-cdk/pkglint": "0.0.0",
     "@types/jest": "^26.0.24",
     "@types/mock-fs": "^4.13.1",
-    "@types/semver": "^7.3.8",
+    "@types/semver": "^7.3.9",
     "jest": "^26.6.3",
     "mock-fs": "^4.14.0"
   },
diff --git a/packages/@aws-cdk/example-construct-library/lib/example-resource.ts b/packages/@aws-cdk/example-construct-library/lib/example-resource.ts
index 6c4630dab6ae4..3c514d01ba19c 100644
--- a/packages/@aws-cdk/example-construct-library/lib/example-resource.ts
+++ b/packages/@aws-cdk/example-construct-library/lib/example-resource.ts
@@ -137,7 +137,7 @@ export interface IExampleResource extends
    * The details of which metric methods you should have of course depends on the
    * resource that is being modeled.
    */
-  metricCount(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric;
+  metricCount(props?: cloudwatch.MetricOptions): cloudwatch.Metric;
 }
 
 /**
@@ -212,12 +212,12 @@ abstract class ExampleResourceBase extends core.Resource implements IExampleReso
   }
 
   /** Implement the {@link IExampleResource.metricCount} method. */
-  public metricCount(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric {
+  public metricCount(props?: cloudwatch.MetricOptions): cloudwatch.Metric {
     return new cloudwatch.Metric({
       // of course, you would put your resource-specific values here
       namespace: 'AWS/ExampleResource',
+      metricName: 'Count',
       dimensions: { ExampleResource: this.exampleResourceName },
-      metricName,
       ...props,
     }).attachTo(this);
   }
diff --git a/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts b/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts
index db1e8d68d4830..7ef95e9a6e671 100644
--- a/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts
+++ b/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts
@@ -6,9 +6,11 @@
 
 import { Match, Template } from '@aws-cdk/assertions';
 
+import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
 import * as ec2 from '@aws-cdk/aws-ec2';
 import * as iam from '@aws-cdk/aws-iam';
 import * as core from '@aws-cdk/core';
+
 // Always import the module you're testing qualified -
 // don't import individual classes from it!
 // Importing it qualified tests whether everything that needs to be exported
@@ -18,6 +20,12 @@ import * as er from '../lib';
 /* We allow quotes in the object keys used for CloudFormation template assertions */
 /* eslint-disable quote-props */
 
+const EXAMPLE_RESOURCE_NAME = {
+  'Fn::Select': [1, {
+    'Fn::Split': ['/', { 'Ref': 'ExampleResourceAC53F4AE' }],
+  }],
+};
+
 describe('Example Resource', () => {
   let stack: core.Stack;
 
@@ -111,6 +119,40 @@ describe('Example Resource', () => {
         },
       });
     });
+
+    test('onEvent adds an Event Rule', () => {
+      exampleResource.onEvent('MyEvent');
+
+      Template.fromStack(stack).hasResourceProperties('AWS::Events::Rule', {
+        EventPattern: {
+          detail: {
+            'example-resource-name': [EXAMPLE_RESOURCE_NAME],
+          },
+        },
+      });
+    });
+
+    test('metricCount returns a metric with correct dimensions', () => {
+      const countMetric = exampleResource.metricCount();
+
+      new cloudwatch.Alarm(stack, 'Alarm', {
+        metric: countMetric,
+        threshold: 10,
+        evaluationPeriods: 2,
+      });
+
+      Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', {
+        EvaluationPeriods: 2,
+        Dimensions: [
+          {
+            Name: 'ExampleResource',
+            Value: EXAMPLE_RESOURCE_NAME,
+          },
+        ],
+        MetricName: 'Count',
+        Namespace: 'AWS/ExampleResource',
+      });
+    });
   });
 
   describe('created with a VPC', () => {
diff --git a/packages/@monocdk-experiment/rewrite-imports/package.json b/packages/@monocdk-experiment/rewrite-imports/package.json
index 7f602376d551a..3142c44c79526 100644
--- a/packages/@monocdk-experiment/rewrite-imports/package.json
+++ b/packages/@monocdk-experiment/rewrite-imports/package.json
@@ -35,7 +35,7 @@
     "typescript": "~3.9.10"
   },
   "devDependencies": {
-    "@types/glob": "^7.1.4",
+    "@types/glob": "^7.2.0",
     "@types/jest": "^26.0.24",
     "@types/node": "^10.17.60",
     "@aws-cdk/cdk-build-tools": "0.0.0",
diff --git a/packages/aws-cdk-migration/package.json b/packages/aws-cdk-migration/package.json
index 1ce16c5670458..34a387cadab5f 100644
--- a/packages/aws-cdk-migration/package.json
+++ b/packages/aws-cdk-migration/package.json
@@ -38,7 +38,7 @@
     "typescript": "~3.9.10"
   },
   "devDependencies": {
-    "@types/glob": "^7.1.4",
+    "@types/glob": "^7.2.0",
     "@types/jest": "^26.0.24",
     "@types/node": "^10.17.60",
     "@aws-cdk/cdk-build-tools": "0.0.0",
diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json
index 4492f92549b45..c71dddbf206f4 100644
--- a/packages/aws-cdk/package.json
+++ b/packages/aws-cdk/package.json
@@ -41,13 +41,13 @@
     "@octokit/rest": "^18.12.0",
     "@types/archiver": "^5.3.0",
     "@types/fs-extra": "^8.1.2",
-    "@types/glob": "^7.1.4",
+    "@types/glob": "^7.2.0",
     "@types/jest": "^26.0.24",
     "@types/minimatch": "^3.0.5",
     "@types/mockery": "^1.4.30",
     "@types/node": "^10.17.60",
     "@types/promptly": "^3.0.2",
-    "@types/semver": "^7.3.8",
+    "@types/semver": "^7.3.9",
     "@types/sinon": "^9.0.11",
     "@types/table": "^6.0.0",
     "@types/uuid": "^8.3.1",
@@ -59,7 +59,7 @@
     "jest": "^26.6.3",
     "make-runnable": "^1.3.10",
     "mockery": "^2.1.0",
-    "nock": "^13.1.3",
+    "nock": "^13.1.4",
     "@aws-cdk/pkglint": "0.0.0",
     "sinon": "^9.2.4",
     "ts-jest": "^26.5.6",
@@ -71,7 +71,7 @@
     "@aws-cdk/cloudformation-diff": "0.0.0",
     "@aws-cdk/cx-api": "0.0.0",
     "@aws-cdk/region-info": "0.0.0",
-    "@jsii/check-node": "1.40.0",
+    "@jsii/check-node": "1.42.0",
     "archiver": "^5.3.0",
     "aws-sdk": "^2.979.0",
     "camelcase": "^6.2.0",
diff --git a/packages/awslint/package.json b/packages/awslint/package.json
index df07c732685ef..626809090c391 100644
--- a/packages/awslint/package.json
+++ b/packages/awslint/package.json
@@ -18,11 +18,11 @@
     "awslint": "bin/awslint"
   },
   "dependencies": {
-    "@jsii/spec": "^1.41.0",
+    "@jsii/spec": "^1.42.0",
     "camelcase": "^6.2.0",
     "colors": "^1.4.0",
     "fs-extra": "^9.1.0",
-    "jsii-reflect": "^1.41.0",
+    "jsii-reflect": "^1.42.0",
     "yargs": "^16.2.0"
   },
   "devDependencies": {
diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json
index e5572280b04df..d594eccfc0e02 100644
--- a/packages/cdk-assets/package.json
+++ b/packages/cdk-assets/package.json
@@ -31,7 +31,7 @@
   "license": "Apache-2.0",
   "devDependencies": {
     "@types/archiver": "^5.3.0",
-    "@types/glob": "^7.1.4",
+    "@types/glob": "^7.2.0",
     "@types/jest": "^26.0.24",
     "@types/mime": "^2.0.3",
     "@types/mock-fs": "^4.13.1",
@@ -49,7 +49,7 @@
     "archiver": "^5.3.0",
     "aws-sdk": "^2.848.0",
     "glob": "^7.2.0",
-    "mime": "^2.5.2",
+    "mime": "^2.6.0",
     "yargs": "^16.2.0"
   },
   "repository": {
diff --git a/packages/cdk-dasm/package.json b/packages/cdk-dasm/package.json
index c7147f7e5b4a5..6589159649794 100644
--- a/packages/cdk-dasm/package.json
+++ b/packages/cdk-dasm/package.json
@@ -28,7 +28,7 @@
   },
   "license": "Apache-2.0",
   "dependencies": {
-    "codemaker": "^1.39.0",
+    "codemaker": "^1.42.0",
     "yaml": "1.10.2"
   },
   "devDependencies": {
diff --git a/packages/decdk/package.json b/packages/decdk/package.json
index 7ebd9cc3d632c..3d181528f325e 100644
--- a/packages/decdk/package.json
+++ b/packages/decdk/package.json
@@ -244,7 +244,7 @@
     "@aws-cdk/region-info": "0.0.0",
     "constructs": "^3.3.69",
     "fs-extra": "^9.1.0",
-    "jsii-reflect": "^1.41.0",
+    "jsii-reflect": "^1.42.0",
     "jsonschema": "^1.4.0",
     "yaml": "1.10.2",
     "yargs": "^16.2.0"
@@ -255,7 +255,7 @@
     "@types/yaml": "1.9.7",
     "@types/yargs": "^15.0.14",
     "jest": "^26.6.3",
-    "jsii": "^1.41.0"
+    "jsii": "^1.42.0"
   },
   "keywords": [
     "aws",
diff --git a/tools/@aws-cdk/cdk-build-tools/config/jest.config.js b/tools/@aws-cdk/cdk-build-tools/config/jest.config.js
index b8e056af3c8a3..367fff38462a4 100644
--- a/tools/@aws-cdk/cdk-build-tools/config/jest.config.js
+++ b/tools/@aws-cdk/cdk-build-tools/config/jest.config.js
@@ -21,6 +21,7 @@ module.exports = {
     coveragePathIgnorePatterns: [
         "/lib/.*\\.generated\\.[jt]s",
         "/test/.*\\.[jt]s",
+        "/.*\\.jsii\\.js",
     ],
 	reporters: [
         "default",
diff --git a/tools/@aws-cdk/cdk-build-tools/package.json b/tools/@aws-cdk/cdk-build-tools/package.json
index a99a32059c006..5e2015222bc13 100644
--- a/tools/@aws-cdk/cdk-build-tools/package.json
+++ b/tools/@aws-cdk/cdk-build-tools/package.json
@@ -38,7 +38,7 @@
     "@aws-cdk/pkglint": "0.0.0",
     "@types/fs-extra": "^8.1.2",
     "@types/jest": "^26.0.24",
-    "@types/semver": "^7.3.8",
+    "@types/semver": "^7.3.9",
     "@types/yargs": "^15.0.14"
   },
   "dependencies": {
@@ -56,9 +56,9 @@
     "fs-extra": "^9.1.0",
     "jest": "^27.3.1",
     "jest-junit": "^11.1.0",
-    "jsii": "^1.41.0",
-    "jsii-pacmak": "^1.41.0",
-    "jsii-reflect": "^1.41.0",
+    "jsii": "^1.42.0",
+    "jsii-pacmak": "^1.42.0",
+    "jsii-reflect": "^1.42.0",
     "markdownlint-cli": "^0.29.0",
     "nyc": "^15.1.0",
     "semver": "^7.3.5",
diff --git a/tools/@aws-cdk/cdk-release/package.json b/tools/@aws-cdk/cdk-release/package.json
index ed0b5705e94df..26b5d08f9764e 100644
--- a/tools/@aws-cdk/cdk-release/package.json
+++ b/tools/@aws-cdk/cdk-release/package.json
@@ -43,7 +43,7 @@
     "conventional-changelog-config-spec": "^2.1.0",
     "conventional-changelog-preset-loader": "^2.3.4",
     "conventional-changelog-writer": "^4.1.0",
-    "conventional-commits-parser": "^3.2.2",
+    "conventional-commits-parser": "^3.2.3",
     "detect-indent": "^6.1.0",
     "detect-newline": "^3.1.0",
     "fs-extra": "^9.1.0",
diff --git a/tools/@aws-cdk/cfn2ts/package.json b/tools/@aws-cdk/cfn2ts/package.json
index dbb024e64cb32..8b484144ee4f8 100644
--- a/tools/@aws-cdk/cfn2ts/package.json
+++ b/tools/@aws-cdk/cfn2ts/package.json
@@ -32,7 +32,7 @@
   "license": "Apache-2.0",
   "dependencies": {
     "@aws-cdk/cfnspec": "0.0.0",
-    "codemaker": "^1.39.0",
+    "codemaker": "^1.42.0",
     "fast-json-patch": "^3.1.0",
     "fs-extra": "^9.1.0",
     "yargs": "^16.2.0"
diff --git a/tools/@aws-cdk/eslint-plugin/package.json b/tools/@aws-cdk/eslint-plugin/package.json
index 87c004f94d846..19b0e287247d2 100644
--- a/tools/@aws-cdk/eslint-plugin/package.json
+++ b/tools/@aws-cdk/eslint-plugin/package.json
@@ -14,7 +14,7 @@
     "build+extract": "npm run build"
   },
   "devDependencies": {
-    "@types/eslint": "^7.28.1",
+    "@types/eslint": "^7.28.2",
     "@types/fs-extra": "^8.1.2",
     "@types/jest": "^26.0.24",
     "@types/node": "^10.17.60",
diff --git a/tools/@aws-cdk/pkglint/package.json b/tools/@aws-cdk/pkglint/package.json
index 72283bad492b2..463b2b96c3e5e 100644
--- a/tools/@aws-cdk/pkglint/package.json
+++ b/tools/@aws-cdk/pkglint/package.json
@@ -39,9 +39,9 @@
   "devDependencies": {
     "@aws-cdk/eslint-plugin": "0.0.0",
     "@types/fs-extra": "^8.1.2",
-    "@types/glob": "^7.1.4",
+    "@types/glob": "^7.2.0",
     "@types/jest": "^26.0.24",
-    "@types/semver": "^7.3.8",
+    "@types/semver": "^7.3.9",
     "@types/yargs": "^15.0.14",
     "@typescript-eslint/eslint-plugin": "^4.33.0",
     "@typescript-eslint/parser": "^4.33.0",
diff --git a/tools/@aws-cdk/prlint/package.json b/tools/@aws-cdk/prlint/package.json
index 1c45caf95233d..c85296b6a292a 100644
--- a/tools/@aws-cdk/prlint/package.json
+++ b/tools/@aws-cdk/prlint/package.json
@@ -13,14 +13,14 @@
   "dependencies": {
     "@actions/core": "^1.6.0",
     "@actions/github": "^2.2.0",
-    "conventional-commits-parser": "^3.2.2",
+    "conventional-commits-parser": "^3.2.3",
     "fs-extra": "^9.1.0",
     "github-api": "^3.4.0",
     "glob": "^7.2.0"
   },
   "devDependencies": {
     "@types/fs-extra": "^9.0.13",
-    "@types/glob": "^7.1.4",
+    "@types/glob": "^7.2.0",
     "@types/jest": "^26.0.24",
     "jest": "^26.6.3",
     "make-runnable": "^1.3.10",
diff --git a/tools/@aws-cdk/yarn-cling/package.json b/tools/@aws-cdk/yarn-cling/package.json
index b8c930eb66867..036cf5377eac2 100644
--- a/tools/@aws-cdk/yarn-cling/package.json
+++ b/tools/@aws-cdk/yarn-cling/package.json
@@ -40,7 +40,7 @@
     "@aws-cdk/pkglint": "0.0.0",
     "@types/jest": "^26.0.24",
     "@types/node": "^10.17.60",
-    "@types/semver": "^7.3.8",
+    "@types/semver": "^7.3.9",
     "@types/yarnpkg__lockfile": "^1.1.5",
     "jest": "^26.6.3",
     "typescript": "~3.9.10"
diff --git a/yarn.lock b/yarn.lock
index 48ecde5d6ee28..88df4ad3d4edb 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -32,32 +32,32 @@
   dependencies:
     "@babel/highlight" "^7.10.4"
 
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.15.8":
-  version "7.15.8"
-  resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz#45990c47adadb00c03677baa89221f7cc23d2503"
-  integrity sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==
-  dependencies:
-    "@babel/highlight" "^7.14.5"
-
-"@babel/compat-data@^7.15.0":
-  version "7.15.0"
-  resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176"
-  integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==
-
-"@babel/core@^7.1.0", "@babel/core@^7.7.2", "@babel/core@^7.7.5":
-  version "7.15.8"
-  resolved "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz#195b9f2bffe995d2c6c159e72fe525b4114e8c10"
-  integrity sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==
-  dependencies:
-    "@babel/code-frame" "^7.15.8"
-    "@babel/generator" "^7.15.8"
-    "@babel/helper-compilation-targets" "^7.15.4"
-    "@babel/helper-module-transforms" "^7.15.8"
-    "@babel/helpers" "^7.15.4"
-    "@babel/parser" "^7.15.8"
-    "@babel/template" "^7.15.4"
-    "@babel/traverse" "^7.15.4"
-    "@babel/types" "^7.15.6"
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431"
+  integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==
+  dependencies:
+    "@babel/highlight" "^7.16.0"
+
+"@babel/compat-data@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.0.tgz#ea269d7f78deb3a7826c39a4048eecda541ebdaa"
+  integrity sha512-DGjt2QZse5SGd9nfOSqO4WLJ8NN/oHkijbXbPrxuoJO3oIPJL3TciZs9FX+cOHNiY9E9l0opL8g7BmLe3T+9ew==
+
+"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.7.5":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/core/-/core-7.16.0.tgz#c4ff44046f5fe310525cc9eb4ef5147f0c5374d4"
+  integrity sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==
+  dependencies:
+    "@babel/code-frame" "^7.16.0"
+    "@babel/generator" "^7.16.0"
+    "@babel/helper-compilation-targets" "^7.16.0"
+    "@babel/helper-module-transforms" "^7.16.0"
+    "@babel/helpers" "^7.16.0"
+    "@babel/parser" "^7.16.0"
+    "@babel/template" "^7.16.0"
+    "@babel/traverse" "^7.16.0"
+    "@babel/types" "^7.16.0"
     convert-source-map "^1.7.0"
     debug "^4.1.0"
     gensync "^1.0.0-beta.2"
@@ -65,113 +65,113 @@
     semver "^6.3.0"
     source-map "^0.5.0"
 
-"@babel/generator@^7.15.4", "@babel/generator@^7.15.8", "@babel/generator@^7.7.2":
-  version "7.15.8"
-  resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz#fa56be6b596952ceb231048cf84ee499a19c0cd1"
-  integrity sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==
+"@babel/generator@^7.16.0", "@babel/generator@^7.7.2":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2"
+  integrity sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==
   dependencies:
-    "@babel/types" "^7.15.6"
+    "@babel/types" "^7.16.0"
     jsesc "^2.5.1"
     source-map "^0.5.0"
 
-"@babel/helper-compilation-targets@^7.15.4":
-  version "7.15.4"
-  resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz#cf6d94f30fbefc139123e27dd6b02f65aeedb7b9"
-  integrity sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==
+"@babel/helper-compilation-targets@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.0.tgz#01d615762e796c17952c29e3ede9d6de07d235a8"
+  integrity sha512-S7iaOT1SYlqK0sQaCi21RX4+13hmdmnxIEAnQUB/eh7GeAnRjOUgTYpLkUOiRXzD+yog1JxP0qyAQZ7ZxVxLVg==
   dependencies:
-    "@babel/compat-data" "^7.15.0"
+    "@babel/compat-data" "^7.16.0"
     "@babel/helper-validator-option" "^7.14.5"
     browserslist "^4.16.6"
     semver "^6.3.0"
 
-"@babel/helper-function-name@^7.15.4":
-  version "7.15.4"
-  resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc"
-  integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==
+"@babel/helper-function-name@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz#b7dd0797d00bbfee4f07e9c4ea5b0e30c8bb1481"
+  integrity sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==
   dependencies:
-    "@babel/helper-get-function-arity" "^7.15.4"
-    "@babel/template" "^7.15.4"
-    "@babel/types" "^7.15.4"
+    "@babel/helper-get-function-arity" "^7.16.0"
+    "@babel/template" "^7.16.0"
+    "@babel/types" "^7.16.0"
 
-"@babel/helper-get-function-arity@^7.15.4":
-  version "7.15.4"
-  resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b"
-  integrity sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==
+"@babel/helper-get-function-arity@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz#0088c7486b29a9cb5d948b1a1de46db66e089cfa"
+  integrity sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==
   dependencies:
-    "@babel/types" "^7.15.4"
+    "@babel/types" "^7.16.0"
 
-"@babel/helper-hoist-variables@^7.15.4":
-  version "7.15.4"
-  resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df"
-  integrity sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==
+"@babel/helper-hoist-variables@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz#4c9023c2f1def7e28ff46fc1dbcd36a39beaa81a"
+  integrity sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==
   dependencies:
-    "@babel/types" "^7.15.4"
+    "@babel/types" "^7.16.0"
 
-"@babel/helper-member-expression-to-functions@^7.15.4":
-  version "7.15.4"
-  resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz#bfd34dc9bba9824a4658b0317ec2fd571a51e6ef"
-  integrity sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==
+"@babel/helper-member-expression-to-functions@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz#29287040efd197c77636ef75188e81da8bccd5a4"
+  integrity sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==
   dependencies:
-    "@babel/types" "^7.15.4"
+    "@babel/types" "^7.16.0"
 
-"@babel/helper-module-imports@^7.15.4":
-  version "7.15.4"
-  resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f"
-  integrity sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==
+"@babel/helper-module-imports@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz#90538e60b672ecf1b448f5f4f5433d37e79a3ec3"
+  integrity sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==
   dependencies:
-    "@babel/types" "^7.15.4"
+    "@babel/types" "^7.16.0"
 
-"@babel/helper-module-transforms@^7.15.8":
-  version "7.15.8"
-  resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz#d8c0e75a87a52e374a8f25f855174786a09498b2"
-  integrity sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==
+"@babel/helper-module-transforms@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.0.tgz#1c82a8dd4cb34577502ebd2909699b194c3e9bb5"
+  integrity sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA==
   dependencies:
-    "@babel/helper-module-imports" "^7.15.4"
-    "@babel/helper-replace-supers" "^7.15.4"
-    "@babel/helper-simple-access" "^7.15.4"
-    "@babel/helper-split-export-declaration" "^7.15.4"
+    "@babel/helper-module-imports" "^7.16.0"
+    "@babel/helper-replace-supers" "^7.16.0"
+    "@babel/helper-simple-access" "^7.16.0"
+    "@babel/helper-split-export-declaration" "^7.16.0"
     "@babel/helper-validator-identifier" "^7.15.7"
-    "@babel/template" "^7.15.4"
-    "@babel/traverse" "^7.15.4"
-    "@babel/types" "^7.15.6"
+    "@babel/template" "^7.16.0"
+    "@babel/traverse" "^7.16.0"
+    "@babel/types" "^7.16.0"
 
-"@babel/helper-optimise-call-expression@^7.15.4":
-  version "7.15.4"
-  resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz#f310a5121a3b9cc52d9ab19122bd729822dee171"
-  integrity sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==
+"@babel/helper-optimise-call-expression@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz#cecdb145d70c54096b1564f8e9f10cd7d193b338"
+  integrity sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==
   dependencies:
-    "@babel/types" "^7.15.4"
+    "@babel/types" "^7.16.0"
 
 "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0":
   version "7.14.5"
   resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9"
   integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==
 
-"@babel/helper-replace-supers@^7.15.4":
-  version "7.15.4"
-  resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz#52a8ab26ba918c7f6dee28628b07071ac7b7347a"
-  integrity sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==
+"@babel/helper-replace-supers@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.0.tgz#73055e8d3cf9bcba8ddb55cad93fedc860f68f17"
+  integrity sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==
   dependencies:
-    "@babel/helper-member-expression-to-functions" "^7.15.4"
-    "@babel/helper-optimise-call-expression" "^7.15.4"
-    "@babel/traverse" "^7.15.4"
-    "@babel/types" "^7.15.4"
+    "@babel/helper-member-expression-to-functions" "^7.16.0"
+    "@babel/helper-optimise-call-expression" "^7.16.0"
+    "@babel/traverse" "^7.16.0"
+    "@babel/types" "^7.16.0"
 
-"@babel/helper-simple-access@^7.15.4":
-  version "7.15.4"
-  resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz#ac368905abf1de8e9781434b635d8f8674bcc13b"
-  integrity sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==
+"@babel/helper-simple-access@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz#21d6a27620e383e37534cf6c10bba019a6f90517"
+  integrity sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==
   dependencies:
-    "@babel/types" "^7.15.4"
+    "@babel/types" "^7.16.0"
 
-"@babel/helper-split-export-declaration@^7.15.4":
-  version "7.15.4"
-  resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz#aecab92dcdbef6a10aa3b62ab204b085f776e257"
-  integrity sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==
+"@babel/helper-split-export-declaration@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438"
+  integrity sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==
   dependencies:
-    "@babel/types" "^7.15.4"
+    "@babel/types" "^7.16.0"
 
-"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.15.7":
+"@babel/helper-validator-identifier@^7.15.7":
   version "7.15.7"
   resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389"
   integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==
@@ -181,28 +181,28 @@
   resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3"
   integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==
 
-"@babel/helpers@^7.15.4":
-  version "7.15.4"
-  resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz#5f40f02050a3027121a3cf48d497c05c555eaf43"
-  integrity sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==
+"@babel/helpers@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.0.tgz#875519c979c232f41adfbd43a3b0398c2e388183"
+  integrity sha512-dVRM0StFMdKlkt7cVcGgwD8UMaBfWJHl3A83Yfs8GQ3MO0LHIIIMvK7Fa0RGOGUQ10qikLaX6D7o5htcQWgTMQ==
   dependencies:
-    "@babel/template" "^7.15.4"
-    "@babel/traverse" "^7.15.4"
-    "@babel/types" "^7.15.4"
+    "@babel/template" "^7.16.0"
+    "@babel/traverse" "^7.16.0"
+    "@babel/types" "^7.16.0"
 
-"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5":
-  version "7.14.5"
-  resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9"
-  integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==
+"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.0":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a"
+  integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==
   dependencies:
-    "@babel/helper-validator-identifier" "^7.14.5"
+    "@babel/helper-validator-identifier" "^7.15.7"
     chalk "^2.0.0"
     js-tokens "^4.0.0"
 
-"@babel/parser@^7.1.0", "@babel/parser@^7.15.4", "@babel/parser@^7.15.8", "@babel/parser@^7.7.2":
-  version "7.15.8"
-  resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz#7bacdcbe71bdc3ff936d510c15dcea7cf0b99016"
-  integrity sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==
+"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.0", "@babel/parser@^7.7.2":
+  version "7.16.2"
+  resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz#3723cd5c8d8773eef96ce57ea1d9b7faaccd12ac"
+  integrity sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==
 
 "@babel/plugin-syntax-async-generators@^7.8.4":
   version "7.8.4"
@@ -289,42 +289,42 @@
     "@babel/helper-plugin-utils" "^7.14.5"
 
 "@babel/plugin-syntax-typescript@^7.7.2":
-  version "7.14.5"
-  resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716"
-  integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.0.tgz#2feeb13d9334cc582ea9111d3506f773174179bb"
+  integrity sha512-Xv6mEXqVdaqCBfJFyeab0fH2DnUoMsDmhamxsSi4j8nLd4Vtw213WMJr55xxqipC/YVWyPY3K0blJncPYji+dQ==
   dependencies:
     "@babel/helper-plugin-utils" "^7.14.5"
 
-"@babel/template@^7.15.4", "@babel/template@^7.3.3":
-  version "7.15.4"
-  resolved "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194"
-  integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==
-  dependencies:
-    "@babel/code-frame" "^7.14.5"
-    "@babel/parser" "^7.15.4"
-    "@babel/types" "^7.15.4"
-
-"@babel/traverse@^7.1.0", "@babel/traverse@^7.15.4", "@babel/traverse@^7.7.2":
-  version "7.15.4"
-  resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d"
-  integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==
-  dependencies:
-    "@babel/code-frame" "^7.14.5"
-    "@babel/generator" "^7.15.4"
-    "@babel/helper-function-name" "^7.15.4"
-    "@babel/helper-hoist-variables" "^7.15.4"
-    "@babel/helper-split-export-declaration" "^7.15.4"
-    "@babel/parser" "^7.15.4"
-    "@babel/types" "^7.15.4"
+"@babel/template@^7.16.0", "@babel/template@^7.3.3":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6"
+  integrity sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==
+  dependencies:
+    "@babel/code-frame" "^7.16.0"
+    "@babel/parser" "^7.16.0"
+    "@babel/types" "^7.16.0"
+
+"@babel/traverse@^7.1.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.7.2":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.0.tgz#965df6c6bfc0a958c1e739284d3c9fa4a6e3c45b"
+  integrity sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==
+  dependencies:
+    "@babel/code-frame" "^7.16.0"
+    "@babel/generator" "^7.16.0"
+    "@babel/helper-function-name" "^7.16.0"
+    "@babel/helper-hoist-variables" "^7.16.0"
+    "@babel/helper-split-export-declaration" "^7.16.0"
+    "@babel/parser" "^7.16.0"
+    "@babel/types" "^7.16.0"
     debug "^4.1.0"
     globals "^11.1.0"
 
-"@babel/types@^7.0.0", "@babel/types@^7.15.4", "@babel/types@^7.15.6", "@babel/types@^7.3.0", "@babel/types@^7.3.3":
-  version "7.15.6"
-  resolved "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f"
-  integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==
+"@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3":
+  version "7.16.0"
+  resolved "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba"
+  integrity sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==
   dependencies:
-    "@babel/helper-validator-identifier" "^7.14.9"
+    "@babel/helper-validator-identifier" "^7.15.7"
     to-fast-properties "^2.0.0"
 
 "@balena/dockerignore@^1.0.2":
@@ -387,9 +387,9 @@
     minimatch "^3.0.4"
 
 "@humanwhocodes/object-schema@^1.2.0":
-  version "1.2.0"
-  resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf"
-  integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==
+  version "1.2.1"
+  resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
+  integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
 
 "@hutson/parse-repository-url@^3.0.0":
   version "3.0.2"
@@ -752,26 +752,18 @@
     "@types/yargs" "^16.0.0"
     chalk "^4.0.0"
 
-"@jsii/check-node@1.40.0":
-  version "1.40.0"
-  resolved "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.40.0.tgz#49882a61ad1b3a37cd35c35fa1a2301955f1c058"
-  integrity sha512-rk0hFXxFQR8rDGUfsZT9ua6OufOpnLQWsNFyFU86AvpoKQ0ciw2KlGdWs7OYFnzPq8sQGhSS+iuBrUboaHW3jg==
-  dependencies:
-    chalk "^4.1.2"
-    semver "^7.3.5"
-
-"@jsii/check-node@1.41.0":
-  version "1.41.0"
-  resolved "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.41.0.tgz#17b6895e1fcc0b8bbb8fa81b52b17c47c9c47674"
-  integrity sha512-lV/vMK1HZQcUye2vXPu6XsmnTk7fEui0GnQsPAX1eLWfRMkxkRblT4VZ9DQTYjMno2HuVP4IH51fiFoICMmnkA==
+"@jsii/check-node@1.42.0":
+  version "1.42.0"
+  resolved "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.42.0.tgz#10dd84fbefa020344c9574079361c1a18754872a"
+  integrity sha512-URX4s0iOmuxbERL2rO10JlwedYbAT/3vM2HqswgjtJUbZTFgHsmg+Tzh3JglJzKuCg8Xm4m6CP4UlFMPqPRcqA==
   dependencies:
     chalk "^4.1.2"
     semver "^7.3.5"
 
-"@jsii/spec@^1.41.0":
-  version "1.41.0"
-  resolved "https://registry.npmjs.org/@jsii/spec/-/spec-1.41.0.tgz#d504c8536139a97986b1ec63201d3575972e1e9c"
-  integrity sha512-sN7x6C0DGLngiO6SkrM/7gVaHyeja59bDZODZtBXIq8kBIC+GgAFS8P0s1e5FpU9mHHvvHq4rvzvcIbxw0nkXw==
+"@jsii/spec@^1.42.0":
+  version "1.42.0"
+  resolved "https://registry.npmjs.org/@jsii/spec/-/spec-1.42.0.tgz#39e787e5ac2ddc96256b73421603bc734c56f7d8"
+  integrity sha512-SS2Q1Ds/yiTejd/0KO5lC6SUGqlfjuqZ6nAxJxLU76JQ99v1spRJeS7oi/2OW+ZmTEwBy81DgjOxA8bwUc0U/Q==
   dependencies:
     jsonschema "^1.4.0"
 
@@ -1468,9 +1460,9 @@
     fastq "^1.6.0"
 
 "@npmcli/ci-detect@^1.0.0":
-  version "1.3.0"
-  resolved "https://registry.npmjs.org/@npmcli/ci-detect/-/ci-detect-1.3.0.tgz#6c1d2c625fb6ef1b9dea85ad0a5afcbef85ef22a"
-  integrity sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q==
+  version "1.4.0"
+  resolved "https://registry.npmjs.org/@npmcli/ci-detect/-/ci-detect-1.4.0.tgz#18478bbaa900c37bfbd8a2006a6262c62e8b0fe1"
+  integrity sha512-3BGrt6FLjqM6br5AhWRKTr3u5GIVkjRYeAFrMp3HjnfICrg4xOrVRwFavKT6tsp++bq5dluL5t8ME/Nha/6c1Q==
 
 "@npmcli/fs@^1.0.0":
   version "1.0.0"
@@ -1774,10 +1766,10 @@
   dependencies:
     "@types/glob" "*"
 
-"@types/aws-lambda@^8.10.84":
-  version "8.10.84"
-  resolved "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.84.tgz#b1f391ceeb6908b28d8416d93f27afe8d1348d4e"
-  integrity sha512-5V78eLtmN0d4RA14hKDwcsMQRl3JotQJlhGFDBo/jdE2TyDFRaYwB/UmMUC4SzhSvRGn+YMkh7jGPnXi8COAng==
+"@types/aws-lambda@^8.10.85":
+  version "8.10.85"
+  resolved "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.85.tgz#26cd76897b1972247cbc1a34b6f21d023e987437"
+  integrity sha512-cMRXVxb+NMb6EekKel1fPBfz2ZqE5cGhIS14G7FVUM4Bqilx0lHKnZbsDLWLSeckDpkvlp5six2F7UWyEEJSoQ==
 
 "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.7":
   version "7.1.16"
@@ -1817,10 +1809,10 @@
   resolved "https://registry.npmjs.org/@types/changelog-parser/-/changelog-parser-2.7.1.tgz#da124373fc8abfb6951fef83718ea5f041fea527"
   integrity sha512-OFZB7OlG6nrkcnvJhcyV2Zm/PUGk40oHyfaEBRjlm+ghrKxbFQI+xao/IzYL0G72fpLCTGGs3USrhe38/FF6QQ==
 
-"@types/eslint@^7.28.1":
-  version "7.28.1"
-  resolved "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.1.tgz#50b07747f1f84c2ba8cd394cf0fe0ba07afce320"
-  integrity sha512-XhZKznR3i/W5dXqUhgU9fFdJekufbeBd5DALmkuXoeFcjbQcPk+2cL+WLHf6Q81HWAnM2vrslIHpGVyCAviRwg==
+"@types/eslint@^7.28.2":
+  version "7.28.2"
+  resolved "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.2.tgz#0ff2947cdd305897c52d5372294e8c76f351db68"
+  integrity sha512-KubbADPkfoU75KgKeKLsFHXnU4ipH7wYg0TRT33NK3N3yiu7jlFAAoygIWBV+KbuHx/G+AvuGX6DllnK35gfJA==
   dependencies:
     "@types/estree" "*"
     "@types/json-schema" "*"
@@ -1844,10 +1836,10 @@
   dependencies:
     "@types/node" "*"
 
-"@types/glob@*", "@types/glob@^7.1.4":
-  version "7.1.4"
-  resolved "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz#ea59e21d2ee5c517914cb4bc8e4153b99e566672"
-  integrity sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==
+"@types/glob@*", "@types/glob@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
+  integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==
   dependencies:
     "@types/minimatch" "*"
     "@types/node" "*"
@@ -1896,10 +1888,10 @@
   resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
   integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
 
-"@types/lodash@^4.14.175":
-  version "4.14.175"
-  resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.175.tgz#b78dfa959192b01fae0ad90e166478769b215f45"
-  integrity sha512-XmdEOrKQ8a1Y/yxQFOMbC47G/V2VDO1GvMRnl4O75M4GW/abC5tnfzadQYkqEveqRM1dEJGFFegfPNA2vvx2iw==
+"@types/lodash@^4.14.176":
+  version "4.14.176"
+  resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.176.tgz#641150fc1cda36fbfa329de603bbb175d7ee20c0"
+  integrity sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ==
 
 "@types/md5@^2.3.1":
   version "2.3.1"
@@ -1936,9 +1928,9 @@
   integrity sha512-uv53RrNdhbkV/3VmVCtfImfYCWC3GTTRn3R11Whni3EJ+gb178tkZBVNj2edLY5CMrB749dQi+SJkg87jsN8UQ==
 
 "@types/node@*", "@types/node@>= 8", "@types/node@^16.9.2":
-  version "16.10.5"
-  resolved "https://registry.npmjs.org/@types/node/-/node-16.10.5.tgz#7fe4123b061753f1a58a6cd077ff0bb069ee752d"
-  integrity sha512-9iI3OOlkyOjLQQ9s+itIJNMRepDhB/96jW3fqduJ2FTPQj1dJjw6Q3QCImF9FE1wmdBs5QSun4FjDSFS8d8JLw==
+  version "16.11.6"
+  resolved "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae"
+  integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==
 
 "@types/node@^10.17.60":
   version "10.17.60"
@@ -1977,10 +1969,10 @@
   resolved "https://registry.npmjs.org/@types/punycode/-/punycode-2.1.0.tgz#89e4f3d09b3f92e87a80505af19be7e0c31d4e83"
   integrity sha512-PG5aLpW6PJOeV2fHRslP4IOMWn+G+Uq8CfnyJ+PDS8ndCbU+soO+fB3NKCKo0p/Jh2Y4aPaiQZsrOXFdzpcA6g==
 
-"@types/semver@^7.3.8":
-  version "7.3.8"
-  resolved "https://registry.npmjs.org/@types/semver/-/semver-7.3.8.tgz#508a27995498d7586dcecd77c25e289bfaf90c59"
-  integrity sha512-D/2EJvAlCEtYFEYmmlGwbGXuK886HzyCc3nZX/tkFTQdEU8jZDAgiv08P162yB17y4ZXZoq7yFAnW4GDBb9Now==
+"@types/semver@^7.3.9":
+  version "7.3.9"
+  resolved "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc"
+  integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==
 
 "@types/sinon@^9.0.11":
   version "9.0.11"
@@ -2484,9 +2476,9 @@ astral-regex@^2.0.0:
   integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
 
 async@^3.2.0:
-  version "3.2.1"
-  resolved "https://registry.npmjs.org/async/-/async-3.2.1.tgz#d3274ec66d107a47476a4c49136aacdb00665fc8"
-  integrity sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==
+  version "3.2.2"
+  resolved "https://registry.npmjs.org/async/-/async-3.2.2.tgz#2eb7671034bb2194d45d30e31e24ec7e7f9670cd"
+  integrity sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==
 
 asynckit@^0.4.0:
   version "0.4.0"
@@ -2523,9 +2515,9 @@ aws-sdk-mock@^5.4.0:
     traverse "^0.6.6"
 
 aws-sdk@^2.596.0, aws-sdk@^2.848.0, aws-sdk@^2.928.0, aws-sdk@^2.979.0:
-  version "2.1006.0"
-  resolved "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1006.0.tgz#fc2f7e267d19a6297f732e19449461bb944682af"
-  integrity sha512-lwXAy706+1HVQqMnHaahdeBZZbdu6TWrtTY0ydeG0qanwldTFNMLczwnETTZWYsqNAU+wjl1VzmFdMO4gePLNQ==
+  version "2.1020.0"
+  resolved "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1020.0.tgz#91fee48f3897e21b0fa6fbd066ea716ac2f0957d"
+  integrity sha512-cCFLGRfzJn0whOioljFjcFpQTXWB4PTdVnrpNhX2R687W3Yz6WriHxHqIxVnIke1yp9twU00z4kW522U809l0g==
   dependencies:
     buffer "4.9.2"
     events "1.1.1"
@@ -2583,14 +2575,14 @@ babel-jest@^27.3.1:
     slash "^3.0.0"
 
 babel-plugin-istanbul@^6.0.0:
-  version "6.0.0"
-  resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765"
-  integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==
+  version "6.1.1"
+  resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73"
+  integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
     "@istanbuljs/load-nyc-config" "^1.0.0"
     "@istanbuljs/schema" "^0.1.2"
-    istanbul-lib-instrument "^4.0.0"
+    istanbul-lib-instrument "^5.0.4"
     test-exclude "^6.0.0"
 
 babel-plugin-jest-hoist@^26.6.2:
@@ -2733,15 +2725,15 @@ browser-process-hrtime@^1.0.0:
   integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==
 
 browserslist@^4.16.6:
-  version "4.17.3"
-  resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.17.3.tgz#2844cd6eebe14d12384b0122d217550160d2d624"
-  integrity sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ==
+  version "4.17.6"
+  resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.17.6.tgz#c76be33e7786b497f66cad25a73756c8b938985d"
+  integrity sha512-uPgz3vyRTlEiCv4ee9KlsKgo2V6qPk7Jsn0KAn2OBqbqKo3iNcPEC1Ti6J4dwnz+aIRfEEEuOzC9IBk8tXUomw==
   dependencies:
-    caniuse-lite "^1.0.30001264"
-    electron-to-chromium "^1.3.857"
+    caniuse-lite "^1.0.30001274"
+    electron-to-chromium "^1.3.886"
     escalade "^3.1.1"
-    node-releases "^1.1.77"
-    picocolors "^0.2.1"
+    node-releases "^2.0.1"
+    picocolors "^1.0.0"
 
 bs-logger@0.x:
   version "0.2.6"
@@ -2890,10 +2882,10 @@ camelcase@^6.0.0, camelcase@^6.2.0:
   resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
   integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
 
-caniuse-lite@^1.0.30001264:
-  version "1.0.30001265"
-  resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz#0613c9e6c922e422792e6fcefdf9a3afeee4f8c3"
-  integrity sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw==
+caniuse-lite@^1.0.30001274:
+  version "1.0.30001275"
+  resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001275.tgz#26f5076629fe4e52bbd245f9046ad7b90aafdf57"
+  integrity sha512-ihJVvj8RX0kn9GgP43HKhb5q9s2XQn4nEQhdldEJvZhCsuiB2XOq6fAMYQZaN6FPWfsr2qU0cdL0CSbETwbJAg==
 
 capture-exit@^2.0.0:
   version "2.0.0"
@@ -3081,19 +3073,10 @@ co@^4.6.0:
   resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
   integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
 
-codemaker@^1.39.0:
-  version "1.39.0"
-  resolved "https://registry.npmjs.org/codemaker/-/codemaker-1.39.0.tgz#d8103f4b587210b1d6aa073d62ffb510ac20bc42"
-  integrity sha512-1PPD7ZCC05nrkN47elPcno3zm4Md7XSkG52CvIbNsEcXddc0Ma2xgoMZnWPu+Ab6801FunSqov9X4O+OZle95A==
-  dependencies:
-    camelcase "^6.2.0"
-    decamelize "^5.0.1"
-    fs-extra "^9.1.0"
-
-codemaker@^1.41.0:
-  version "1.41.0"
-  resolved "https://registry.npmjs.org/codemaker/-/codemaker-1.41.0.tgz#814edff6ffd241727794e76f81c5f9e4df135162"
-  integrity sha512-Iow0udcpshcVmztwSSJDTRhJxTbH0nXU3pxf7iF0gv6+BWC5Nd2aWQ2W5rHECySQPIvmWn4KEpV/SvXgvfl0aA==
+codemaker@^1.42.0:
+  version "1.42.0"
+  resolved "https://registry.npmjs.org/codemaker/-/codemaker-1.42.0.tgz#dab2ae818e424803d7aa5f837838d7ec5f1dab4b"
+  integrity sha512-pjLw1YeWKdY09tDmr6HmeZCGd6G+Ku1UP3cK/oX79x5iEL2ZEm8kJrGQisasK6pk/Er75sDZA86c5Cn7sIx4GQ==
   dependencies:
     camelcase "^6.2.0"
     decamelize "^5.0.1"
@@ -3270,16 +3253,7 @@ conventional-changelog-config-spec@2.1.0, conventional-changelog-config-spec@^2.
   resolved "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz#874a635287ef8b581fd8558532bf655d4fb59f2d"
   integrity sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==
 
-conventional-changelog-conventionalcommits@4.5.0:
-  version "4.5.0"
-  resolved "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.5.0.tgz#a02e0b06d11d342fdc0f00c91d78265ed0bc0a62"
-  integrity sha512-buge9xDvjjOxJlyxUnar/+6i/aVEVGA7EEh4OafBCXPlLUQPGbRUBhBUveWRxzvR8TEjhKEP4BdepnpG2FSZXw==
-  dependencies:
-    compare-func "^2.0.0"
-    lodash "^4.17.15"
-    q "^1.5.1"
-
-conventional-changelog-conventionalcommits@^4.5.0:
+conventional-changelog-conventionalcommits@4.6.1, conventional-changelog-conventionalcommits@^4.5.0:
   version "4.6.1"
   resolved "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.1.tgz#f4c0921937050674e578dc7875f908351ccf4014"
   integrity sha512-lzWJpPZhbM1R0PIzkwzGBCnAkH5RKJzJfFQZcl/D+2lsJxAwGnDKBqn/F4C1RD31GJNn8NuKWQzAZDAVXPp2Mw==
@@ -3405,10 +3379,10 @@ conventional-commits-filter@^2.0.7:
     lodash.ismatch "^4.4.0"
     modify-values "^1.0.0"
 
-conventional-commits-parser@^3.2.0, conventional-commits-parser@^3.2.2:
-  version "3.2.2"
-  resolved "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.2.tgz#190fb9900c6e02be0c0bca9b03d57e24982639fd"
-  integrity sha512-Jr9KAKgqAkwXMRHjxDwO/zOCDKod1XdAESHAGuJX38iZ7ZzVti/tvVoysO0suMsdAObp9NQ2rHSsSbnAqZ5f5g==
+conventional-commits-parser@^3.2.0, conventional-commits-parser@^3.2.3:
+  version "3.2.3"
+  resolved "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.3.tgz#fc43704698239451e3ef35fd1d8ed644f46bd86e"
+  integrity sha512-YyRDR7On9H07ICFpRm/igcdjIqebXbvf4Cff+Pf0BrBys1i1EOzx9iFXNlAbdrLAR8jf7bkUYkDAr8pEy0q4Pw==
   dependencies:
     JSONStream "^1.0.4"
     is-text-path "^1.0.1"
@@ -3876,10 +3850,10 @@ ecc-jsbn@~0.1.1:
     jsbn "~0.1.0"
     safer-buffer "^2.1.0"
 
-electron-to-chromium@^1.3.857:
-  version "1.3.867"
-  resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.867.tgz#7cb484db4b57c28da0b65c51e434c3a1f3f9aa0d"
-  integrity sha512-WbTXOv7hsLhjJyl7jBfDkioaY++iVVZomZ4dU6TMe/SzucV6mUAs2VZn/AehBwuZMiNEQDaPuTGn22YK5o+aDw==
+electron-to-chromium@^1.3.886:
+  version "1.3.887"
+  resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.887.tgz#b36aeed12a28aaa19460a467823f5bbe1f3c6f06"
+  integrity sha512-QQUumrEjFDKSVYVdaeBmFdyQGoaV+fCSMyWHvfx/u22bRHSTeBQYt6P4jMY+gFd4kgKB9nqk7RMtWkDB49OYPA==
 
 emittery@^0.7.1:
   version "0.7.2"
@@ -4008,107 +3982,113 @@ es6-error@^4.0.1:
   resolved "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
   integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
 
-esbuild-android-arm64@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.5.tgz#a299a18fd8a016ae19fd948fc659b3f65d1b992f"
-  integrity sha512-xaNH58b9XRAWT5q0rwA2GNTgJynb51JhdotlNKdLmSCyKXPVlF87yqNLNdmlX/zndzRDrZdtpCWSALdn/J63Ug==
-
-esbuild-darwin-64@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.5.tgz#01359f2c6921bd2704d0a895f5603ab33f2eeb1b"
-  integrity sha512-ClGQeUObXIxEpZviGzjTinDikXy9XodojP9jLKwqLCBpZ9wdV3MW7JOmw60fgXgnbNRvkZCqM6uEi+ur8p80Ow==
-
-esbuild-darwin-arm64@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.5.tgz#1dbe362ebc9afcdab4f9af9bb320dacd73e2aedc"
-  integrity sha512-qro6M/qzs1dBPh14Ca+5moIkLo2KE3ll3dOpiN7aAususkM1HmqQptCEchi0XwX+6nfqWI96YvVqPJ3DfUUK5A==
-
-esbuild-freebsd-64@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.5.tgz#fecee59fa491a3f544c731b0c0319bd5a9da7d50"
-  integrity sha512-vklf7L7fghREEvS1sjAFcxcw/Qqt+Z+L0ySN+pEeb7rA8nPLfRBSFdXAru8UNuHsMWns6CrcZ5eDOKTerZZ5ng==
-
-esbuild-freebsd-arm64@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.5.tgz#4e98c0e33ed19a63ffd4db87314986b9d93850b5"
-  integrity sha512-kJoouhbZt4QvjiPak7/Lz57Azok0CgFnNtixiOsqEQXTabIaKmMmnq4qgjD6EBFeU/hvSXDrPe6U8dWhBZOrWQ==
-
-esbuild-linux-32@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.5.tgz#00083740af7f1416951c634a461e3d01ed812cd0"
-  integrity sha512-/QufG6tTGKAf42pIYkOVZzKBPxF01xH1kCPyOFJZukZBV/Tk3TeOZfhJIAf7pxl4jhfa+c4Jcdp7CvIAjXrmJg==
-
-esbuild-linux-64@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.5.tgz#49bd1648fd2070594fe3aad31925108ee2916216"
-  integrity sha512-NmNFMXEthuFJTFaD4cLhAHCxg+y3uXzo7nqH/WNNSZ8PPY11jbeOvMbdArYlbo2Wy1N/mTHXMcK1synSJj+4Iw==
-
-esbuild-linux-arm64@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.5.tgz#78ef0f20d2b175403552075cc6d6af80f55a22d8"
-  integrity sha512-dOS5EZsZj8Lw0TgEj3zy1/slTBbfBw4v7uHEqZXP34dUaRq2oltNaUYIj735CtgB7I5/MXrXEUYkXLqcVfzJQQ==
-
-esbuild-linux-arm@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.5.tgz#27c4e92a6597376a8c3fe8c79177d72ba77f8500"
-  integrity sha512-69nQmbKLBRaAxf88diyaOyarrI7yIdBkZ8bmVzQ7XVWneY+nYIcGtugTSOs5znNGfPqGOElAjh1lX+0sGYHNpA==
-
-esbuild-linux-mips64le@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.5.tgz#4061cbef41f96e4a176bebf7e7b2d6d397e05e86"
-  integrity sha512-dmKA8ZI/nHwpxIQW/L5crk7Ac4wJJ2Kquvdo1CdXPW1UljMyKUDuHc4K7D1Iws5igqJmNO6U5vdRUKrdnIov6Q==
-
-esbuild-linux-ppc64le@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.5.tgz#290a5caca6751b8c80c5d075cafe857102263118"
-  integrity sha512-HkVGKkPL3XOhJqNOJ752Q1li5zeidrJHv+XWX6qCnCipNsVuGqaAGfxeWbL/+A/giolMlP7wvAuiKgoe+a5UAw==
-
-esbuild-openbsd-64@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.5.tgz#223eb2730a6fede7930a2b44b0b1d5b067a3cef5"
-  integrity sha512-BuOZzmdsdreSs0qDgbuiEhSbUDDW2Wyp4VtpNGBmaLwPMHftdprOJXLkeFud3HlnRB2n9qdiTVKg1B8YqMogSw==
-
-esbuild-sunos-64@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.5.tgz#6f121ac285c298f09467748607cc0496ebbfd23e"
-  integrity sha512-YJNB6Og1QYAPikvYDbqvk5xCqr6WL2i5cRWPGGgWOEItQPnq6gFsWogS3DiYM8TQKe50KRiD3Lwu7eNYsdPO4w==
-
-esbuild-windows-32@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.5.tgz#0da6d240152f76f3dd764c0bb0391d894acd403f"
-  integrity sha512-CigOlBSKsZ61IS+FyhD3luqCpl7LN9ntDaBZXumls/0IZ/8BJ5txqw4a6pv4LtnfIgt0ixGHSH7kAUmApw/HAw==
-
-esbuild-windows-64@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.5.tgz#330266a2c95b26c2f949e9de9b0c366924fec53f"
-  integrity sha512-pg2BZXLpcPcrIcmToGapLRExzj6sm0VmQlqlmnMOtIJh0YQV9c0CRbhfIT0gYvJqCz5JEGiRvYpArRlxWADN3Q==
-
-esbuild-windows-arm64@0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.5.tgz#e0501e82b88f4165cce7cd017db83428f459f775"
-  integrity sha512-KKRDmUOIE4oCvJp0I4p4QyazK2X79spF29vsZr2U8qHhmxbTLSQWvYmb2WlF5Clb1URRsX0L013rhwHx1SEu0w==
-
-esbuild@^0.13.5:
-  version "0.13.5"
-  resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.13.5.tgz#f9add2c2c899a9023dd7f7b64c452320f008aa79"
-  integrity sha512-Q9/f1njsZaO+Qqe3dqAdtu4zGHNZIbcEtdg44/NooyPhqCerns4FeC1UPYeB4pKD08iDuWcmyINFJTqpdN+pqg==
+esbuild-android-arm64@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.12.tgz#e1f199dc05405cdc6670c00fb6c793822bf8ae4c"
+  integrity sha512-TSVZVrb4EIXz6KaYjXfTzPyyRpXV5zgYIADXtQsIenjZ78myvDGaPi11o4ZSaHIwFHsuwkB6ne5SZRBwAQ7maw==
+
+esbuild-darwin-64@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.12.tgz#f5c59e622955c01f050e5a7ac9c1d41db714b94d"
+  integrity sha512-c51C+N+UHySoV2lgfWSwwmlnLnL0JWj/LzuZt9Ltk9ub1s2Y8cr6SQV5W3mqVH1egUceew6KZ8GyI4nwu+fhsw==
+
+esbuild-darwin-arm64@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.12.tgz#8abae74c2956a8aa568fc52c78829338c4a4b988"
+  integrity sha512-JvAMtshP45Hd8A8wOzjkY1xAnTKTYuP/QUaKp5eUQGX+76GIie3fCdUUr2ZEKdvpSImNqxiZSIMziEiGB5oUmQ==
+
+esbuild-freebsd-64@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.12.tgz#6ad2ab8c0364ee7dd2d6e324d876a8e60ae75d12"
+  integrity sha512-r6On/Skv9f0ZjTu6PW5o7pdXr8aOgtFOEURJZYf1XAJs0IQ+gW+o1DzXjVkIoT+n1cm3N/t1KRJfX71MPg/ZUA==
+
+esbuild-freebsd-arm64@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.12.tgz#6f38155f4c300ac4c8adde1fde3cc6a4440a8294"
+  integrity sha512-F6LmI2Q1gii073kmBE3NOTt/6zLL5zvZsxNLF8PMAwdHc+iBhD1vzfI8uQZMJA1IgXa3ocr3L3DJH9fLGXy6Yw==
+
+esbuild-linux-32@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.12.tgz#b1d15e330188a8c21de75c3f0058628a3eefade7"
+  integrity sha512-U1UZwG3UIwF7/V4tCVAo/nkBV9ag5KJiJTt+gaCmLVWH3bPLX7y+fNlhIWZy8raTMnXhMKfaTvWZ9TtmXzvkuQ==
+
+esbuild-linux-64@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.12.tgz#25bd64b66162b02348e32d8f12e4c9ee61f1d070"
+  integrity sha512-YpXSwtu2NxN3N4ifJxEdsgd6Q5d8LYqskrAwjmoCT6yQnEHJSF5uWcxv783HWN7lnGpJi9KUtDvYsnMdyGw71Q==
+
+esbuild-linux-arm64@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.12.tgz#ba582298457cc5c9ac823a275de117620c06537f"
+  integrity sha512-sgDNb8kb3BVodtAlcFGgwk+43KFCYjnFOaOfJibXnnIojNWuJHpL6aQJ4mumzNWw8Rt1xEtDQyuGK9f+Y24jGA==
+
+esbuild-linux-arm@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.12.tgz#6bc81c957bff22725688cc6359c29a25765be09b"
+  integrity sha512-SyiT/JKxU6J+DY2qUiSLZJqCAftIt3uoGejZ0HDnUM2MGJqEGSGh7p1ecVL2gna3PxS4P+j6WAehCwgkBPXNIw==
+
+esbuild-linux-mips64le@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.12.tgz#ef3c4aba3e585d847cbade5945a8b4a5c62c7ce2"
+  integrity sha512-qQJHlZBG+QwVIA8AbTEtbvF084QgDi4DaUsUnA+EolY1bxrG+UyOuGflM2ZritGhfS/k7THFjJbjH2wIeoKA2g==
+
+esbuild-linux-ppc64le@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.12.tgz#a21fb64e80c38bef06122e48283990fc6db578e1"
+  integrity sha512-2dSnm1ldL7Lppwlo04CGQUpwNn5hGqXI38OzaoPOkRsBRWFBozyGxTFSee/zHFS+Pdh3b28JJbRK3owrrRgWNw==
+
+esbuild-netbsd-64@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.12.tgz#1ea7fc8cfce88a20a4047b867ef184049a6641ae"
+  integrity sha512-D4raxr02dcRiQNbxOLzpqBzcJNFAdsDNxjUbKkDMZBkL54Z0vZh4LRndycdZAMcIdizC/l/Yp/ZsBdAFxc5nbA==
+
+esbuild-openbsd-64@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.12.tgz#adde32f2f1b05dc4bd4fc544d6ea5a4379f9ca4d"
+  integrity sha512-KuLCmYMb2kh05QuPJ+va60bKIH5wHL8ypDkmpy47lzwmdxNsuySeCMHuTv5o2Af1RUn5KLO5ZxaZeq4GEY7DaQ==
+
+esbuild-sunos-64@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.12.tgz#a7ecaf52b7364fbee76dc8aa707fa3e1cff3342c"
+  integrity sha512-jBsF+e0woK3miKI8ufGWKG3o3rY9DpHvCVRn5eburMIIE+2c+y3IZ1srsthKyKI6kkXLvV4Cf/E7w56kLipMXw==
+
+esbuild-windows-32@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.12.tgz#a8756033dc905c4b7bea19be69f7ee68809f8770"
+  integrity sha512-L9m4lLFQrFeR7F+eLZXG82SbXZfUhyfu6CexZEil6vm+lc7GDCE0Q8DiNutkpzjv1+RAbIGVva9muItQ7HVTkQ==
+
+esbuild-windows-64@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.12.tgz#ae694aa66ca078acb8509b2da31197ed1f40f798"
+  integrity sha512-k4tX4uJlSbSkfs78W5d9+I9gpd+7N95W7H2bgOMFPsYREVJs31+Q2gLLHlsnlY95zBoPQMIzHooUIsixQIBjaQ==
+
+esbuild-windows-arm64@0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.12.tgz#782c5a8bd6d717ea55aaafe648f9926ca36a4a88"
+  integrity sha512-2tTv/BpYRIvuwHpp2M960nG7uvL+d78LFW/ikPItO+2GfK51CswIKSetSpDii+cjz8e9iSPgs+BU4o8nWICBwQ==
+
+esbuild@^0.13.12:
+  version "0.13.12"
+  resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.13.12.tgz#9cac641594bf03cf34145258c093d743ebbde7ca"
+  integrity sha512-vTKKUt+yoz61U/BbrnmlG9XIjwpdIxmHB8DlPR0AAW6OdS+nBQBci6LUHU2q9WbBobMEIQxxDpKbkmOGYvxsow==
   optionalDependencies:
-    esbuild-android-arm64 "0.13.5"
-    esbuild-darwin-64 "0.13.5"
-    esbuild-darwin-arm64 "0.13.5"
-    esbuild-freebsd-64 "0.13.5"
-    esbuild-freebsd-arm64 "0.13.5"
-    esbuild-linux-32 "0.13.5"
-    esbuild-linux-64 "0.13.5"
-    esbuild-linux-arm "0.13.5"
-    esbuild-linux-arm64 "0.13.5"
-    esbuild-linux-mips64le "0.13.5"
-    esbuild-linux-ppc64le "0.13.5"
-    esbuild-openbsd-64 "0.13.5"
-    esbuild-sunos-64 "0.13.5"
-    esbuild-windows-32 "0.13.5"
-    esbuild-windows-64 "0.13.5"
-    esbuild-windows-arm64 "0.13.5"
+    esbuild-android-arm64 "0.13.12"
+    esbuild-darwin-64 "0.13.12"
+    esbuild-darwin-arm64 "0.13.12"
+    esbuild-freebsd-64 "0.13.12"
+    esbuild-freebsd-arm64 "0.13.12"
+    esbuild-linux-32 "0.13.12"
+    esbuild-linux-64 "0.13.12"
+    esbuild-linux-arm "0.13.12"
+    esbuild-linux-arm64 "0.13.12"
+    esbuild-linux-mips64le "0.13.12"
+    esbuild-linux-ppc64le "0.13.12"
+    esbuild-netbsd-64 "0.13.12"
+    esbuild-openbsd-64 "0.13.12"
+    esbuild-sunos-64 "0.13.12"
+    esbuild-windows-32 "0.13.12"
+    esbuild-windows-64 "0.13.12"
+    esbuild-windows-arm64 "0.13.12"
 
 escalade@^3.1.1:
   version "3.1.1"
@@ -4179,9 +4159,9 @@ eslint-import-resolver-typescript@^2.5.0:
     tsconfig-paths "^3.9.0"
 
 eslint-module-utils@^2.7.0:
-  version "2.7.0"
-  resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.0.tgz#9e97c12688113401259b39d960e6a1f09f966435"
-  integrity sha512-hqSE88MmHl3ru9SYvDyGrlo0JwROlf9fiEMplEV7j/EAuq9iSlIlyCFbBT6pdULQBSnBYtYKiMLps+hKkyP7Gg==
+  version "2.7.1"
+  resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz#b435001c9f8dd4ab7f6d0efcae4b9696d4c24b7c"
+  integrity sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==
   dependencies:
     debug "^3.2.7"
     find-up "^2.1.0"
@@ -4360,9 +4340,9 @@ estraverse@^4.1.1, estraverse@^4.2.0:
   integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
 
 estraverse@^5.1.0, estraverse@^5.2.0:
-  version "5.2.0"
-  resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880"
-  integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==
+  version "5.3.0"
+  resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
+  integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
 
 esutils@^2.0.2:
   version "2.0.3"
@@ -4523,14 +4503,14 @@ extsprintf@1.3.0:
   integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
 
 extsprintf@^1.2.0:
-  version "1.4.0"
-  resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
-  integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
+  version "1.4.1"
+  resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07"
+  integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==
 
-fast-check@^2.18.0:
-  version "2.18.0"
-  resolved "https://registry.npmjs.org/fast-check/-/fast-check-2.18.0.tgz#0337d82e7d7cb4eed5806c42b9e61ed0fb6592b2"
-  integrity sha512-7KKUw0wtAJOVrJ1DgmFILd9EmeqMLGtfe5HoEtkYZfYIxohm6Zy7zPq1Zl8t6tPL8A3e86YZrheyGg2m5j8cLA==
+fast-check@^2.19.0:
+  version "2.19.0"
+  resolved "https://registry.npmjs.org/fast-check/-/fast-check-2.19.0.tgz#e87666450e417cd163a564bd546ee763d27c0f19"
+  integrity sha512-qY4Rc0Nljl2aJx2qgbK3o6wPBjL9QvhKdD/VqJgaKd5ewn8l4ViqgDpUHJq/JkHTBnFKomYYvkFkOYGDVTT8bw==
   dependencies:
     pure-rand "^5.0.0"
 
@@ -4705,9 +4685,9 @@ flatted@^3.1.0:
   integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==
 
 follow-redirects@^1.11.0, follow-redirects@^1.14.0:
-  version "1.14.4"
-  resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379"
-  integrity sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==
+  version "1.14.5"
+  resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381"
+  integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==
 
 for-in@^1.0.2:
   version "1.0.2"
@@ -5037,9 +5017,9 @@ globals@^11.1.0:
   integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
 
 globals@^13.6.0, globals@^13.9.0:
-  version "13.11.0"
-  resolved "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz#40ef678da117fe7bd2e28f1fab24951bd0255be7"
-  integrity sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==
+  version "13.12.0"
+  resolved "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e"
+  integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==
   dependencies:
     type-fest "^0.20.2"
 
@@ -5467,9 +5447,9 @@ is-ci@^2.0.0:
     ci-info "^2.0.0"
 
 is-core-module@^2.2.0, is-core-module@^2.5.0, is-core-module@^2.7.0:
-  version "2.7.0"
-  resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3"
-  integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==
+  version "2.8.0"
+  resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548"
+  integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==
   dependencies:
     has "^1.0.3"
 
@@ -5760,10 +5740,10 @@ isstream@~0.1.2:
   resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
   integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
 
-istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.0.0-alpha.1:
-  version "3.0.2"
-  resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.2.tgz#36786d4d82aad2ea5911007e255e2da6b5f80d86"
-  integrity sha512-o5+eTUYzCJ11/+JhW5/FUCdfsdoYVdQ/8I/OveE2XsjehYn5DdeSnNQAbjYaO8gQ6hvGTN6GM6ddQqpTVG5j8g==
+istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.0.0-alpha.1, istanbul-lib-coverage@^3.2.0:
+  version "3.2.0"
+  resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3"
+  integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==
 
 istanbul-lib-hook@^3.0.0:
   version "3.0.0"
@@ -5782,6 +5762,17 @@ istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3:
     istanbul-lib-coverage "^3.0.0"
     semver "^6.3.0"
 
+istanbul-lib-instrument@^5.0.4:
+  version "5.1.0"
+  resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a"
+  integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==
+  dependencies:
+    "@babel/core" "^7.12.3"
+    "@babel/parser" "^7.14.7"
+    "@istanbuljs/schema" "^0.1.2"
+    istanbul-lib-coverage "^3.2.0"
+    semver "^6.3.0"
+
 istanbul-lib-processinfo@^2.0.2:
   version "2.0.2"
   resolved "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz#e1426514662244b2f25df728e8fd1ba35fe53b9c"
@@ -5814,9 +5805,9 @@ istanbul-lib-source-maps@^4.0.0:
     source-map "^0.6.1"
 
 istanbul-reports@^3.0.2:
-  version "3.0.4"
-  resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.4.tgz#5c38ce8136edf484c0fcfbf7514aafb0363ed1db"
-  integrity sha512-bFjUnc95rHjdCR63WMHUS7yfJJh8T9IPSWavvR02hhjVwezWALZ5axF9EqjmwZHpXqkzbgAMP8DmAtiyNxrdrQ==
+  version "3.0.5"
+  resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz#a2580107e71279ea6d661ddede929ffc6d693384"
+  integrity sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==
   dependencies:
     html-escaper "^2.0.0"
     istanbul-lib-report "^3.0.0"
@@ -6692,57 +6683,57 @@ jsesc@^2.5.1:
   resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
   integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
 
-jsii-diff@^1.41.0:
-  version "1.41.0"
-  resolved "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.41.0.tgz#ef88aa98081e4bb41f13d24074fce9bee1574d24"
-  integrity sha512-LTfqGh0f0fUuWu8DBkEUgl0fteIBfzyEiExcqLBXbztg/8JRbt3DYUr63hHULJj4O/rnRTaaYNH7oT1sg4gpSQ==
+jsii-diff@^1.42.0:
+  version "1.42.0"
+  resolved "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.42.0.tgz#08fab1b90575239daa5f3ae853e2e921d4d26e90"
+  integrity sha512-ErMGIBt14Z12b2/FGCv8/H8X19nKr/fcq0UA3xJ6/dIvJyATGNlzxcWHmTUcSoaIxlKjFHYErPvZNUrJslbH4Q==
   dependencies:
-    "@jsii/check-node" "1.41.0"
-    "@jsii/spec" "^1.41.0"
+    "@jsii/check-node" "1.42.0"
+    "@jsii/spec" "^1.42.0"
     fs-extra "^9.1.0"
-    jsii-reflect "^1.41.0"
+    jsii-reflect "^1.42.0"
     log4js "^6.3.0"
     typescript "~3.9.10"
     yargs "^16.2.0"
 
-jsii-pacmak@^1.41.0:
-  version "1.41.0"
-  resolved "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.41.0.tgz#b94575f4a7c658d3fbd1c5f30876ce53a22ed126"
-  integrity sha512-B3ohEObc2xSnWoawK0q4qVkxa9Dh4A+x1y9K31AAS5jGbhdjbdS/FfphlUbukIoSR0NBJLgJg9pT+h/PIlUqdA==
+jsii-pacmak@^1.42.0:
+  version "1.42.0"
+  resolved "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.42.0.tgz#eee5c15222042b85340ce8e497a70c8c4a48fba6"
+  integrity sha512-JqgvmI2gIEedB+BvfG7kXkxc5o38TI1VwdQTgUW5hbr0631AgKs/hrpWqcUQ9aNQFwTyzaKWPb0vF8bDitCF6A==
   dependencies:
-    "@jsii/check-node" "1.41.0"
-    "@jsii/spec" "^1.41.0"
+    "@jsii/check-node" "1.42.0"
+    "@jsii/spec" "^1.42.0"
     clone "^2.1.2"
-    codemaker "^1.41.0"
+    codemaker "^1.42.0"
     commonmark "^0.30.0"
     escape-string-regexp "^4.0.0"
     fs-extra "^9.1.0"
-    jsii-reflect "^1.41.0"
-    jsii-rosetta "^1.41.0"
+    jsii-reflect "^1.42.0"
+    jsii-rosetta "^1.42.0"
     semver "^7.3.5"
     spdx-license-list "^6.4.0"
     xmlbuilder "^15.1.1"
     yargs "^16.2.0"
 
-jsii-reflect@^1.41.0:
-  version "1.41.0"
-  resolved "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.41.0.tgz#3c8fbcbbb7e2853b7c2a59384524ccbd2d9d832c"
-  integrity sha512-KQaAXQ38hyREs7IuBChZldSyvW1gezHRezGKGc6BZILwlIX330F3GIauJ2rJKJinh/Lo/DlMfd0k1mxdBz/W9A==
+jsii-reflect@^1.42.0:
+  version "1.42.0"
+  resolved "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.42.0.tgz#cab5e6ef64b0ae678efaabf10cefdb76c55818b5"
+  integrity sha512-gwVZqk2vEnEEYfOU2awHaqZqJd9lA+rEBrlaiMlun42Ve2ZY5HMDBtP/DxgFJG68LCzdlS0xQuHleuBlLYWy0A==
   dependencies:
-    "@jsii/check-node" "1.41.0"
-    "@jsii/spec" "^1.41.0"
+    "@jsii/check-node" "1.42.0"
+    "@jsii/spec" "^1.42.0"
     colors "^1.4.0"
     fs-extra "^9.1.0"
-    oo-ascii-tree "^1.41.0"
+    oo-ascii-tree "^1.42.0"
     yargs "^16.2.0"
 
-jsii-rosetta@^1.41.0:
-  version "1.41.0"
-  resolved "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.41.0.tgz#ddf3f49738489d8330aa4eff96f0a9c8c811792d"
-  integrity sha512-wSjMqRBhjBKB8kx+gIXE7YXoiOlTFH/ugksHz2K4UwqriPmEHue8b7LkV3d/mD8xuhXWS6ekGAz67Gd1RSB7Sg==
+jsii-rosetta@^1.42.0:
+  version "1.42.0"
+  resolved "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.42.0.tgz#84f80a91446b0a6e4ed8c981b1807eb7fce0b79e"
+  integrity sha512-F7GLNdoHBAYN4eqw7c6Tv12lqGOoMazsjuXDJRubjjbbwZ0tM6a78rHhrZwE4w1XV7mIkTxKmkj4DnbSIPW8wg==
   dependencies:
-    "@jsii/check-node" "1.41.0"
-    "@jsii/spec" "^1.41.0"
+    "@jsii/check-node" "1.42.0"
+    "@jsii/spec" "^1.42.0"
     "@xmldom/xmldom" "^0.7.5"
     commonmark "^0.30.0"
     fs-extra "^9.1.0"
@@ -6751,13 +6742,13 @@ jsii-rosetta@^1.41.0:
     workerpool "^6.1.5"
     yargs "^16.2.0"
 
-jsii@^1.41.0:
-  version "1.41.0"
-  resolved "https://registry.npmjs.org/jsii/-/jsii-1.41.0.tgz#926e033d7ba57c65d6d070dee1d4d19da0fa9508"
-  integrity sha512-5pjfWjSaMzE+mkpW//llBSGLcXJGNjE0KFSf73USPZTfJC09dBEJ4KJM85SogCNnWHwG5QecEpZStxNvt8GI7g==
+jsii@^1.42.0:
+  version "1.42.0"
+  resolved "https://registry.npmjs.org/jsii/-/jsii-1.42.0.tgz#2f8a534c9f981149f4455ec1272bfab7ba1fa6a3"
+  integrity sha512-Ctbaudn3t3wJ3ihsgCLuEjQGM5CfZl1PJDXfOlELUV6ELwTbvT3TCbyVdt/CCWTOObigQR8OftAB3jl7ymqd3w==
   dependencies:
-    "@jsii/check-node" "1.41.0"
-    "@jsii/spec" "^1.41.0"
+    "@jsii/check-node" "1.42.0"
+    "@jsii/spec" "^1.42.0"
     case "^1.6.3"
     colors "^1.4.0"
     deep-equal "^2.0.5"
@@ -6951,9 +6942,9 @@ lambda-tester@^3.6.0:
     vandium-utils "^1.1.1"
 
 lazystream@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4"
-  integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=
+  version "1.0.1"
+  resolved "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638"
+  integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==
   dependencies:
     readable-stream "^2.0.5"
 
@@ -7293,12 +7284,12 @@ make-runnable@^1.3.10:
     bluebird "^3.5.0"
     yargs "^16.2.0"
 
-makeerror@1.0.x:
-  version "1.0.11"
-  resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
-  integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=
+makeerror@1.0.12:
+  version "1.0.12"
+  resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a"
+  integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==
   dependencies:
-    tmpl "1.0.x"
+    tmpl "1.0.5"
 
 map-cache@^0.2.2:
   version "0.2.2"
@@ -7450,10 +7441,10 @@ mime-types@^2.1.12, mime-types@~2.1.19:
   dependencies:
     mime-db "1.50.0"
 
-mime@^2.5.2:
-  version "2.5.2"
-  resolved "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe"
-  integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==
+mime@^2.6.0:
+  version "2.6.0"
+  resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367"
+  integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==
 
 mimic-fn@^2.1.0:
   version "2.1.0"
@@ -7707,10 +7698,10 @@ nise@^5.1.0:
     just-extend "^4.0.2"
     path-to-regexp "^1.7.0"
 
-nock@^13.1.3:
-  version "13.1.3"
-  resolved "https://registry.npmjs.org/nock/-/nock-13.1.3.tgz#110b005965654a8ffb798e87bad18b467bff15f9"
-  integrity sha512-YKj0rKQWMGiiIO+Y65Ut8OEgYM3PplLU2+GAhnPmqZdBd6z5IskgdBqWmjzA6lH3RF0S2a3wiAlrMOF5Iv2Jeg==
+nock@^13.1.4:
+  version "13.1.4"
+  resolved "https://registry.npmjs.org/nock/-/nock-13.1.4.tgz#367c917d4c532a889404b85ade92762c29e80262"
+  integrity sha512-hr5+mknLpIbTOXifB13lx9mAKF1zQPUCMh53Galx79ic5opvNOd55jiB0iGCp2xqh+hwnFbNE/ddBKHsJNQrbw==
   dependencies:
     debug "^4.1.0"
     json-stringify-safe "^5.0.1"
@@ -7718,9 +7709,9 @@ nock@^13.1.3:
     propagate "^2.0.0"
 
 node-fetch@^2.6.1:
-  version "2.6.5"
-  resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd"
-  integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==
+  version "2.6.6"
+  resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89"
+  integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==
   dependencies:
     whatwg-url "^5.0.0"
 
@@ -7786,10 +7777,10 @@ node-preload@^0.2.1:
   dependencies:
     process-on-spawn "^1.0.0"
 
-node-releases@^1.1.77:
-  version "1.1.77"
-  resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.77.tgz#50b0cfede855dd374e7585bf228ff34e57c1c32e"
-  integrity sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==
+node-releases@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5"
+  integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==
 
 nopt@^4.0.1:
   version "4.0.3"
@@ -8096,10 +8087,10 @@ onetime@^5.1.0, onetime@^5.1.2:
   dependencies:
     mimic-fn "^2.1.0"
 
-oo-ascii-tree@^1.41.0:
-  version "1.41.0"
-  resolved "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.41.0.tgz#88883d2b8446ded7082a96faf3294e1092aeeb46"
-  integrity sha512-WxQIFO+JMCIJBlIMUATsp+PW5kqDMy2CD7u5uC9qQk29XInUMO+RN7/QVZJsPHO3o73eJFN9CFc9XDWQJwVKBQ==
+oo-ascii-tree@^1.42.0:
+  version "1.42.0"
+  resolved "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.42.0.tgz#e9ab47834b004ec2789a5e8b3e477b3fac770804"
+  integrity sha512-qlynjsWdGidfoWT2uEIr0iNsNmHU2ZhKwtjpJw4VSd3jlxoDpWDDmd5cud/ZBhFT2F1UFSbz+Gl9YtlPYMgQ5Q==
 
 open@^7.4.2:
   version "7.4.2"
@@ -8471,10 +8462,10 @@ performance-now@^2.1.0:
   resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
   integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
 
-picocolors@^0.2.1:
-  version "0.2.1"
-  resolved "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f"
-  integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==
+picocolors@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
+  integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
 
 picomatch@^2.0.4, picomatch@^2.2.3:
   version "2.3.0"
@@ -9526,15 +9517,15 @@ stack-utils@^2.0.2, stack-utils@^2.0.3:
   dependencies:
     escape-string-regexp "^2.0.0"
 
-standard-version@^9.3.1:
-  version "9.3.1"
-  resolved "https://registry.npmjs.org/standard-version/-/standard-version-9.3.1.tgz#786c16c318847f58a31a2434f97e8db33a635853"
-  integrity sha512-5qMxXw/FxLouC5nANyx/5RY1kiorJx9BppUso8gN07MG64q2uLRmrPb4KfXp3Ql4s/gxjZwZ89e0FwxeLubGww==
+standard-version@^9.3.2:
+  version "9.3.2"
+  resolved "https://registry.npmjs.org/standard-version/-/standard-version-9.3.2.tgz#28db8c1be66fd2d736f28f7c5de7619e64cd6dab"
+  integrity sha512-u1rfKP4o4ew7Yjbfycv80aNMN2feTiqseAhUhrrx2XtdQGmu7gucpziXe68Z4YfHVqlxVEzo4aUA0Iu3VQOTgQ==
   dependencies:
     chalk "^2.4.2"
     conventional-changelog "3.1.24"
     conventional-changelog-config-spec "2.1.0"
-    conventional-changelog-conventionalcommits "4.5.0"
+    conventional-changelog-conventionalcommits "4.6.1"
     conventional-recommended-bump "6.1.0"
     detect-indent "^6.0.0"
     detect-newline "^3.1.0"
@@ -9582,7 +9573,7 @@ string-length@^4.0.1:
     char-regex "^1.0.2"
     strip-ansi "^6.0.0"
 
-string-width@*, string-width@^1.0.1, "string-width@^1.0.2 || 2", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+string-width@*, string-width@^1.0.1, "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
   version "4.2.3"
   resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
   integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -9873,7 +9864,7 @@ tmp@^0.0.33:
   dependencies:
     os-tmpdir "~1.0.2"
 
-tmpl@1.0.x:
+tmpl@1.0.5:
   version "1.0.5"
   resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
   integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==
@@ -9981,9 +9972,9 @@ ts-mock-imports@^1.3.7:
   integrity sha512-zy4B3QSGaOhjaX9j0h9YKwM1oHG4Kd1KIUJBeXlXIQrFnATNLgh4+NyRcaAHsPeqwe3TWeRtHXkNXPxySEKk3w==
 
 ts-node@^10.2.1:
-  version "10.3.0"
-  resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.3.0.tgz#a797f2ed3ff50c9a5d814ce400437cb0c1c048b4"
-  integrity sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw==
+  version "10.4.0"
+  resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7"
+  integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==
   dependencies:
     "@cspotcode/source-map-support" "0.7.0"
     "@tsconfig/node10" "^1.0.7"
@@ -10149,9 +10140,9 @@ uc.micro@^1.0.1, uc.micro@^1.0.5:
   integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
 
 uglify-js@^3.1.4:
-  version "3.14.2"
-  resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz#d7dd6a46ca57214f54a2d0a43cad0f35db82ac99"
-  integrity sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==
+  version "3.14.3"
+  resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.3.tgz#c0f25dfea1e8e5323eccf59610be08b6043c15cf"
+  integrity sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==
 
 uid-number@0.0.6:
   version "0.0.6"
@@ -10347,9 +10338,9 @@ verror@1.10.0:
     extsprintf "^1.2.0"
 
 vm2@^3.9.3:
-  version "3.9.4"
-  resolved "https://registry.npmjs.org/vm2/-/vm2-3.9.4.tgz#2e118290fefe7bd8ea09ebe2f5faf53730dbddaa"
-  integrity sha512-sOdharrJ7KEePIpHekiWaY1DwgueuiBeX/ZBJUPgETsVlJsXuEx0K0/naATq2haFvJrvZnRiORQRubR0b7Ye6g==
+  version "3.9.5"
+  resolved "https://registry.npmjs.org/vm2/-/vm2-3.9.5.tgz#5288044860b4bbace443101fcd3bddb2a0aa2496"
+  integrity sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng==
 
 w3c-hr-time@^1.0.2:
   version "1.0.2"
@@ -10366,11 +10357,11 @@ w3c-xmlserializer@^2.0.0:
     xml-name-validator "^3.0.0"
 
 walker@^1.0.7, walker@~1.0.5:
-  version "1.0.7"
-  resolved "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
-  integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=
+  version "1.0.8"
+  resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f"
+  integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==
   dependencies:
-    makeerror "1.0.x"
+    makeerror "1.0.12"
 
 wcwidth@^1.0.0:
   version "1.0.1"
@@ -10476,11 +10467,11 @@ which@^2.0.1, which@^2.0.2:
     isexe "^2.0.0"
 
 wide-align@^1.1.0:
-  version "1.1.3"
-  resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
-  integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==
+  version "1.1.5"
+  resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3"
+  integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==
   dependencies:
-    string-width "^1.0.2 || 2"
+    string-width "^1.0.2 || 2 || 3 || 4"
 
 windows-release@^3.1.0:
   version "3.3.3"

From e4616010c1915206758be3bf4cd6da9f14d2101a Mon Sep 17 00:00:00 2001
From: kaylanm <1063516+kaylanm@users.noreply.github.com>
Date: Wed, 3 Nov 2021 11:05:45 -0400
Subject: [PATCH 115/148] feat(eks): expose FargateCluster's defaultProfile
 (#17130)

Expose FargateCluster's defaultProfile.

Fixes #16149

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-eks/README.md              | 2 ++
 packages/@aws-cdk/aws-eks/lib/fargate-cluster.ts | 9 +++++++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/packages/@aws-cdk/aws-eks/README.md b/packages/@aws-cdk/aws-eks/README.md
index 3b04f5d9e7f61..cd6e324ecf788 100644
--- a/packages/@aws-cdk/aws-eks/README.md
+++ b/packages/@aws-cdk/aws-eks/README.md
@@ -342,6 +342,8 @@ const cluster = new eks.FargateCluster(this, 'MyCluster', {
 });
 ```
 
+`FargateCluster` will create a default `FargateProfile` which can be accessed via the cluster's `defaultProfile` property. The created profile can also be customized by passing options as with `addFargateProfile`.
+
 **NOTE**: Classic Load Balancers and Network Load Balancers are not supported on
 pods running on Fargate. For ingress, we recommend that you use the [ALB Ingress
 Controller](https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html)
diff --git a/packages/@aws-cdk/aws-eks/lib/fargate-cluster.ts b/packages/@aws-cdk/aws-eks/lib/fargate-cluster.ts
index 11036875a9d30..022d6bc6ecdbf 100644
--- a/packages/@aws-cdk/aws-eks/lib/fargate-cluster.ts
+++ b/packages/@aws-cdk/aws-eks/lib/fargate-cluster.ts
@@ -1,6 +1,6 @@
 import { Construct } from 'constructs';
 import { Cluster, ClusterOptions, CoreDnsComputeType } from './cluster';
-import { FargateProfileOptions } from './fargate-profile';
+import { FargateProfile, FargateProfileOptions } from './fargate-profile';
 
 /**
  * Configuration props for EKS Fargate.
@@ -23,6 +23,11 @@ export interface FargateClusterProps extends ClusterOptions {
  * `addFargateProfile`.
  */
 export class FargateCluster extends Cluster {
+  /**
+   * Fargate Profile that was created with the cluster.
+   */
+  public readonly defaultProfile: FargateProfile;
+
   constructor(scope: Construct, id: string, props: FargateClusterProps) {
     super(scope, id, {
       ...props,
@@ -31,7 +36,7 @@ export class FargateCluster extends Cluster {
       version: props.version,
     });
 
-    this.addFargateProfile(
+    this.defaultProfile = this.addFargateProfile(
       props.defaultProfile?.fargateProfileName ?? (props.defaultProfile ? 'custom' : 'default'),
       props.defaultProfile ?? {
         selectors: [

From e2f2a972df588ab760bcd7b6f3c9d2f49741f489 Mon Sep 17 00:00:00 2001
From: Rico Huijbers 
Date: Wed, 3 Nov 2021 16:59:36 +0100
Subject: [PATCH 116/148] chore: activate 'rosetta infuse' feature (#17191)
 (#17305)

`jsii-rosetta infuse` will modify all the assemblies in-place to
add examples to types that don't have examples yet.

This feature depends on jsii 1.41, and should not be merged before
jsii has been upgraded to that version (either by #17187 or by #17190).

Depends-On: #17190

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 pack.sh | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/pack.sh b/pack.sh
index 168a17f972406..3c2d7dbce6c1a 100755
--- a/pack.sh
+++ b/pack.sh
@@ -39,12 +39,17 @@ function lerna_scopes() {
 # Compile examples with respect to "decdk" directory, as all packages will
 # be symlinked there so they can all be included.
 echo "Extracting code samples" >&2
-node --experimental-worker $(which $ROSETTA) \
+$ROSETTA extract \
   --compile \
   --output samples.tabl.json \
   --directory packages/decdk \
   $(cat $TMPDIR/jsii.txt)
 
+echo "Infusing examples back into assemblies" >&2
+$ROSETTA infuse \
+  samples.tabl.json \
+  $(cat $TMPDIR/jsii.txt)
+
 # Jsii packaging (all at once using jsii-pacmak)
 echo "Packaging jsii modules" >&2
 $PACMAK \

From 89d8fc7ef9649c66a233ee2207b3e7999b3c87ab Mon Sep 17 00:00:00 2001
From: Paolo Lazzari 
Date: Wed, 3 Nov 2021 17:26:26 +0000
Subject: [PATCH 117/148] docs: fix typo in CONTRIBUTING.md (#17303)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 CONTRIBUTING.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b6568c7be1263..5af7da4ecc25a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -113,7 +113,7 @@ $ yarn build
 $ yarn test
 ```
 
-However, if you wish to build the the entire repository, the following command will achieve this.
+However, if you wish to build the entire repository, the following command will achieve this.
 
 ```console
 cd 

From e05bd012d0d3e956dfe75418cc9a428d57bf1ad6 Mon Sep 17 00:00:00 2001
From: Eli Polonsky 
Date: Wed, 3 Nov 2021 20:20:03 +0200
Subject: [PATCH 118/148] chore: integ failures due to unbound variable on
 `FRAMEWORK_VERSION` (#17308)

Follow up fix for https://github.com/aws/aws-cdk/pull/17276

```console
export CANDIDATE_VERSION=1.131.0-rc.0
--
690 | + CANDIDATE_VERSION=1.131.0-rc.0
691 | /codebuild/output/src644443490/src/package/test/integ/run-against-dist: line 29: FRAMEWORK_VERSION: unbound variable
692 | ++ run_traps
```

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/aws-cdk/test/integ/run-against-dist    | 2 +-
 packages/aws-cdk/test/integ/run-against-release | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/aws-cdk/test/integ/run-against-dist b/packages/aws-cdk/test/integ/run-against-dist
index 0cd683b112dca..c7ade80dbb1f3 100755
--- a/packages/aws-cdk/test/integ/run-against-dist
+++ b/packages/aws-cdk/test/integ/run-against-dist
@@ -26,7 +26,7 @@ fi
 export CANDIDATE_VERSION=$(node -p "require('${dist_root}/build.json').version")
 
 # FRAMEWORK_VERSION is the version that will be 'npm install'ed by the tests
-if [[ "${FRAMEWORK_VERSION}" = "" ]]; then
+if [[ "${FRAMEWORK_VERSION:-}" = "" ]]; then
   export FRAMEWORK_VERSION=${CANDIDATE_VERSION}
 fi
 export TEST_RUNNER=dist
diff --git a/packages/aws-cdk/test/integ/run-against-release b/packages/aws-cdk/test/integ/run-against-release
index b3ebe1e4fc409..366fd081f5380 100755
--- a/packages/aws-cdk/test/integ/run-against-release
+++ b/packages/aws-cdk/test/integ/run-against-release
@@ -15,7 +15,7 @@ mkdir -p $npmws
 (cd $npmws && npm install aws-cdk)
 
 # FRAMEWORK_VERSION is the version that will be 'npm install'ed by the tests
-if [[ "${FRAMEWORK_VERSION}" = "" ]]; then
+if [[ "${FRAMEWORK_VERSION:-}" = "" ]]; then
   cli_version=$(cd $npmws && node -p "require('aws-cdk/package.json').version")
   export FRAMEWORK_VERSION=${cli_version}
 fi

From af61fa64003e74c680be6dd2437d2dc40cfe4552 Mon Sep 17 00:00:00 2001
From: Madeline Kusters <80541297+madeline-k@users.noreply.github.com>
Date: Wed, 3 Nov 2021 12:14:31 -0700
Subject: [PATCH 119/148] chore(CDK V2 canaries): allow canary tests to run
 with a specific aws-cdk version (#17285)

If an environment variable, `$RELEASE_TAG` is defined, it will be appended to the end of the `npm install aws-cdk@` command. This will allow us to run canaries that test against v2 by specifying `RELEASE_TAG=next` in the environment variables. If `$RELEASE_TAG` is not defined, `npm install aws-cdk@latest` will be used.

This PR also includes a comment in `release-notes.ts` that the v2 publishing verification canary is dependent on the format of the release notes.

part of #16593, see https://github.com/cdklabs/cdk-ops/pull/1769

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/aws-cdk/test/integ/run-against-release | 2 +-
 tools/@aws-cdk/cdk-release/lib/release-notes.ts | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/packages/aws-cdk/test/integ/run-against-release b/packages/aws-cdk/test/integ/run-against-release
index 366fd081f5380..1e4c0a8b3aba1 100755
--- a/packages/aws-cdk/test/integ/run-against-release
+++ b/packages/aws-cdk/test/integ/run-against-release
@@ -12,7 +12,7 @@ rm -rf $npmws
 mkdir -p $npmws
 
 # Install the CLI and put it on the PATH
-(cd $npmws && npm install aws-cdk)
+(cd $npmws && npm install aws-cdk@${RELEASE_TAG:-latest})
 
 # FRAMEWORK_VERSION is the version that will be 'npm install'ed by the tests
 if [[ "${FRAMEWORK_VERSION:-}" = "" ]]; then
diff --git a/tools/@aws-cdk/cdk-release/lib/release-notes.ts b/tools/@aws-cdk/cdk-release/lib/release-notes.ts
index 4647b4db71533..694613b6c7a0f 100644
--- a/tools/@aws-cdk/cdk-release/lib/release-notes.ts
+++ b/tools/@aws-cdk/cdk-release/lib/release-notes.ts
@@ -40,6 +40,8 @@ async function releaseNoteContents(currentVersion: Versions, opts: ReleaseNotesO
   return [
     stableChangelogContents,
     '---',
+    // DO NOT CHANGE THE FORMAT OF THE FOLLOWING LINE. This will cause the v2 publishing verification canary to skip verification of Alpha modules.
+    // See https://github.com/cdklabs/cdk-ops/pull/1769.
     `## Alpha modules (${currentVersion.alphaVersion})`,
     alphaChangelogContents,
   ].join('\n');

From ca208058256703759ae5e35d04194edbdc6b1756 Mon Sep 17 00:00:00 2001
From: Cory Hall <43035978+corymhall@users.noreply.github.com>
Date: Wed, 3 Nov 2021 17:44:41 -0400
Subject: [PATCH 120/148] chore(init-templates): move init templates to new
 assertions module (#17062)

this updates both v1 and v2 init templates to use the new assertions
module. I also added tests for the python app templates since those were
missing.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../v1/app/go/%name%.template.go              | 12 ++--
 .../v1/app/go/%name%_test.template.go         | 40 +++++------
 .../init-templates/v1/app/go/go.template.mod  |  4 --
 .../v1/app/java/pom.template.xml              | 18 ++---
 .../%name.PascalCased%Stack.template.java     |  7 ++
 .../%name.PascalCased%Test.template.java      | 40 +++++------
 .../javascript/lib/%name%-stack.template.js   |  6 ++
 .../v1/app/javascript/package.template.json   |  2 +-
 .../javascript/test/%name%.test.template.js   | 27 ++++---
 .../%name.PythonModule%_stack.template.py     | 11 ++-
 .../v1/app/python/requirements-dev.txt        |  1 +
 .../v1/app/python/requirements.template.txt   |  2 +
 .../v1/app/python/requirements.txt            |  1 -
 .../v1/app/python/setup.template.py           | 43 -----------
 .../v1/app/python/tests/__init__.py           |  0
 .../v1/app/python/tests/unit/__init__.py      |  0
 ...test_%name.PythonModule%_stack.template.py | 18 +++++
 .../typescript/lib/%name%-stack.template.ts   |  6 ++
 .../v1/app/typescript/package.template.json   |  2 +-
 .../typescript/test/%name%.test.template.ts   | 26 ++++---
 .../v1/lib/typescript/lib/index.template.ts   |  6 ++
 .../v1/lib/typescript/package.template.json   |  2 +-
 .../typescript/test/%name%.test.template.ts   | 29 ++++----
 .../v1/sample-app/go/%name%.template.go       | 71 +++++++++++++++++++
 .../v1/sample-app/go/%name%_test.template.go  | 25 +++++++
 .../v1/sample-app/go/.template.gitignore      | 19 +++++
 .../init-templates/v1/sample-app/go/README.md | 14 ++++
 .../v1/sample-app/go/cdk.template.json        |  3 +
 .../v1/sample-app/go/go.template.mod          |  9 +++
 .../v1/sample-app/java/pom.template.xml       | 18 ++---
 .../%name.PascalCased%StackTest.template.java | 19 +++--
 .../javascript/package.template.json          |  2 +-
 .../javascript/test/%name%.test.template.js   | 22 +++---
 .../v1/sample-app/python/requirements-dev.txt |  1 +
 .../python/requirements.template.txt          |  7 ++
 .../v1/sample-app/python/requirements.txt     |  2 -
 .../v1/sample-app/python/setup.template.py    | 48 -------------
 ...test_%name.PythonModule%_stack.template.py | 25 ++++---
 .../typescript/package.template.json          |  2 +-
 .../typescript/test/%name%.test.template.ts   | 18 +++--
 .../v2/app/go/%name%.template.go              | 12 ++--
 .../v2/app/go/%name%_test.template.go         | 40 +++++------
 .../init-templates/v2/app/go/go.template.mod  |  5 +-
 .../v2/app/java/pom.template.xml              | 18 ++---
 .../%name.PascalCased%Stack.template.java     |  7 ++
 .../%name.PascalCased%Test.template.java      | 41 +++++------
 .../javascript/lib/%name%-stack.template.js   |  8 ++-
 .../v2/app/javascript/package.template.json   |  1 +
 .../javascript/test/%name%.test.template.js   | 24 ++++---
 .../%name.PythonModule%_stack.template.py     | 12 +++-
 .../v2/app/python/requirements-dev.txt        |  1 +
 .../v2/app/python/requirements.template.txt   |  3 +
 .../v2/app/python/requirements.txt            |  1 -
 .../v2/app/python/setup.template.py           | 44 ------------
 .../v2/app/python/tests/__init__.py           |  0
 .../v2/app/python/tests/unit/__init__.py      |  0
 ...test_%name.PythonModule%_stack.template.py | 15 ++++
 .../typescript/lib/%name%-stack.template.ts   |  6 ++
 .../v2/app/typescript/package.template.json   |  1 +
 .../typescript/test/%name%.test.template.ts   | 24 ++++---
 .../v2/lib/typescript/lib/index.template.ts   |  6 ++
 .../v2/lib/typescript/package.template.json   |  1 +
 .../typescript/test/%name%.test.template.ts   | 26 ++++---
 .../v2/sample-app/go/%name%.template.go       | 71 +++++++++++++++++++
 .../v2/sample-app/go/%name%_test.template.go  | 25 +++++++
 .../v2/sample-app/go/.template.gitignore      | 19 +++++
 .../init-templates/v2/sample-app/go/README.md | 14 ++++
 .../v2/sample-app/go/cdk.template.json        |  3 +
 .../v2/sample-app/go/go.template.mod          | 10 +++
 .../v2/sample-app/java/pom.template.xml       | 18 ++---
 .../%name.PascalCased%StackTest.template.java | 20 +++---
 .../javascript/package.template.json          |  1 +
 .../javascript/test/%name%.test.template.js   | 18 +++--
 .../v2/sample-app/python/requirements-dev.txt |  1 +
 .../python/requirements.template.txt          |  3 +
 .../v2/sample-app/python/requirements.txt     |  2 -
 .../v2/sample-app/python/setup.template.py    | 44 ------------
 ...test_%name.PythonModule%_stack.template.py | 24 ++++---
 .../typescript/package.template.json          |  1 +
 .../typescript/test/%name%.test.template.ts   | 19 +++--
 packages/aws-cdk/test/integ/init/test-go.sh   |  6 +-
 packages/aws-cdk/test/integ/init/test-java.sh |  1 +
 .../aws-cdk/test/integ/init/test-python.sh    |  2 +
 83 files changed, 725 insertions(+), 481 deletions(-)
 create mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/requirements-dev.txt
 create mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/requirements.template.txt
 delete mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/requirements.txt
 delete mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/setup.template.py
 create mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/tests/__init__.py
 create mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/__init__.py
 create mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/test_%name.PythonModule%_stack.template.py
 create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%.template.go
 create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%_test.template.go
 create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/go/.template.gitignore
 create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/go/README.md
 create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/go/cdk.template.json
 create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/go/go.template.mod
 create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements-dev.txt
 create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.template.txt
 delete mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.txt
 delete mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/python/setup.template.py
 create mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/requirements-dev.txt
 create mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt
 delete mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/requirements.txt
 delete mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/setup.template.py
 create mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/tests/__init__.py
 create mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/__init__.py
 create mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/test_%name.PythonModule%_stack.template.py
 create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%.template.go
 create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%_test.template.go
 create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/go/.template.gitignore
 create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/go/README.md
 create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/go/cdk.template.json
 create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/go/go.template.mod
 create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements-dev.txt
 create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt
 delete mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.txt
 delete mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/python/setup.template.py

diff --git a/packages/aws-cdk/lib/init-templates/v1/app/go/%name%.template.go b/packages/aws-cdk/lib/init-templates/v1/app/go/%name%.template.go
index 24a2b0e90b616..742ed4c64ce7b 100644
--- a/packages/aws-cdk/lib/init-templates/v1/app/go/%name%.template.go
+++ b/packages/aws-cdk/lib/init-templates/v1/app/go/%name%.template.go
@@ -2,9 +2,9 @@ package main
 
 import (
 	"github.com/aws/aws-cdk-go/awscdk"
-	"github.com/aws/aws-cdk-go/awscdk/awssns"
+	// "github.com/aws/aws-cdk-go/awscdk/awssqs"
 	"github.com/aws/constructs-go/constructs/v3"
-	"github.com/aws/jsii-runtime-go"
+	// "github.com/aws/jsii-runtime-go"
 )
 
 type %name.PascalCased%StackProps struct {
@@ -20,10 +20,10 @@ func New%name.PascalCased%Stack(scope constructs.Construct, id string, props *%n
 
 	// The code that defines your stack goes here
 
-	// as an example, here's how you would define an AWS SNS topic:
-	awssns.NewTopic(stack, jsii.String("MyTopic"), &awssns.TopicProps{
-		DisplayName: jsii.String("MyCoolTopic"),
-	})
+	// example resource
+	// queue := awssqs.NewQueue(stack, jsii.String("%name.PascalCased%Queue"), &awssqs.QueueProps{
+	// 	VisibilityTimeout: awscdk.Duration_Seconds(jsii.Number(300)),
+	// })
 
 	return stack
 }
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/go/%name%_test.template.go b/packages/aws-cdk/lib/init-templates/v1/app/go/%name%_test.template.go
index c0534249b6282..78742540bc2f7 100644
--- a/packages/aws-cdk/lib/init-templates/v1/app/go/%name%_test.template.go
+++ b/packages/aws-cdk/lib/init-templates/v1/app/go/%name%_test.template.go
@@ -1,28 +1,26 @@
 package main
 
-import (
-	"encoding/json"
-	"testing"
+// import (
+// 	"testing"
 
-	"github.com/aws/aws-cdk-go/awscdk"
-	"github.com/stretchr/testify/assert"
-	"github.com/tidwall/gjson"
-)
+// 	"github.com/aws/aws-cdk-go/awscdk"
+// 	"github.com/aws/aws-cdk-go/awscdk/assertions"
+// 	"github.com/aws/jsii-runtime-go"
+// )
 
-func Test%name.PascalCased%Stack(t *testing.T) {
-	// GIVEN
-	app := awscdk.NewApp(nil)
+// example tests. To run these tests, uncomment this file along with the
+// example resource in %name%_test.go
+// func Test%name.PascalCased%Stack(t *testing.T) {
+// 	// GIVEN
+// 	app := awscdk.NewApp(nil)
 
-	// WHEN
-	stack := New%name.PascalCased%Stack(app, "MyStack", nil)
+// 	// WHEN
+// 	stack := New%name.PascalCased%Stack(app, "MyStack", nil)
 
-	// THEN
-	bytes, err := json.Marshal(app.Synth(nil).GetStackArtifact(stack.ArtifactId()).Template())
-	if err != nil {
-		t.Error(err)
-	}
+// 	// THEN
+// 	template := assertions.Template_FromStack(stack)
 
-	template := gjson.ParseBytes(bytes)
-	displayName := template.Get("Resources.MyTopic86869434.Properties.DisplayName").String()
-	assert.Equal(t, "MyCoolTopic", displayName)
-}
+// 	template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{
+// 		"VisibilityTimeout": 300,
+// 	})
+// }
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/go/go.template.mod b/packages/aws-cdk/lib/init-templates/v1/app/go/go.template.mod
index a1dcb391c1614..5dbef39984826 100644
--- a/packages/aws-cdk/lib/init-templates/v1/app/go/go.template.mod
+++ b/packages/aws-cdk/lib/init-templates/v1/app/go/go.template.mod
@@ -6,8 +6,4 @@ require (
   github.com/aws/aws-cdk-go/awscdk v%cdk-version%-devpreview
   github.com/aws/constructs-go/constructs/v3 v3.3.71
   github.com/aws/jsii-runtime-go v1.26.0
-
-  // for testing
-  github.com/tidwall/gjson v1.7.4
-  github.com/stretchr/testify v1.7.0
 )
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/java/pom.template.xml b/packages/aws-cdk/lib/init-templates/v1/app/java/pom.template.xml
index fb0b6cf828aaf..b8b00e798209c 100644
--- a/packages/aws-cdk/lib/init-templates/v1/app/java/pom.template.xml
+++ b/packages/aws-cdk/lib/init-templates/v1/app/java/pom.template.xml
@@ -43,24 +43,18 @@
             core
             ${cdk.version}
         
-
         
-          org.junit.jupiter
-          junit-jupiter-api
-          ${junit.version}
-          test
+            software.amazon.awscdk
+            assertions
+            ${cdk.version}
+            test
         
+
         
           org.junit.jupiter
-          junit-jupiter-engine
+          junit-jupiter
           ${junit.version}
           test
         
-        
-            org.assertj
-            assertj-core
-            3.18.1
-            test
-        
     
 
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java b/packages/aws-cdk/lib/init-templates/v1/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java
index e0d4b5a0be8b1..a4dbab1dbd8b9 100644
--- a/packages/aws-cdk/lib/init-templates/v1/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java
+++ b/packages/aws-cdk/lib/init-templates/v1/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java
@@ -3,6 +3,8 @@
 import software.amazon.awscdk.core.Construct;
 import software.amazon.awscdk.core.Stack;
 import software.amazon.awscdk.core.StackProps;
+// import software.amazon.awscdk.services.sqs.Queue;
+// import software.amazon.awscdk.core.Duration;
 
 public class %name.PascalCased%Stack extends Stack {
     public %name.PascalCased%Stack(final Construct scope, final String id) {
@@ -13,5 +15,10 @@ public class %name.PascalCased%Stack extends Stack {
         super(scope, id, props);
 
         // The code that defines your stack goes here
+
+        // example resource
+        // final Queue queue = Queue.Builder.create(this, "%name.PascalCased%Queue")
+        //         .visibilityTimeout(Duration.seconds(300))
+        //         .build();
     }
 }
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java b/packages/aws-cdk/lib/init-templates/v1/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java
index 9494caf63d628..f96ca04987f31 100644
--- a/packages/aws-cdk/lib/init-templates/v1/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java
+++ b/packages/aws-cdk/lib/init-templates/v1/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java
@@ -1,28 +1,26 @@
-package com.myorg;
+// package com.myorg;
 
-import software.amazon.awscdk.core.App;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
+// import software.amazon.awscdk.core.App;
+// import software.amazon.awscdk.assertions.Template;
+// import java.io.IOException;
 
-import java.io.IOException;
+// import java.util.Map;
 
-import org.junit.jupiter.api.Test;
-import static org.assertj.core.api.Assertions.assertThat;
+// import org.junit.jupiter.api.Test;
 
-public class %name.PascalCased%Test {
-    private final static ObjectMapper JSON =
-        new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true);
+// example test. To run these tests, uncomment this file, along with the
+// example resource in java/src/main/java/com/myorg/%name.PascalCased%Stack.java
+// public class %name.PascalCased%Test {
 
-    @Test
-    public void testStack() throws IOException {
-        App app = new App();
-        %name.PascalCased%Stack stack = new %name.PascalCased%Stack(app, "test");
+//     @Test
+//     public void testStack() throws IOException {
+//         App app = new App();
+//         %name.PascalCased%Stack stack = new %name.PascalCased%Stack(app, "test");
 
-        // synthesize the stack to a CloudFormation template
-        JsonNode actual = JSON.valueToTree(app.synth().getStackArtifact(stack.getArtifactId()).getTemplate());
+//         Template template = Template.fromStack(stack);
 
-        // Update once resources have been added to the stack
-        assertThat(actual.get("Resources")).isNull();
-    }
-}
+//         template.hasResourceProperties("AWS::SQS::Queue", Map.of(
+//             "VisibilityTimeout", 300
+//          ));
+//     }
+// }
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/javascript/lib/%name%-stack.template.js b/packages/aws-cdk/lib/init-templates/v1/app/javascript/lib/%name%-stack.template.js
index 2c52c5f65244c..8004c54a568aa 100644
--- a/packages/aws-cdk/lib/init-templates/v1/app/javascript/lib/%name%-stack.template.js
+++ b/packages/aws-cdk/lib/init-templates/v1/app/javascript/lib/%name%-stack.template.js
@@ -1,4 +1,5 @@
 const cdk = require('@aws-cdk/core');
+// const sqs = require('@aws-cdk/aws-sqs');
 
 class %name.PascalCased%Stack extends cdk.Stack {
   /**
@@ -11,6 +12,11 @@ class %name.PascalCased%Stack extends cdk.Stack {
     super(scope, id, props);
 
     // The code that defines your stack goes here
+
+    // example resource
+    // const queue = new sqs.Queue(this, '%name.PascalCased%Queue', {
+    //   visibilityTimeout: cdk.Duration.seconds(300)
+    // });
   }
 }
 
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/javascript/package.template.json b/packages/aws-cdk/lib/init-templates/v1/app/javascript/package.template.json
index 5547dacf3a673..abe1218b79d96 100644
--- a/packages/aws-cdk/lib/init-templates/v1/app/javascript/package.template.json
+++ b/packages/aws-cdk/lib/init-templates/v1/app/javascript/package.template.json
@@ -10,7 +10,7 @@
     "test": "jest"
   },
   "devDependencies": {
-    "@aws-cdk/assert": "%cdk-version%",
+    "@aws-cdk/assertions": "%cdk-version%",
     "aws-cdk": "%cdk-version%",
     "jest": "^26.4.2"
   },
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/javascript/test/%name%.test.template.js b/packages/aws-cdk/lib/init-templates/v1/app/javascript/test/%name%.test.template.js
index 54e6bb172e0a9..514cd34e9faf1 100644
--- a/packages/aws-cdk/lib/init-templates/v1/app/javascript/test/%name%.test.template.js
+++ b/packages/aws-cdk/lib/init-templates/v1/app/javascript/test/%name%.test.template.js
@@ -1,13 +1,18 @@
-const { expect, matchTemplate, MatchStyle } = require('@aws-cdk/assert');
-const cdk = require('@aws-cdk/core');
-const %name.PascalCased% = require('../lib/%name%-stack');
+// const { Template } = require('@aws-cdk/assertions');
+// const cdk = require('@aws-cdk/core');
+// const %name.PascalCased% = require('../lib/%name%-stack');
 
-test('Empty Stack', () => {
-    const app = new cdk.App();
-    // WHEN
-    const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
-    // THEN
-    expect(stack).to(matchTemplate({
-      "Resources": {}
-    }, MatchStyle.EXACT))
+// example test. To run these tests, uncomment this file along with the
+// example resource in lib/%name%-stack.js
+test('SQS Queue Created', () => {
+//   const app = new cdk.App();
+//   // WHEN
+//   const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
+//   // THEN
+//   const template = Template.fromStack(stack);
+
+//   template.hasResourceProperties('AWS::SQS::Queue', {
+//     VisibilityTimeout: 300
+//   });
 });
+
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py b/packages/aws-cdk/lib/init-templates/v1/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py
index 6b4ed6e8ea6ed..9c5de032e839d 100644
--- a/packages/aws-cdk/lib/init-templates/v1/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py
+++ b/packages/aws-cdk/lib/init-templates/v1/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py
@@ -1,4 +1,7 @@
-from aws_cdk import core as cdk
+from aws_cdk import (
+    core as cdk
+    # aws_sqs as sqs,
+)
 
 # For consistency with other languages, `cdk` is the preferred import name for
 # the CDK's core module.  The following line also imports it as `core` for use
@@ -13,3 +16,9 @@ def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
         super().__init__(scope, construct_id, **kwargs)
 
         # The code that defines your stack goes here
+
+        # example resource
+        # queue = sqs.Queue(
+        #     self, "%name.PascalCased%Queue",
+        #     visibility_timeout=cdk.Duration.seconds(300),
+        # )
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/requirements-dev.txt b/packages/aws-cdk/lib/init-templates/v1/app/python/requirements-dev.txt
new file mode 100644
index 0000000000000..927094516e657
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v1/app/python/requirements-dev.txt
@@ -0,0 +1 @@
+pytest==6.2.5
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.template.txt b/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.template.txt
new file mode 100644
index 0000000000000..e14ce6e77e499
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.template.txt
@@ -0,0 +1,2 @@
+aws-cdk.core>=%cdk-version%,
+aws-cdk.assertions>=%cdk-version%,
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.txt b/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.txt
deleted file mode 100644
index d6e1198b1ab1f..0000000000000
--- a/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
--e .
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/setup.template.py b/packages/aws-cdk/lib/init-templates/v1/app/python/setup.template.py
deleted file mode 100644
index 113bf29e54755..0000000000000
--- a/packages/aws-cdk/lib/init-templates/v1/app/python/setup.template.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import setuptools
-
-
-with open("README.md") as fp:
-    long_description = fp.read()
-
-
-setuptools.setup(
-    name="%name.PythonModule%",
-    version="0.0.1",
-
-    description="An empty CDK Python app",
-    long_description=long_description,
-    long_description_content_type="text/markdown",
-
-    author="author",
-
-    package_dir={"": "%name.PythonModule%"},
-    packages=setuptools.find_packages(where="%name.PythonModule%"),
-
-    install_requires=[
-        "aws-cdk.core==%cdk-version%",
-    ],
-
-    python_requires=">=3.6",
-
-    classifiers=[
-        "Development Status :: 4 - Beta",
-
-        "Intended Audience :: Developers",
-
-        "Programming Language :: JavaScript",
-        "Programming Language :: Python :: 3 :: Only",
-        "Programming Language :: Python :: 3.6",
-        "Programming Language :: Python :: 3.7",
-        "Programming Language :: Python :: 3.8",
-
-        "Topic :: Software Development :: Code Generators",
-        "Topic :: Utilities",
-
-        "Typing :: Typed",
-    ],
-)
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/tests/__init__.py b/packages/aws-cdk/lib/init-templates/v1/app/python/tests/__init__.py
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/__init__.py b/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/__init__.py
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/test_%name.PythonModule%_stack.template.py b/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/test_%name.PythonModule%_stack.template.py
new file mode 100644
index 0000000000000..94f2234e02aa6
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/test_%name.PythonModule%_stack.template.py
@@ -0,0 +1,18 @@
+# from aws_cdk import (
+#         core,
+#         assertions
+#     )
+
+# from %name.PythonModule%.%name.PythonModule%_stack import %name.PascalCased%Stack
+
+
+# example tests. To run these tests, uncomment this file along with the example
+# resource in %name.PythonModule%/%name.PythonModule%_stack.py
+# def test_sqs_queue_created():
+#     app = core.App()
+#     stack = %name.PascalCased%Stack(app, "%name.StackName%")
+#     template = assertions.Template.from_stack(stack)
+
+#     template.has_resource_properties("AWS::SQS::Queue", {
+#         "VisibilityTimeout": 300
+#     })
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/typescript/lib/%name%-stack.template.ts b/packages/aws-cdk/lib/init-templates/v1/app/typescript/lib/%name%-stack.template.ts
index 80fa43a59ea24..82fd9a48ac0dd 100644
--- a/packages/aws-cdk/lib/init-templates/v1/app/typescript/lib/%name%-stack.template.ts
+++ b/packages/aws-cdk/lib/init-templates/v1/app/typescript/lib/%name%-stack.template.ts
@@ -1,9 +1,15 @@
 import * as cdk from '@aws-cdk/core';
+// import * as sqs from '@aws-cdk/aws-sqs';
 
 export class %name.PascalCased%Stack extends cdk.Stack {
   constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
     super(scope, id, props);
 
     // The code that defines your stack goes here
+
+    // example resource
+    // const queue = new sqs.Queue(this, '%name.PascalCased%Queue', {
+    //   visibilityTimeout: cdk.Duration.seconds(300)
+    // });
   }
 }
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/typescript/package.template.json b/packages/aws-cdk/lib/init-templates/v1/app/typescript/package.template.json
index df89ae6a206bb..94bbd07dae3ac 100644
--- a/packages/aws-cdk/lib/init-templates/v1/app/typescript/package.template.json
+++ b/packages/aws-cdk/lib/init-templates/v1/app/typescript/package.template.json
@@ -11,7 +11,7 @@
     "cdk": "cdk"
   },
   "devDependencies": {
-    "@aws-cdk/assert": "%cdk-version%",
+    "@aws-cdk/assertions": "%cdk-version%",
     "@types/jest": "^26.0.10",
     "@types/node": "10.17.27",
     "jest": "^26.4.2",
diff --git a/packages/aws-cdk/lib/init-templates/v1/app/typescript/test/%name%.test.template.ts b/packages/aws-cdk/lib/init-templates/v1/app/typescript/test/%name%.test.template.ts
index a574690020687..d41f3aaf74d04 100644
--- a/packages/aws-cdk/lib/init-templates/v1/app/typescript/test/%name%.test.template.ts
+++ b/packages/aws-cdk/lib/init-templates/v1/app/typescript/test/%name%.test.template.ts
@@ -1,13 +1,17 @@
-import { expect as expectCDK, matchTemplate, MatchStyle } from '@aws-cdk/assert';
-import * as cdk from '@aws-cdk/core';
-import * as %name.PascalCased% from '../lib/%name%-stack';
+// import { Template } from '@aws-cdk/assertions';
+// import * as cdk from '@aws-cdk/core';
+// import * as %name.PascalCased% from '../lib/%name%-stack';
 
-test('Empty Stack', () => {
-    const app = new cdk.App();
-    // WHEN
-    const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
-    // THEN
-    expectCDK(stack).to(matchTemplate({
-      "Resources": {}
-    }, MatchStyle.EXACT));
+// example test. To run these tests, uncomment this file along with the
+// example resource in lib/%name%-stack.ts
+test('SQS Queue Created', () => {
+//   const app = new cdk.App();
+//     // WHEN
+//   const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
+//     // THEN
+//   const template = Template.fromStack(stack);
+
+//   template.hasResourceProperties('AWS::SQS::Queue', {
+//     VisibilityTimeout: 300
+//   });
 });
diff --git a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/lib/index.template.ts b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/lib/index.template.ts
index d05d444fc8f09..49c002d8e8271 100644
--- a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/lib/index.template.ts
+++ b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/lib/index.template.ts
@@ -1,4 +1,5 @@
 import * as cdk from '@aws-cdk/core';
+// import * as sqs from '@aws-cdk/aws-sqs';
 
 export interface %name.PascalCased%Props {
   // Define construct properties here
@@ -10,5 +11,10 @@ export class %name.PascalCased% extends cdk.Construct {
     super(scope, id);
 
     // Define construct contents here
+
+    // example resource
+    // const queue = new sqs.Queue(this, '%name.PascalCased%Queue', {
+    //   visibilityTimeout: cdk.Duration.seconds(300)
+    // });
   }
 }
diff --git a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/package.template.json b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/package.template.json
index 8d9ef219c74ca..4e99fa16cbc8f 100644
--- a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/package.template.json
+++ b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/package.template.json
@@ -9,7 +9,7 @@
     "test": "jest"
   },
   "devDependencies": {
-    "@aws-cdk/assert": "%cdk-version%",
+    "@aws-cdk/assertions": "%cdk-version%",
     "@types/jest": "^26.0.10",
     "@types/node": "10.17.27",
     "jest": "^26.4.2",
diff --git a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/test/%name%.test.template.ts b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/test/%name%.test.template.ts
index 0b49cb3cc99d1..641b974082aa7 100644
--- a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/test/%name%.test.template.ts
+++ b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/test/%name%.test.template.ts
@@ -1,15 +1,18 @@
-import { expect as expectCDK, countResources } from '@aws-cdk/assert';
-import * as cdk from '@aws-cdk/core';
-import * as %name.PascalCased% from '../lib/index';
+// import { Template } from '@aws-cdk/assertions';
+// import * as cdk from '@aws-cdk/core';
+// import * as %name.PascalCased% from '../lib/index';
 
-/*
- * Example test
- */
-test('SNS Topic Created', () => {
-  const app = new cdk.App();
-  const stack = new cdk.Stack(app, "TestStack");
-  // WHEN
-  new %name.PascalCased%.%name.PascalCased%(stack, 'MyTestConstruct');
-  // THEN
-  expectCDK(stack).to(countResources("AWS::SNS::Topic",0));
+// example test. To run these tests, uncomment this file along with the
+// example resource in lib/index.ts
+test('SQS Queue Created', () => {
+//   const app = new cdk.App();
+//   const stack = new cdk.Stack(app, 'TestStack');
+//   // WHEN
+//   new %name.PascalCased%.%name.PascalCased%(stack, 'MyTestConstruct');
+//   // THEN
+//   const template = Template.fromStack(stack);
+
+//   template.hasResourceProperties('AWS::SQS::Queue', {
+//     VisibilityTimeout: 300
+//   });
 });
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%.template.go b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%.template.go
new file mode 100644
index 0000000000000..5ac97c495740f
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%.template.go
@@ -0,0 +1,71 @@
+package main
+
+import (
+	"github.com/aws/aws-cdk-go/awscdk"
+	"github.com/aws/aws-cdk-go/awscdk/awssns"
+	"github.com/aws/aws-cdk-go/awscdk/awssnssubscriptions"
+	"github.com/aws/aws-cdk-go/awscdk/awssqs"
+	"github.com/aws/constructs-go/constructs/v3"
+	"github.com/aws/jsii-runtime-go"
+)
+
+type %name.PascalCased%StackProps struct {
+	awscdk.StackProps
+}
+
+func New%name.PascalCased%Stack(scope constructs.Construct, id string, props *%name.PascalCased%StackProps) awscdk.Stack {
+	var sprops awscdk.StackProps
+	if props != nil {
+		sprops = props.StackProps
+	}
+	stack := awscdk.NewStack(scope, &id, &sprops)
+
+
+	queue := awssqs.NewQueue(stack, jsii.String("%name.PascalCased%Queue"), &awssqs.QueueProps{
+		VisibilityTimeout: awscdk.Duration_Seconds(jsii.Number(300)),
+	})
+
+	topic := awssns.NewTopic(stack, jsii.String("%name.PascalCased%Topic"), &awssns.TopicProps{})
+	topic.AddSubscription(awssnssubscriptions.NewSqsSubscription(queue, &awssnssubscriptions.SqsSubscriptionProps{}))
+
+	return stack
+}
+
+func main() {
+	app := awscdk.NewApp(nil)
+
+	New%name.PascalCased%Stack(app, "%name.PascalCased%Stack", &%name.PascalCased%StackProps{
+		awscdk.StackProps{
+			Env: env(),
+		},
+	})
+
+	app.Synth(nil)
+}
+
+// env determines the AWS environment (account+region) in which our stack is to
+// be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html
+func env() *awscdk.Environment {
+	// If unspecified, this stack will be "environment-agnostic".
+	// Account/Region-dependent features and context lookups will not work, but a
+	// single synthesized template can be deployed anywhere.
+	//---------------------------------------------------------------------------
+	return nil
+
+	// Uncomment if you know exactly what account and region you want to deploy
+	// the stack to. This is the recommendation for production stacks.
+	//---------------------------------------------------------------------------
+	// return &awscdk.Environment{
+	//  Account: jsii.String("123456789012"),
+	//  Region:  jsii.String("us-east-1"),
+	// }
+
+	// Uncomment to specialize this stack for the AWS Account and Region that are
+	// implied by the current CLI configuration. This is recommended for dev
+	// stacks.
+	//---------------------------------------------------------------------------
+	// return &awscdk.Environment{
+	//  Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")),
+	//  Region:  jsii.String(os.Getenv("CDK_DEFAULT_REGION")),
+	// }
+}
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%_test.template.go b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%_test.template.go
new file mode 100644
index 0000000000000..834f4830cf23e
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%_test.template.go
@@ -0,0 +1,25 @@
+package main
+
+import (
+	"testing"
+
+	"github.com/aws/aws-cdk-go/awscdk"
+	"github.com/aws/aws-cdk-go/awscdk/assertions"
+	"github.com/aws/jsii-runtime-go"
+)
+
+func Test%name.PascalCased%Stack(t *testing.T) {
+	// GIVEN
+	app := awscdk.NewApp(nil)
+
+	// WHEN
+	stack := New%name.PascalCased%Stack(app, "MyStack", nil)
+
+	// THEN
+	template := assertions.Template_FromStack(stack)
+
+	template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{
+		"VisibilityTimeout": 300,
+	})
+	template.ResourceCountIs(jsii.String("AWS::SNS::Topic"), jsii.Number(1))
+}
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/go/.template.gitignore b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/.template.gitignore
new file mode 100644
index 0000000000000..92fe1ec34b4b6
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/.template.gitignore
@@ -0,0 +1,19 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# go.sum should be committed
+!go.sum
+
+# CDK asset staging directory
+.cdk.staging
+cdk.out
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/go/README.md b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/README.md
new file mode 100644
index 0000000000000..9b8d4b29f26e3
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/README.md
@@ -0,0 +1,14 @@
+# Welcome to your CDK Go project!
+
+This is a blank project for Go development with CDK.
+
+**NOTICE**: Go support is still in Developer Preview. This implies that APIs may
+change while we address early feedback from the community. We would love to hear
+about your experience through GitHub issues.
+
+## Useful commands
+
+ * `cdk deploy`      deploy this stack to your default AWS account/region
+ * `cdk diff`        compare deployed stack with current state
+ * `cdk synth`       emits the synthesized CloudFormation template
+ * `go test`         run unit tests
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/go/cdk.template.json b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/cdk.template.json
new file mode 100644
index 0000000000000..ad88cd7ef75f3
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/cdk.template.json
@@ -0,0 +1,3 @@
+{
+  "app": "go mod download && go run %name%.go"
+}
\ No newline at end of file
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/go/go.template.mod b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/go.template.mod
new file mode 100644
index 0000000000000..5dbef39984826
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/go.template.mod
@@ -0,0 +1,9 @@
+module %name%
+
+go 1.16
+
+require (
+  github.com/aws/aws-cdk-go/awscdk v%cdk-version%-devpreview
+  github.com/aws/constructs-go/constructs/v3 v3.3.71
+  github.com/aws/jsii-runtime-go v1.26.0
+)
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/java/pom.template.xml b/packages/aws-cdk/lib/init-templates/v1/sample-app/java/pom.template.xml
index 5d679d2570040..e25c5e7c23a9b 100644
--- a/packages/aws-cdk/lib/init-templates/v1/sample-app/java/pom.template.xml
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/java/pom.template.xml
@@ -55,24 +55,18 @@
             sqs
             ${cdk.version}
         
-
         
-          org.junit.jupiter
-          junit-jupiter-api
-          ${junit.version}
-          test
+            software.amazon.awscdk
+            assertions
+            ${cdk.version}
+            test
         
+
         
           org.junit.jupiter
-          junit-jupiter-engine
+          junit-jupiter
           ${junit.version}
           test
         
-        
-            org.assertj
-            assertj-core
-            3.18.1
-            test
-        
     
 
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java b/packages/aws-cdk/lib/init-templates/v1/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java
index 93b00f5d770c2..b648a3a72dc46 100644
--- a/packages/aws-cdk/lib/init-templates/v1/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java
@@ -1,27 +1,26 @@
 package com.myorg;
 
 import software.amazon.awscdk.core.App;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
+import software.amazon.awscdk.assertions.Template;
+import software.amazon.awscdk.assertions.Match;
 import java.io.IOException;
 
+import java.util.Map;
+
 import org.junit.jupiter.api.Test;
-import static org.assertj.core.api.Assertions.assertThat;
 
 public class %name.PascalCased%StackTest {
-    private final static ObjectMapper JSON =
-        new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true);
 
     @Test
     public void testStack() throws IOException {
         App app = new App();
         %name.PascalCased%Stack stack = new %name.PascalCased%Stack(app, "test");
 
-        JsonNode actual = JSON.valueToTree(app.synth().getStackArtifact(stack.getArtifactId()).getTemplate());
+        Template template = Template.fromStack(stack);
 
-        assertThat(actual.toString())
-            .contains("AWS::SQS::Queue")
-            .contains("AWS::SNS::Topic");
+        template.hasResourceProperties("AWS::SQS::Queue", Map.of(
+            "VisibilityTimeout", 300
+        ));
+        template.resourceCountIs("AWS::SNS::Topic", 1);
     }
 }
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/package.template.json b/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/package.template.json
index 7594be2ffb151..43b6f94c6f314 100644
--- a/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/package.template.json
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/package.template.json
@@ -10,7 +10,7 @@
     "test": "jest"
   },
   "devDependencies": {
-    "@aws-cdk/assert": "%cdk-version%",
+    "@aws-cdk/assertions": "%cdk-version%",
     "aws-cdk": "%cdk-version%",
     "jest": "^26.4.2"
   },
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/test/%name%.test.template.js b/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/test/%name%.test.template.js
index 7e786e6ee3753..4e53341387c69 100644
--- a/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/test/%name%.test.template.js
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/test/%name%.test.template.js
@@ -1,15 +1,17 @@
-const { expect, haveResource } = require('@aws-cdk/assert');
+const { Template, Match } = require('@aws-cdk/assertions');
 const cdk = require('@aws-cdk/core');
 const %name.PascalCased% = require('../lib/%name%-stack');
 
 test('SQS Queue Created', () => {
-    const app = new cdk.App();
-    // WHEN
-    const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
-    // THEN
-    expect(stack).to(haveResource("AWS::SQS::Queue",{
-      VisibilityTimeout: 300
-    }));
+  const app = new cdk.App();
+  // WHEN
+  const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
+  // THEN
+  const template = Template.fromStack(stack);
+
+  template.hasResourceProperties('AWS::SQS::Queue', {
+    VisibilityTimeout: 300
+  });
 });
 
 test('SNS Topic Created', () => {
@@ -17,5 +19,7 @@ test('SNS Topic Created', () => {
   // WHEN
   const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
   // THEN
-  expect(stack).to(haveResource("AWS::SNS::Topic"));
+  const template = Template.fromStack(stack);
+
+  template.resourceCountIs('AWS::SNS::Topic', 1);
 });
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements-dev.txt b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements-dev.txt
new file mode 100644
index 0000000000000..927094516e657
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements-dev.txt
@@ -0,0 +1 @@
+pytest==6.2.5
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.template.txt b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.template.txt
new file mode 100644
index 0000000000000..6c20aced0687a
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.template.txt
@@ -0,0 +1,7 @@
+aws-cdk.core==%cdk-version%
+aws-cdk.aws_iam==%cdk-version%
+aws-cdk.aws_sqs==%cdk-version%
+aws-cdk.aws_sns==%cdk-version%
+aws-cdk.aws_sns_subscriptions==%cdk-version%
+aws-cdk.aws_s3==%cdk-version%
+aws-cdk.assertions==%cdk-version%
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.txt b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.txt
deleted file mode 100644
index ae60ed5f14ca8..0000000000000
--- a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
--e .
-pytest
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/setup.template.py b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/setup.template.py
deleted file mode 100644
index d79611021c860..0000000000000
--- a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/setup.template.py
+++ /dev/null
@@ -1,48 +0,0 @@
-import setuptools
-
-
-with open("README.md") as fp:
-    long_description = fp.read()
-
-
-setuptools.setup(
-    name="%name.PythonModule%",
-    version="0.0.1",
-
-    description="A sample CDK Python app",
-    long_description=long_description,
-    long_description_content_type="text/markdown",
-
-    author="author",
-
-    package_dir={"": "%name.PythonModule%"},
-    packages=setuptools.find_packages(where="%name.PythonModule%"),
-
-    install_requires=[
-        "aws-cdk.core==%cdk-version%",
-        "aws-cdk.aws_iam==%cdk-version%",
-        "aws-cdk.aws_sqs==%cdk-version%",
-        "aws-cdk.aws_sns==%cdk-version%",
-        "aws-cdk.aws_sns_subscriptions==%cdk-version%",
-        "aws-cdk.aws_s3==%cdk-version%",
-    ],
-
-    python_requires=">=3.6",
-
-    classifiers=[
-        "Development Status :: 4 - Beta",
-
-        "Intended Audience :: Developers",
-
-        "Programming Language :: JavaScript",
-        "Programming Language :: Python :: 3 :: Only",
-        "Programming Language :: Python :: 3.6",
-        "Programming Language :: Python :: 3.7",
-        "Programming Language :: Python :: 3.8",
-
-        "Topic :: Software Development :: Code Generators",
-        "Topic :: Utilities",
-
-        "Typing :: Typed",
-    ],
-)
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py
index 182d07fe09855..99a6a26b4a15e 100644
--- a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py
@@ -1,19 +1,24 @@
-import json
-import pytest
+from aws_cdk import (
+        core,
+        assertions
+    )
 
-from aws_cdk import core
 from %name.PythonModule%.%name.PythonModule%_stack import %name.PascalCased%Stack
 
 
-def get_template():
+def test_sqs_queue_created():
     app = core.App()
-    %name.PascalCased%Stack(app, "%name.StackName%")
-    return json.dumps(app.synth().get_stack("%name.StackName%").template)
-
+    stack = %name.PascalCased%Stack(app, "%name.StackName%")
+    template = assertions.Template.from_stack(stack)
 
-def test_sqs_queue_created():
-    assert("AWS::SQS::Queue" in get_template())
+    template.has_resource_properties("AWS::SQS::Queue", {
+        "VisibilityTimeout": 300
+    })
 
 
 def test_sns_topic_created():
-    assert("AWS::SNS::Topic" in get_template())
+    app = core.App()
+    stack = %name.PascalCased%Stack(app, "%name.StackName%")
+    template = assertions.Template.from_stack(stack)
+
+    template.resource_count_is("AWS::SNS::Topic", 1)
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/package.template.json b/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/package.template.json
index 98942aa31c167..550691f4eb2c5 100644
--- a/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/package.template.json
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/package.template.json
@@ -12,7 +12,7 @@
   },
   "devDependencies": {
     "aws-cdk": "%cdk-version%",
-    "@aws-cdk/assert": "%cdk-version%",
+    "@aws-cdk/assertions": "%cdk-version%",
     "@types/jest": "^26.0.10",
     "@types/node": "10.17.27",
     "jest": "^26.4.2",
diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/test/%name%.test.template.ts b/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/test/%name%.test.template.ts
index 3a602380d6f6d..45cd6cca71ba4 100644
--- a/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/test/%name%.test.template.ts
+++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/test/%name%.test.template.ts
@@ -1,15 +1,17 @@
-import { expect as expectCDK, haveResource } from '@aws-cdk/assert';
+import { Template, Match } from '@aws-cdk/assertions';
 import * as cdk from '@aws-cdk/core';
 import * as %name.PascalCased% from '../lib/%name%-stack';
 
 test('SQS Queue Created', () => {
-    const app = new cdk.App();
+  const app = new cdk.App();
     // WHEN
-    const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
+  const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
     // THEN
-    expectCDK(stack).to(haveResource("AWS::SQS::Queue",{
-      VisibilityTimeout: 300
-    }));
+  const template = Template.fromStack(stack);
+
+  template.hasResourceProperties('AWS::SQS::Queue', {
+    VisibilityTimeout: 300
+  });
 });
 
 test('SNS Topic Created', () => {
@@ -17,5 +19,7 @@ test('SNS Topic Created', () => {
   // WHEN
   const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
   // THEN
-  expectCDK(stack).to(haveResource("AWS::SNS::Topic"));
+  const template = Template.fromStack(stack);
+
+  template.resourceCountIs('AWS::SNS::Topic', 1);
 });
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/go/%name%.template.go b/packages/aws-cdk/lib/init-templates/v2/app/go/%name%.template.go
index 46577faef90f6..a2ab8b5d8f8fd 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/go/%name%.template.go
+++ b/packages/aws-cdk/lib/init-templates/v2/app/go/%name%.template.go
@@ -2,9 +2,9 @@ package main
 
 import (
 	"github.com/aws/aws-cdk-go/awscdk/v2"
-	"github.com/aws/aws-cdk-go/awscdk/v2/awssns"
+	// "github.com/aws/aws-cdk-go/awscdk/v2/awssqs"
 	"github.com/aws/constructs-go/constructs/v10"
-	"github.com/aws/jsii-runtime-go"
+	// "github.com/aws/jsii-runtime-go"
 )
 
 type %name.PascalCased%StackProps struct {
@@ -20,10 +20,10 @@ func New%name.PascalCased%Stack(scope constructs.Construct, id string, props *%n
 
 	// The code that defines your stack goes here
 
-	// as an example, here's how you would define an AWS SNS topic:
-	awssns.NewTopic(stack, jsii.String("MyTopic"), &awssns.TopicProps{
-		DisplayName: jsii.String("MyCoolTopic"),
-	})
+	// example resource
+	// queue := awssqs.NewQueue(stack, jsii.String("%name.PascalCased%Queue"), &awssqs.QueueProps{
+	// 	VisibilityTimeout: awscdk.Duration_Seconds(jsii.Number(300)),
+	// })
 
 	return stack
 }
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/go/%name%_test.template.go b/packages/aws-cdk/lib/init-templates/v2/app/go/%name%_test.template.go
index 6c166d681b0ce..e1b5f2c91adcb 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/go/%name%_test.template.go
+++ b/packages/aws-cdk/lib/init-templates/v2/app/go/%name%_test.template.go
@@ -1,28 +1,26 @@
 package main
 
-import (
-	"encoding/json"
-	"testing"
+// import (
+// 	"testing"
 
-	"github.com/aws/aws-cdk-go/awscdk/v2"
-	"github.com/stretchr/testify/assert"
-	"github.com/tidwall/gjson"
-)
+// 	"github.com/aws/aws-cdk-go/awscdk/v2"
+// 	assertions "github.com/aws/aws-cdk-go/awscdkassertionsalpha/v2"
+// 	"github.com/aws/jsii-runtime-go"
+// )
 
-func Test%name.PascalCased%Stack(t *testing.T) {
-	// GIVEN
-	app := awscdk.NewApp(nil)
+// example tests. To run these tests, uncomment this file along with the
+// example resource in %name%_test.go
+// func Test%name.PascalCased%Stack(t *testing.T) {
+// 	// GIVEN
+// 	app := awscdk.NewApp(nil)
 
-	// WHEN
-	stack := New%name.PascalCased%Stack(app, "MyStack", nil)
+// 	// WHEN
+// 	stack := New%name.PascalCased%Stack(app, "MyStack", nil)
 
-	// THEN
-	bytes, err := json.Marshal(app.Synth(nil).GetStackArtifact(stack.ArtifactId()).Template())
-	if err != nil {
-		t.Error(err)
-	}
+// 	// THEN
+// 	template := assertions.Template_FromStack(stack)
 
-	template := gjson.ParseBytes(bytes)
-	displayName := template.Get("Resources.MyTopic86869434.Properties.DisplayName").String()
-	assert.Equal(t, "MyCoolTopic", displayName)
-}
+// 	template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{
+// 		"VisibilityTimeout": 300,
+// 	})
+// }
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/go/go.template.mod b/packages/aws-cdk/lib/init-templates/v2/app/go/go.template.mod
index 50f21389478f4..3f1a4a639d1e3 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/go/go.template.mod
+++ b/packages/aws-cdk/lib/init-templates/v2/app/go/go.template.mod
@@ -4,10 +4,7 @@ go 1.16
 
 require (
   github.com/aws/aws-cdk-go/awscdk/v2 v%cdk-version%
+  github.com/aws/aws-cdk-go/awscdkassertionsalpha/v2 v%cdk-version%
   github.com/aws/constructs-go/constructs/v10 v10.0.5
   github.com/aws/jsii-runtime-go v1.29.0
-
-  // for testing
-  github.com/tidwall/gjson v1.7.4
-  github.com/stretchr/testify v1.7.0
 )
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/java/pom.template.xml b/packages/aws-cdk/lib/init-templates/v2/app/java/pom.template.xml
index 1d0eb742d4f8e..3173c567c1149 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/java/pom.template.xml
+++ b/packages/aws-cdk/lib/init-templates/v2/app/java/pom.template.xml
@@ -50,24 +50,18 @@
             constructs
             ${constructs.version}
         
-
         
-          org.junit.jupiter
-          junit-jupiter-api
-          ${junit.version}
-          test
+            software.amazon.awscdk
+            assertions-alpha
+            ${cdk.version}
+            test
         
+
         
           org.junit.jupiter
-          junit-jupiter-engine
+          junit-jupiter
           ${junit.version}
           test
         
-        
-            org.assertj
-            assertj-core
-            3.18.1
-            test
-        
     
 
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java b/packages/aws-cdk/lib/init-templates/v2/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java
index 0d8cbf10bf988..e944bde388603 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java
+++ b/packages/aws-cdk/lib/init-templates/v2/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java
@@ -3,6 +3,8 @@
 import software.constructs.Construct;
 import software.amazon.awscdk.Stack;
 import software.amazon.awscdk.StackProps;
+// import software.amazon.awscdk.Duration;
+// import software.amazon.awscdk.services.sqs.Queue;
 
 public class %name.PascalCased%Stack extends Stack {
     public %name.PascalCased%Stack(final Construct scope, final String id) {
@@ -13,5 +15,10 @@ public class %name.PascalCased%Stack extends Stack {
         super(scope, id, props);
 
         // The code that defines your stack goes here
+
+        // example resource
+        // final Queue queue = Queue.Builder.create(this, "%name.PascalCased%Queue")
+        //         .visibilityTimeout(Duration.seconds(300))
+        //         .build();
     }
 }
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java b/packages/aws-cdk/lib/init-templates/v2/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java
index 715840abd0de1..5e9d7806654d0 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java
+++ b/packages/aws-cdk/lib/init-templates/v2/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java
@@ -1,29 +1,26 @@
-package com.myorg;
+// package com.myorg;
 
-import software.amazon.awscdk.App;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
+// import software.amazon.awscdk.App;
+// import software.amazon.awscdk.assertions.alpha.Template;
+// import java.io.IOException;
 
-import java.io.IOException;
+// import java.util.Map;
 
-import org.junit.jupiter.api.Test;
-import static org.assertj.core.api.Assertions.assertThat;
+// import org.junit.jupiter.api.Test;
 
-public class %name.PascalCased%Test {
-    private final static ObjectMapper JSON =
-        new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true);
+// example test. To run these tests, uncomment this file, along with the
+// example resource in java/src/main/java/com/myorg/%name.PascalCased%Stack.java
+// public class %name.PascalCased%Test {
 
-    @Test
-    public void testStack() throws IOException {
-        App app = new App();
-        %name.PascalCased%Stack stack = new %name.PascalCased%Stack(app, "test");
+//     @Test
+//     public void testStack() throws IOException {
+//         App app = new App();
+//         %name.PascalCased%Stack stack = new %name.PascalCased%Stack(app, "test");
 
-        // synthesize the stack to a CloudFormation template and compare against
-        // a checked-in JSON file.
-        JsonNode actual = JSON.valueToTree(app.synth().getStackArtifact(stack.getArtifactId()).getTemplate());
+//         Template template = Template.fromStack(stack);
 
-        // Update once resources have been added to the stack
-        assertThat(actual.get("Resources")).isNull();
-    }
-}
+//         template.hasResourceProperties("AWS::SQS::Queue", Map.of(
+//             "VisibilityTimeout", 300
+//         ));
+//     }
+// }
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/javascript/lib/%name%-stack.template.js b/packages/aws-cdk/lib/init-templates/v2/app/javascript/lib/%name%-stack.template.js
index d5d66d9bd229e..cb7c095969484 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/javascript/lib/%name%-stack.template.js
+++ b/packages/aws-cdk/lib/init-templates/v2/app/javascript/lib/%name%-stack.template.js
@@ -1,4 +1,5 @@
-const { Stack } = require('aws-cdk-lib');
+const { Stack, Duration } = require('aws-cdk-lib');
+// const sqs = require('aws-cdk-lib/aws-sqs');
 
 class %name.PascalCased%Stack extends Stack {
   /**
@@ -11,6 +12,11 @@ class %name.PascalCased%Stack extends Stack {
     super(scope, id, props);
 
     // The code that defines your stack goes here
+
+    // example resource
+    // const queue = new sqs.Queue(this, '%name.PascalCased%Queue', {
+    //   visibilityTimeout: Duration.seconds(300)
+    // });
   }
 }
 
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/javascript/package.template.json b/packages/aws-cdk/lib/init-templates/v2/app/javascript/package.template.json
index 550e7544f9b44..3fcda877c39da 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/javascript/package.template.json
+++ b/packages/aws-cdk/lib/init-templates/v2/app/javascript/package.template.json
@@ -11,6 +11,7 @@
   },
   "devDependencies": {
     "aws-cdk": "%cdk-version%",
+    "@aws-cdk/assertions-alpha": "%cdk-version%",
     "jest": "^26.4.2"
   },
   "dependencies": {
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/javascript/test/%name%.test.template.js b/packages/aws-cdk/lib/init-templates/v2/app/javascript/test/%name%.test.template.js
index 79db241da8e0e..874a74f5b17d8 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/javascript/test/%name%.test.template.js
+++ b/packages/aws-cdk/lib/init-templates/v2/app/javascript/test/%name%.test.template.js
@@ -1,11 +1,17 @@
-const cdk = require('aws-cdk-lib');
-const %name.PascalCased% = require('../lib/%name%-stack');
+// const cdk = require('aws-cdk-lib');
+// const { Template } = require('@aws-cdk/assertions-alpha');
+// const %name.PascalCased% = require('../lib/%name%-stack');
 
-test('Empty Stack', () => {
-    const app = new cdk.App();
-    // WHEN
-    const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
-    // THEN
-    const actual = app.synth().getStackArtifact(stack.artifactId).template;
-    expect(actual.Resources || {}).toEqual({});
+// example test. To run these tests, uncomment this file along with the
+// example resource in lib/%name%-stack.js
+test('SQS Queue Created', () => {
+//   const app = new cdk.App();
+//   // WHEN
+//   const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
+//   // THEN
+//   const template = Template.fromStack(stack);
+
+//   template.hasResourceProperties('AWS::SQS::Queue', {
+//     VisibilityTimeout: 300
+//   });
 });
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py b/packages/aws-cdk/lib/init-templates/v2/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py
index 4599c4f6e19f6..b93133ce944cf 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py
+++ b/packages/aws-cdk/lib/init-templates/v2/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py
@@ -1,4 +1,8 @@
-from aws_cdk import Stack
+from aws_cdk import (
+    # Duration,
+    Stack,
+    # aws_sqs as sqs,
+)
 from constructs import Construct
 
 class %name.PascalCased%Stack(Stack):
@@ -7,3 +11,9 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
         super().__init__(scope, construct_id, **kwargs)
 
         # The code that defines your stack goes here
+
+        # example resource
+        # queue = sqs.Queue(
+        #     self, "%name.PascalCased%Queue",
+        #     visibility_timeout=Duration.seconds(300),
+        # )
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/requirements-dev.txt b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements-dev.txt
new file mode 100644
index 0000000000000..927094516e657
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements-dev.txt
@@ -0,0 +1 @@
+pytest==6.2.5
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt
new file mode 100644
index 0000000000000..5ba3f43115a07
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt
@@ -0,0 +1,3 @@
+aws-cdk-lib==%cdk-version%
+aws-cdk.assertions-alpha==%cdk-version%
+constructs>=%constructs-version%
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.txt b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.txt
deleted file mode 100644
index d6e1198b1ab1f..0000000000000
--- a/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
--e .
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/setup.template.py b/packages/aws-cdk/lib/init-templates/v2/app/python/setup.template.py
deleted file mode 100644
index d819a7bcadb77..0000000000000
--- a/packages/aws-cdk/lib/init-templates/v2/app/python/setup.template.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import setuptools
-
-
-with open("README.md") as fp:
-    long_description = fp.read()
-
-
-setuptools.setup(
-    name="%name.PythonModule%",
-    version="0.0.1",
-
-    description="An empty CDK Python app",
-    long_description=long_description,
-    long_description_content_type="text/markdown",
-
-    author="author",
-
-    package_dir={"": "%name.PythonModule%"},
-    packages=setuptools.find_packages(where="%name.PythonModule%"),
-
-    install_requires=[
-        "aws-cdk-lib==%cdk-version%",
-        "constructs%constructs-version%",
-    ],
-
-    python_requires=">=3.6",
-
-    classifiers=[
-        "Development Status :: 4 - Beta",
-
-        "Intended Audience :: Developers",
-
-        "Programming Language :: JavaScript",
-        "Programming Language :: Python :: 3 :: Only",
-        "Programming Language :: Python :: 3.6",
-        "Programming Language :: Python :: 3.7",
-        "Programming Language :: Python :: 3.8",
-
-        "Topic :: Software Development :: Code Generators",
-        "Topic :: Utilities",
-
-        "Typing :: Typed",
-    ],
-)
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/tests/__init__.py b/packages/aws-cdk/lib/init-templates/v2/app/python/tests/__init__.py
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/__init__.py b/packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/__init__.py
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/test_%name.PythonModule%_stack.template.py b/packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/test_%name.PythonModule%_stack.template.py
new file mode 100644
index 0000000000000..19c612a3da691
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/test_%name.PythonModule%_stack.template.py
@@ -0,0 +1,15 @@
+# import aws_cdk as core
+# import aws_cdk.assertions_alpha as assertions
+
+# from %name.PythonModule%.%name.PythonModule%_stack import %name.PascalCased%Stack
+
+# example tests. To run these tests, uncomment this file along with the example
+# resource in %name.PythonModule%/%name.PythonModule%_stack.py
+# def test_sqs_queue_created():
+#     app = core.App()
+#     stack = %name.PascalCased%Stack(app, "%name.StackName%")
+#     template = assertions.Template.from_stack(stack)
+
+#     template.has_resource_properties("AWS::SQS::Queue", {
+#         "VisibilityTimeout": 300
+#     })
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/typescript/lib/%name%-stack.template.ts b/packages/aws-cdk/lib/init-templates/v2/app/typescript/lib/%name%-stack.template.ts
index 82d70c083134e..3d6c54bd3dca2 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/typescript/lib/%name%-stack.template.ts
+++ b/packages/aws-cdk/lib/init-templates/v2/app/typescript/lib/%name%-stack.template.ts
@@ -1,10 +1,16 @@
 import { Stack, StackProps } from 'aws-cdk-lib';
 import { Construct } from 'constructs';
+// import * as sqs from 'aws-cdk-lib/aws-sqs';
 
 export class %name.PascalCased%Stack extends Stack {
   constructor(scope: Construct, id: string, props?: StackProps) {
     super(scope, id, props);
 
     // The code that defines your stack goes here
+
+    // example resource
+    // const queue = new sqs.Queue(this, '%name.PascalCased%Queue', {
+    //   visibilityTimeout: cdk.Duration.seconds(300)
+    // });
   }
 }
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/typescript/package.template.json b/packages/aws-cdk/lib/init-templates/v2/app/typescript/package.template.json
index a599c63f6ec35..9f6f0d47cade9 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/typescript/package.template.json
+++ b/packages/aws-cdk/lib/init-templates/v2/app/typescript/package.template.json
@@ -11,6 +11,7 @@
     "cdk": "cdk"
   },
   "devDependencies": {
+    "@aws-cdk/assertions-alpha": "%cdk-version%",
     "@types/jest": "^26.0.10",
     "@types/node": "10.17.27",
     "jest": "^26.4.2",
diff --git a/packages/aws-cdk/lib/init-templates/v2/app/typescript/test/%name%.test.template.ts b/packages/aws-cdk/lib/init-templates/v2/app/typescript/test/%name%.test.template.ts
index a2542902315c8..61e6e96d0dcab 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/typescript/test/%name%.test.template.ts
+++ b/packages/aws-cdk/lib/init-templates/v2/app/typescript/test/%name%.test.template.ts
@@ -1,11 +1,17 @@
-import * as cdk from 'aws-cdk-lib';
-import * as %name.PascalCased% from '../lib/%name%-stack';
+// import * as cdk from 'aws-cdk-lib';
+// import { Template } from '@aws-cdk/assertions-alpha';
+// import * as %name.PascalCased% from '../lib/%name%-stack';
 
-test('Empty Stack', () => {
-    const app = new cdk.App();
-    // WHEN
-    const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
-    // THEN
-    const actual = app.synth().getStackArtifact(stack.artifactId).template;
-    expect(actual.Resources ?? {}).toEqual({});
+// example test. To run these tests, uncomment this file along with the
+// example resource in lib/%name%-stack.ts
+test('SQS Queue Created', () => {
+//   const app = new cdk.App();
+//     // WHEN
+//   const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
+//     // THEN
+//   const template = Template.fromStack(stack);
+
+//   template.hasResourceProperties('AWS::SQS::Queue', {
+//     VisibilityTimeout: 300
+//   });
 });
diff --git a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/lib/index.template.ts b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/lib/index.template.ts
index 3c48194882c3d..bbd6f13d470bd 100644
--- a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/lib/index.template.ts
+++ b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/lib/index.template.ts
@@ -1,4 +1,5 @@
 import { Construct } from 'constructs';
+// import * as sqs from 'aws-cdk-lib/aws-sqs';
 
 export interface %name.PascalCased%Props {
   // Define construct properties here
@@ -10,5 +11,10 @@ export class %name.PascalCased% extends Construct {
     super(scope, id);
 
     // Define construct contents here
+
+    // example resource
+    // const queue = new sqs.Queue(this, '%name.PascalCased%Queue', {
+    //   visibilityTimeout: cdk.Duration.seconds(300)
+    // });
   }
 }
diff --git a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/package.template.json b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/package.template.json
index b388f5270b769..59211fe81715c 100644
--- a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/package.template.json
+++ b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/package.template.json
@@ -12,6 +12,7 @@
     "@types/jest": "^26.0.10",
     "@types/node": "10.17.27",
     "aws-cdk-lib": "%cdk-version%",
+    "@aws-cdk/assertions-alpha": "%cdk-version%",
     "constructs": "%constructs-version%",
     "jest": "^26.4.2",
     "ts-jest": "^26.2.0",
diff --git a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/test/%name%.test.template.ts b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/test/%name%.test.template.ts
index 0aa210d01ae5c..f7200d5dd5cc9 100644
--- a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/test/%name%.test.template.ts
+++ b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/test/%name%.test.template.ts
@@ -1,12 +1,18 @@
-import * as cdk from 'aws-cdk-lib';
-import * as %name.PascalCased% from '../lib/index';
+// import * as cdk from 'aws-cdk-lib';
+// import { Template } from '@aws-cdk/assertions-alpha';
+// import * as %name.PascalCased% from '../lib/index';
 
-test('Empty Stack', () => {
-  const app = new cdk.App();
-  const stack = new cdk.Stack(app, "TestStack");
-  // WHEN
-  new %name.PascalCased%.%name.PascalCased%(stack, 'MyTestConstruct');
-  // THEN
-  const actual = app.synth().getStackArtifact(stack.artifactId).template;
-  expect(actual.Resources ?? {}).toEqual({});
+// example test. To run these tests, uncomment this file along with the
+// example resource in lib/index.ts
+test('SQS Queue Created', () => {
+//   const app = new cdk.App();
+//   const stack = new cdk.Stack(app, "TestStack");
+//   // WHEN
+//   new %name.PascalCased%.%name.PascalCased%(stack, 'MyTestConstruct');
+//   // THEN
+//   const template = Template.fromStack(stack);
+
+//   template.hasResourceProperties('AWS::SQS::Queue', {
+//     VisibilityTimeout: 300
+//   });
 });
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%.template.go b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%.template.go
new file mode 100644
index 0000000000000..1ae8249703373
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%.template.go
@@ -0,0 +1,71 @@
+package main
+
+import (
+	"github.com/aws/aws-cdk-go/awscdk/v2"
+	"github.com/aws/aws-cdk-go/awscdk/v2/awssns"
+	"github.com/aws/aws-cdk-go/awscdk/v2/awssnssubscriptions"
+	"github.com/aws/aws-cdk-go/awscdk/v2/awssqs"
+	"github.com/aws/constructs-go/constructs/v10"
+	"github.com/aws/jsii-runtime-go"
+)
+
+type %name.PascalCased%StackProps struct {
+	awscdk.StackProps
+}
+
+func New%name.PascalCased%Stack(scope constructs.Construct, id string, props *%name.PascalCased%StackProps) awscdk.Stack {
+	var sprops awscdk.StackProps
+	if props != nil {
+		sprops = props.StackProps
+	}
+	stack := awscdk.NewStack(scope, &id, &sprops)
+
+
+	queue := awssqs.NewQueue(stack, jsii.String("%name.PascalCased%Queue"), &awssqs.QueueProps{
+		VisibilityTimeout: awscdk.Duration_Seconds(jsii.Number(300)),
+	})
+
+	topic := awssns.NewTopic(stack, jsii.String("%name.PascalCased%Topic"), &awssns.TopicProps{})
+	topic.AddSubscription(awssnssubscriptions.NewSqsSubscription(queue, &awssnssubscriptions.SqsSubscriptionProps{}))
+
+	return stack
+}
+
+func main() {
+	app := awscdk.NewApp(nil)
+
+	New%name.PascalCased%Stack(app, "%name.PascalCased%Stack", &%name.PascalCased%StackProps{
+		awscdk.StackProps{
+			Env: env(),
+		},
+	})
+
+	app.Synth(nil)
+}
+
+// env determines the AWS environment (account+region) in which our stack is to
+// be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html
+func env() *awscdk.Environment {
+	// If unspecified, this stack will be "environment-agnostic".
+	// Account/Region-dependent features and context lookups will not work, but a
+	// single synthesized template can be deployed anywhere.
+	//---------------------------------------------------------------------------
+	return nil
+
+	// Uncomment if you know exactly what account and region you want to deploy
+	// the stack to. This is the recommendation for production stacks.
+	//---------------------------------------------------------------------------
+	// return &awscdk.Environment{
+	//  Account: jsii.String("123456789012"),
+	//  Region:  jsii.String("us-east-1"),
+	// }
+
+	// Uncomment to specialize this stack for the AWS Account and Region that are
+	// implied by the current CLI configuration. This is recommended for dev
+	// stacks.
+	//---------------------------------------------------------------------------
+	// return &awscdk.Environment{
+	//  Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")),
+	//  Region:  jsii.String(os.Getenv("CDK_DEFAULT_REGION")),
+	// }
+}
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%_test.template.go b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%_test.template.go
new file mode 100644
index 0000000000000..53b15a49266d1
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%_test.template.go
@@ -0,0 +1,25 @@
+package main
+
+import (
+	"testing"
+
+	"github.com/aws/aws-cdk-go/awscdk/v2"
+	assertions "github.com/aws/aws-cdk-go/awscdkassertionsalpha/v2"
+	"github.com/aws/jsii-runtime-go"
+)
+
+func Test%name.PascalCased%Stack(t *testing.T) {
+	// GIVEN
+	app := awscdk.NewApp(nil)
+
+	// WHEN
+	stack := New%name.PascalCased%Stack(app, "MyStack", nil)
+
+	// THEN
+	template := assertions.Template_FromStack(stack)
+
+	template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{
+		"VisibilityTimeout": 300,
+	})
+	template.ResourceCountIs(jsii.String("AWS::SNS::Topic"), jsii.Number(1))
+}
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/go/.template.gitignore b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/.template.gitignore
new file mode 100644
index 0000000000000..92fe1ec34b4b6
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/.template.gitignore
@@ -0,0 +1,19 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# go.sum should be committed
+!go.sum
+
+# CDK asset staging directory
+.cdk.staging
+cdk.out
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/go/README.md b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/README.md
new file mode 100644
index 0000000000000..9b8d4b29f26e3
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/README.md
@@ -0,0 +1,14 @@
+# Welcome to your CDK Go project!
+
+This is a blank project for Go development with CDK.
+
+**NOTICE**: Go support is still in Developer Preview. This implies that APIs may
+change while we address early feedback from the community. We would love to hear
+about your experience through GitHub issues.
+
+## Useful commands
+
+ * `cdk deploy`      deploy this stack to your default AWS account/region
+ * `cdk diff`        compare deployed stack with current state
+ * `cdk synth`       emits the synthesized CloudFormation template
+ * `go test`         run unit tests
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/go/cdk.template.json b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/cdk.template.json
new file mode 100644
index 0000000000000..ad88cd7ef75f3
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/cdk.template.json
@@ -0,0 +1,3 @@
+{
+  "app": "go mod download && go run %name%.go"
+}
\ No newline at end of file
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/go/go.template.mod b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/go.template.mod
new file mode 100644
index 0000000000000..3f1a4a639d1e3
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/go.template.mod
@@ -0,0 +1,10 @@
+module %name%
+
+go 1.16
+
+require (
+  github.com/aws/aws-cdk-go/awscdk/v2 v%cdk-version%
+  github.com/aws/aws-cdk-go/awscdkassertionsalpha/v2 v%cdk-version%
+  github.com/aws/constructs-go/constructs/v10 v10.0.5
+  github.com/aws/jsii-runtime-go v1.29.0
+)
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/java/pom.template.xml b/packages/aws-cdk/lib/init-templates/v2/sample-app/java/pom.template.xml
index 79c769157ceee..78217b2650669 100644
--- a/packages/aws-cdk/lib/init-templates/v2/sample-app/java/pom.template.xml
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/java/pom.template.xml
@@ -44,24 +44,18 @@
             constructs
             ${constructs.version}
         
-
         
-          org.junit.jupiter
-          junit-jupiter-api
-          ${junit.version}
-          test
+            software.amazon.awscdk
+            assertions-alpha
+            ${cdk.version}
+            test
         
+
         
           org.junit.jupiter
-          junit-jupiter-engine
+          junit-jupiter
           ${junit.version}
           test
         
-        
-            org.assertj
-            assertj-core
-            3.18.1
-            test
-        
     
 
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java b/packages/aws-cdk/lib/init-templates/v2/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java
index a6f7c4f4590b4..c728c6eb6323c 100644
--- a/packages/aws-cdk/lib/init-templates/v2/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java
@@ -1,27 +1,27 @@
 package com.myorg;
 
 import software.amazon.awscdk.App;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
+import software.amazon.awscdk.assertions.alpha.Template;
+import software.amazon.awscdk.assertions.alpha.Match;
 import java.io.IOException;
 
+import java.util.Map;
+
 import org.junit.jupiter.api.Test;
-import static org.assertj.core.api.Assertions.assertThat;
 
 public class %name.PascalCased%StackTest {
-    private final static ObjectMapper JSON =
-        new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true);
 
     @Test
     public void testStack() throws IOException {
         App app = new App();
         %name.PascalCased%Stack stack = new %name.PascalCased%Stack(app, "test");
 
-        JsonNode actual = JSON.valueToTree(app.synth().getStackArtifact(stack.getArtifactId()).getTemplate());
+        Template template = Template.fromStack(stack);
+
+        template.hasResourceProperties("AWS::SQS::Queue", Map.of(
+            "VisibilityTimeout", 300
+        ));
 
-        assertThat(actual.toString())
-            .contains("AWS::SQS::Queue")
-            .contains("AWS::SNS::Topic");
+        template.resourceCountIs("AWS::SNS::Topic", 1);
     }
 }
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/package.template.json b/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/package.template.json
index 550e7544f9b44..3fcda877c39da 100644
--- a/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/package.template.json
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/package.template.json
@@ -11,6 +11,7 @@
   },
   "devDependencies": {
     "aws-cdk": "%cdk-version%",
+    "@aws-cdk/assertions-alpha": "%cdk-version%",
     "jest": "^26.4.2"
   },
   "dependencies": {
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/test/%name%.test.template.js b/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/test/%name%.test.template.js
index b741d4045225b..93294bf407633 100644
--- a/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/test/%name%.test.template.js
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/test/%name%.test.template.js
@@ -1,12 +1,16 @@
 const cdk = require('aws-cdk-lib');
+const { Template, Match } = require('@aws-cdk/assertions-alpha');
 const %name.PascalCased% = require('../lib/%name%-stack');
 
 test('SQS Queue and SNS Topic Created', () => {
-    const app = new cdk.App();
-    // WHEN
-    const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
-    // THEN
-    const actual = JSON.stringify(app.synth().getStackArtifact(stack.artifactId).template);
-    expect(actual).toContain('AWS::SQS::Queue');
-    expect(actual).toContain('AWS::SNS::Topic');
+  const app = new cdk.App();
+  // WHEN
+  const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
+  // THEN
+  const template = Template.fromStack(stack);
+  template.hasResourceProperties('AWS::SQS::Queue', {
+    VisibilityTimeout: 300,
+  });
+
+  template.resourceCountIs('AWS::SNS::Topic', 1);
 });
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements-dev.txt b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements-dev.txt
new file mode 100644
index 0000000000000..927094516e657
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements-dev.txt
@@ -0,0 +1 @@
+pytest==6.2.5
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt
new file mode 100644
index 0000000000000..5ba3f43115a07
--- /dev/null
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt
@@ -0,0 +1,3 @@
+aws-cdk-lib==%cdk-version%
+aws-cdk.assertions-alpha==%cdk-version%
+constructs>=%constructs-version%
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.txt b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.txt
deleted file mode 100644
index ae60ed5f14ca8..0000000000000
--- a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
--e .
-pytest
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/setup.template.py b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/setup.template.py
deleted file mode 100644
index f9eb461178472..0000000000000
--- a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/setup.template.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import setuptools
-
-
-with open("README.md") as fp:
-    long_description = fp.read()
-
-
-setuptools.setup(
-    name="%name.PythonModule%",
-    version="0.0.1",
-
-    description="A sample CDK Python app",
-    long_description=long_description,
-    long_description_content_type="text/markdown",
-
-    author="author",
-
-    package_dir={"": "%name.PythonModule%"},
-    packages=setuptools.find_packages(where="%name.PythonModule%"),
-
-    install_requires=[
-        "aws-cdk-lib==%cdk-version%",
-        "constructs%constructs-version%",
-    ],
-
-    python_requires=">=3.6",
-
-    classifiers=[
-        "Development Status :: 4 - Beta",
-
-        "Intended Audience :: Developers",
-
-        "Programming Language :: JavaScript",
-        "Programming Language :: Python :: 3 :: Only",
-        "Programming Language :: Python :: 3.6",
-        "Programming Language :: Python :: 3.7",
-        "Programming Language :: Python :: 3.8",
-
-        "Topic :: Software Development :: Code Generators",
-        "Topic :: Utilities",
-
-        "Typing :: Typed",
-    ],
-)
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py
index b51a164ff8c5e..50632eb42dae6 100644
--- a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py
@@ -1,19 +1,21 @@
-import json
-import pytest
-
-import aws_cdk_lib as core
+import aws_cdk as core
+import aws_cdk.assertions_alpha as assertions
 from %name.PythonModule%.%name.PythonModule%_stack import %name.PascalCased%Stack
 
 
-def get_template():
+def test_sqs_queue_created():
     app = core.App()
-    %name.PascalCased%Stack(app, "%name.StackName%")
-    return json.dumps(app.synth().get_stack("%name.StackName%").template)
-
+    stack = %name.PascalCased%Stack(app, "%name.StackName%")
+    template = assertions.Template.from_stack(stack)
 
-def test_sqs_queue_created():
-    assert("AWS::SQS::Queue" in get_template())
+    template.has_resource_properties("AWS::SQS::Queue", {
+        "VisibilityTimeout": 300
+    })
 
 
 def test_sns_topic_created():
-    assert("AWS::SNS::Topic" in get_template())
+    app = core.App()
+    stack = %name.PascalCased%Stack(app, "%name.StackName%")
+    template = assertions.Template.from_stack(stack)
+
+    template.resource_count_is("AWS::SNS::Topic", 1)
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/package.template.json b/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/package.template.json
index d4d76c656ba2e..20e4c3829d597 100644
--- a/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/package.template.json
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/package.template.json
@@ -12,6 +12,7 @@
   },
   "devDependencies": {
     "aws-cdk": "%cdk-version%",
+    "@aws-cdk/assertions-alpha": "%cdk-version%",
     "@types/jest": "^26.0.10",
     "@types/node": "10.17.27",
     "jest": "^26.4.2",
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/test/%name%.test.template.ts b/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/test/%name%.test.template.ts
index a563f50309295..5cfaa87ab2ce5 100644
--- a/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/test/%name%.test.template.ts
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/test/%name%.test.template.ts
@@ -1,12 +1,17 @@
 import * as cdk from 'aws-cdk-lib';
+import { Template, Match } from '@aws-cdk/assertions-alpha';
 import * as %name.PascalCased% from '../lib/%name%-stack';
 
 test('SQS Queue and SNS Topic Created', () => {
-    const app = new cdk.App();
-    // WHEN
-    const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
-    // THEN
-    const actual = JSON.stringify(app.synth().getStackArtifact(stack.artifactId).template);
-    expect(actual).toContain('AWS::SQS::Queue');
-    expect(actual).toContain('AWS::SNS::Topic');
+  const app = new cdk.App();
+  // WHEN
+  const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack');
+  // THEN
+
+  const template = Template.fromStack(stack);
+
+  template.hasResourceProperties('AWS::SQS::Queue', {
+    VisibilityTimeout: 300
+  });
+  template.resourceCountIs('AWS::SNS::Topic', 1);
 });
diff --git a/packages/aws-cdk/test/integ/init/test-go.sh b/packages/aws-cdk/test/integ/init/test-go.sh
index 6b461f3e25ef5..58959855073f0 100755
--- a/packages/aws-cdk/test/integ/init/test-go.sh
+++ b/packages/aws-cdk/test/integ/init/test-go.sh
@@ -5,13 +5,14 @@
 set -eu
 scriptdir=$(cd $(dirname $0) && pwd)
 source ${scriptdir}/common.bash
+dist_root=$(cd ${DIST_ROOT:-.} && pwd)
 
 header Go
 
 #------------------------------------------------------------------
 
 if [[ "${1:-}" == "" ]]; then
-    templates="app"
+    templates="app sample-app"
 else
     templates="$@"
 fi
@@ -22,5 +23,8 @@ for template in $templates; do
     setup
 
     cdk init -l go $template
+    go mod edit -replace github.com/aws/aws-cdk-go/awscdk=$dist_root/go/awscdk
+    go mod tidy
+    go test
     cdk synth
 done
diff --git a/packages/aws-cdk/test/integ/init/test-java.sh b/packages/aws-cdk/test/integ/init/test-java.sh
index f27441809da3c..d2c95984fb178 100755
--- a/packages/aws-cdk/test/integ/init/test-java.sh
+++ b/packages/aws-cdk/test/integ/init/test-java.sh
@@ -22,5 +22,6 @@ for template in $templates; do
     setup
 
     cdk init -l java $template
+    mvn package
     cdk synth
 done
diff --git a/packages/aws-cdk/test/integ/init/test-python.sh b/packages/aws-cdk/test/integ/init/test-python.sh
index 1f5163df5ae48..d40d94d4534ca 100755
--- a/packages/aws-cdk/test/integ/init/test-python.sh
+++ b/packages/aws-cdk/test/integ/init/test-python.sh
@@ -26,6 +26,8 @@ for template in $templates; do
     source .venv/bin/activate
     type -p pip
     pip install -r requirements.txt
+    ./.venv/bin/pip install -r requirements-dev.txt
+    pytest
 
     cdk synth
 done

From 8d4aaca2d11d860f20659dd76bc7f9c68b17466f Mon Sep 17 00:00:00 2001
From: AWS CDK Automation
 <43080478+aws-cdk-automation@users.noreply.github.com>
Date: Thu, 4 Nov 2021 04:08:21 +0530
Subject: [PATCH 121/148] chore: npm-check-updates && yarn upgrade (#17304)

Ran npm-check-updates and yarn upgrade to keep the `yarn.lock` file up-to-date.
---
 packages/@aws-cdk/core/package.json                       | 2 +-
 .../test/example-resource.test.ts                         | 4 ++++
 packages/aws-cdk-lib/package.json                         | 2 +-
 packages/monocdk/package.json                             | 2 +-
 yarn.lock                                                 | 8 ++++----
 5 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/packages/@aws-cdk/core/package.json b/packages/@aws-cdk/core/package.json
index 45e4232abb477..a57f69397dba1 100644
--- a/packages/@aws-cdk/core/package.json
+++ b/packages/@aws-cdk/core/package.json
@@ -191,7 +191,7 @@
     "@balena/dockerignore": "^1.0.2",
     "constructs": "^3.3.69",
     "fs-extra": "^9.1.0",
-    "ignore": "^5.1.8",
+    "ignore": "^5.1.9",
     "minimatch": "^3.0.4"
   },
   "bundledDependencies": [
diff --git a/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts b/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts
index 7ef95e9a6e671..cbfb43344ad25 100644
--- a/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts
+++ b/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts
@@ -188,6 +188,10 @@ describe('Example Resource', () => {
         'my-example-resource-name');
     });
 
+    test('throws when accessing connections', () => {
+      expect(() => exampleResource.connections).toThrow();
+    });
+
     test('has the same name as it was imported with', () => {
       expect(exampleResource.exampleResourceName).toEqual('my-example-resource-name');
     });
diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json
index de4d8379cac35..1d2d0c73daa50 100644
--- a/packages/aws-cdk-lib/package.json
+++ b/packages/aws-cdk-lib/package.json
@@ -114,7 +114,7 @@
     "diff": "^5.0.0",
     "fast-deep-equal": "^3.1.3",
     "fs-extra": "^9.1.0",
-    "ignore": "^5.1.8",
+    "ignore": "^5.1.9",
     "jsonschema": "^1.4.0",
     "minimatch": "^3.0.4",
     "punycode": "^2.1.1",
diff --git a/packages/monocdk/package.json b/packages/monocdk/package.json
index 7e0b967fe70ab..49e11473c6be6 100644
--- a/packages/monocdk/package.json
+++ b/packages/monocdk/package.json
@@ -111,7 +111,7 @@
     "diff": "^5.0.0",
     "fast-deep-equal": "^3.1.3",
     "fs-extra": "^9.1.0",
-    "ignore": "^5.1.8",
+    "ignore": "^5.1.9",
     "jsonschema": "^1.4.0",
     "minimatch": "^3.0.4",
     "punycode": "^2.1.1",
diff --git a/yarn.lock b/yarn.lock
index 88df4ad3d4edb..97a3298a6c72f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5277,10 +5277,10 @@ ignore@^4.0.6:
   resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
   integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
 
-ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8, ignore@~5.1.8:
-  version "5.1.8"
-  resolved "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
-  integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
+ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8, ignore@^5.1.9, ignore@~5.1.8:
+  version "5.1.9"
+  resolved "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz#9ec1a5cbe8e1446ec60d4420060d43aa6e7382fb"
+  integrity sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==
 
 immediate@~3.0.5:
   version "3.0.6"

From 5333c72a66955995a65cb365c6a788b82f02afd2 Mon Sep 17 00:00:00 2001
From: Roman <491247+moltar@users.noreply.github.com>
Date: Thu, 4 Nov 2021 06:31:37 +0700
Subject: [PATCH 122/148] docs(aws-stepfunctions-tasks): fixes action example
 to be camelCase  (#17292)

> Use camelCase for actions and PascalCase for parameter names.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-stepfunctions-tasks/README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md
index cedf89eefe07c..2f5d463067a35 100644
--- a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md
+++ b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md
@@ -348,7 +348,7 @@ action name does not match with the API service/action name:
 ```ts
 const listBuckets = new tasks.CallAwsService(this, 'ListBuckets', {
   service: 's3',
-  action: 'ListBuckets',
+  action: 'listBuckets',
   iamResources: ['*'],
   iamAction: 's3:ListAllMyBuckets',
 });

From 30ac0cc2d95ef3fd79d0658428975ea675b6916f Mon Sep 17 00:00:00 2001
From: Berend de Boer 
Date: Thu, 4 Nov 2021 13:25:20 +1300
Subject: [PATCH 123/148] fix(s3): enforce that fromBucketAttributes supplies a
 valid bucket name (#16915)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../aws-apigateway/test/domains.test.ts       |  8 +-
 .../aws-cloudtrail/test/cloudtrail.test.ts    |  4 +-
 .../aws-codebuild/test/project.test.ts        |  8 +-
 .../aws-ec2/test/cfn-init-element.test.ts     |  4 +-
 .../@aws-cdk/aws-ec2/test/cfn-init.test.ts    |  2 +-
 packages/@aws-cdk/aws-glue/test/code.test.ts  |  8 +-
 .../aws-glue/test/job-executable.test.ts      |  2 +-
 packages/@aws-cdk/aws-glue/test/job.test.ts   | 28 +++---
 .../test/notifications.test.ts                | 14 +--
 packages/@aws-cdk/aws-s3/lib/bucket.ts        | 90 ++++++++++---------
 packages/@aws-cdk/aws-s3/test/bucket.test.ts  | 26 ++++--
 .../pipelines/test/compliance/synths.test.ts  |  4 +-
 .../test/compliance/validations.test.ts       |  4 +-
 13 files changed, 108 insertions(+), 94 deletions(-)

diff --git a/packages/@aws-cdk/aws-apigateway/test/domains.test.ts b/packages/@aws-cdk/aws-apigateway/test/domains.test.ts
index 7ad0f4224d70b..7b8817df48853 100644
--- a/packages/@aws-cdk/aws-apigateway/test/domains.test.ts
+++ b/packages/@aws-cdk/aws-apigateway/test/domains.test.ts
@@ -388,7 +388,7 @@ describe('domains', () => {
 
   test('accepts a mutual TLS configuration', () => {
     const stack = new Stack();
-    const bucket = Bucket.fromBucketName(stack, 'testBucket', 'exampleBucket');
+    const bucket = Bucket.fromBucketName(stack, 'testBucket', 'example-bucket');
     new apigw.DomainName(stack, 'another-domain', {
       domainName: 'example.com',
       mtls: {
@@ -402,14 +402,14 @@ describe('domains', () => {
       'DomainName': 'example.com',
       'EndpointConfiguration': { 'Types': ['REGIONAL'] },
       'RegionalCertificateArn': 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d',
-      'MutualTlsAuthentication': { 'TruststoreUri': 's3://exampleBucket/someca.pem' },
+      'MutualTlsAuthentication': { 'TruststoreUri': 's3://example-bucket/someca.pem' },
     });
 
   });
 
   test('mTLS should allow versions to be set on the s3 bucket', () => {
     const stack = new Stack();
-    const bucket = Bucket.fromBucketName(stack, 'testBucket', 'exampleBucket');
+    const bucket = Bucket.fromBucketName(stack, 'testBucket', 'example-bucket');
     new apigw.DomainName(stack, 'another-domain', {
       domainName: 'example.com',
       certificate: acm.Certificate.fromCertificateArn(stack, 'cert2', 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'),
@@ -423,7 +423,7 @@ describe('domains', () => {
       'DomainName': 'example.com',
       'EndpointConfiguration': { 'Types': ['REGIONAL'] },
       'RegionalCertificateArn': 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d',
-      'MutualTlsAuthentication': { 'TruststoreUri': 's3://exampleBucket/someca.pem', 'TruststoreVersion': 'version' },
+      'MutualTlsAuthentication': { 'TruststoreUri': 's3://example-bucket/someca.pem', 'TruststoreVersion': 'version' },
     });
   });
 
diff --git a/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts b/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts
index c00f01d43acc4..89bd89d84c31c 100644
--- a/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts
+++ b/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts
@@ -131,13 +131,13 @@ describe('cloudtrail', () => {
     test('with imported s3 bucket', () => {
       // GIVEN
       const stack = getTestStack();
-      const bucket = s3.Bucket.fromBucketName(stack, 'S3', 'SomeBucket');
+      const bucket = s3.Bucket.fromBucketName(stack, 'S3', 'somebucket');
 
       // WHEN
       new Trail(stack, 'Trail', { bucket });
 
       expect(stack).toHaveResource('AWS::CloudTrail::Trail', {
-        S3BucketName: 'SomeBucket',
+        S3BucketName: 'somebucket',
       });
     });
 
diff --git a/packages/@aws-cdk/aws-codebuild/test/project.test.ts b/packages/@aws-cdk/aws-codebuild/test/project.test.ts
index 08fbe3e8f8768..0041d1651ec9d 100644
--- a/packages/@aws-cdk/aws-codebuild/test/project.test.ts
+++ b/packages/@aws-cdk/aws-codebuild/test/project.test.ts
@@ -673,7 +673,7 @@ describe('Environment', () => {
   test('logs config - s3', () => {
     // GIVEN
     const stack = new cdk.Stack();
-    const bucket = s3.Bucket.fromBucketName(stack, 'LogBucket', 'MyBucketName');
+    const bucket = s3.Bucket.fromBucketName(stack, 'LogBucket', 'mybucketname');
 
     // WHEN
     new codebuild.Project(stack, 'Project', {
@@ -693,7 +693,7 @@ describe('Environment', () => {
     expect(stack).toHaveResourceLike('AWS::CodeBuild::Project', {
       LogsConfig: objectLike({
         S3Logs: {
-          Location: 'MyBucketName/my-logs',
+          Location: 'mybucketname/my-logs',
           Status: 'ENABLED',
         },
       }),
@@ -703,7 +703,7 @@ describe('Environment', () => {
   test('logs config - cloudWatch and s3', () => {
     // GIVEN
     const stack = new cdk.Stack();
-    const bucket = s3.Bucket.fromBucketName(stack, 'LogBucket2', 'MyBucketName');
+    const bucket = s3.Bucket.fromBucketName(stack, 'LogBucket2', 'mybucketname');
     const logGroup = logs.LogGroup.fromLogGroupName(stack, 'LogGroup2', 'MyLogGroupName');
 
     // WHEN
@@ -730,7 +730,7 @@ describe('Environment', () => {
           Status: 'ENABLED',
         },
         S3Logs: {
-          Location: 'MyBucketName',
+          Location: 'mybucketname',
           Status: 'ENABLED',
         },
       }),
diff --git a/packages/@aws-cdk/aws-ec2/test/cfn-init-element.test.ts b/packages/@aws-cdk/aws-ec2/test/cfn-init-element.test.ts
index 75896912f3661..8f1c4951d2bf3 100644
--- a/packages/@aws-cdk/aws-ec2/test/cfn-init-element.test.ts
+++ b/packages/@aws-cdk/aws-ec2/test/cfn-init-element.test.ts
@@ -664,7 +664,7 @@ describe('InitSource', () => {
 
   test('fromS3Object uses object URL', () => {
     // GIVEN
-    const bucket = s3.Bucket.fromBucketName(stack, 'bucket', 'MyBucket');
+    const bucket = s3.Bucket.fromBucketName(stack, 'bucket', 'mybucket');
     const source = ec2.InitSource.fromS3Object('/tmp/foo', bucket, 'myKey');
 
     // WHEN
@@ -672,7 +672,7 @@ describe('InitSource', () => {
 
     // THEN
     expect(rendered).toEqual({
-      '/tmp/foo': expect.stringContaining('/MyBucket/myKey'),
+      '/tmp/foo': expect.stringContaining('/mybucket/myKey'),
     });
   });
 
diff --git a/packages/@aws-cdk/aws-ec2/test/cfn-init.test.ts b/packages/@aws-cdk/aws-ec2/test/cfn-init.test.ts
index 37d4fe2d72d28..2a9cce5e76719 100644
--- a/packages/@aws-cdk/aws-ec2/test/cfn-init.test.ts
+++ b/packages/@aws-cdk/aws-ec2/test/cfn-init.test.ts
@@ -667,7 +667,7 @@ class SingletonLocationSythesizer extends DefaultStackSynthesizer {
   public addFileAsset(_asset: FileAssetSource): FileAssetLocation {
     const httpUrl = 'https://MyBucket.s3.amazonaws.com/MyAsset';
     return {
-      bucketName: 'MyAssetBucket',
+      bucketName: 'myassetbucket',
       objectKey: 'MyAssetFile',
       httpUrl,
       s3ObjectUrl: httpUrl,
diff --git a/packages/@aws-cdk/aws-glue/test/code.test.ts b/packages/@aws-cdk/aws-glue/test/code.test.ts
index 061f6d26c351f..8049bc1b29c6a 100644
--- a/packages/@aws-cdk/aws-glue/test/code.test.ts
+++ b/packages/@aws-cdk/aws-glue/test/code.test.ts
@@ -17,7 +17,7 @@ describe('Code', () => {
     let bucket: s3.IBucket;
 
     test('with valid bucket name and key and bound by job sets the right path and grants the job permissions to read from it', () => {
-      bucket = s3.Bucket.fromBucketName(stack, 'Bucket', 'bucketName');
+      bucket = s3.Bucket.fromBucketName(stack, 'Bucket', 'bucketname');
       script = glue.Code.fromBucket(bucket, key);
       new glue.Job(stack, 'Job1', {
         executable: glue.JobExecutable.pythonShell({
@@ -29,7 +29,7 @@ describe('Code', () => {
 
       Template.fromStack(stack).hasResourceProperties('AWS::Glue::Job', {
         Command: {
-          ScriptLocation: 's3://bucketName/script',
+          ScriptLocation: 's3://bucketname/script',
         },
       });
 
@@ -53,7 +53,7 @@ describe('Code', () => {
                       {
                         Ref: 'AWS::Partition',
                       },
-                      ':s3:::bucketName',
+                      ':s3:::bucketname',
                     ],
                   ],
                 },
@@ -65,7 +65,7 @@ describe('Code', () => {
                       {
                         Ref: 'AWS::Partition',
                       },
-                      ':s3:::bucketName/script',
+                      ':s3:::bucketname/script',
                     ],
                   ],
                 },
diff --git a/packages/@aws-cdk/aws-glue/test/job-executable.test.ts b/packages/@aws-cdk/aws-glue/test/job-executable.test.ts
index 481bd16dc8944..5fcf3b1487764 100644
--- a/packages/@aws-cdk/aws-glue/test/job-executable.test.ts
+++ b/packages/@aws-cdk/aws-glue/test/job-executable.test.ts
@@ -31,7 +31,7 @@ describe('JobExecutable', () => {
 
   beforeEach(() => {
     stack = new cdk.Stack();
-    bucket = s3.Bucket.fromBucketName(stack, 'Bucket', 'bucketName');
+    bucket = s3.Bucket.fromBucketName(stack, 'Bucket', 'bucketname');
     script = glue.Code.fromBucket(bucket, 'script.py');
   });
 
diff --git a/packages/@aws-cdk/aws-glue/test/job.test.ts b/packages/@aws-cdk/aws-glue/test/job.test.ts
index 625e4743570fd..c338b4d09cb42 100644
--- a/packages/@aws-cdk/aws-glue/test/job.test.ts
+++ b/packages/@aws-cdk/aws-glue/test/job.test.ts
@@ -55,7 +55,7 @@ describe('Job', () => {
 
   describe('new', () => {
     const className = 'com.amazon.test.ClassName';
-    const codeBucketName = 'bucketName';
+    const codeBucketName = 'bucketname';
     const codeBucketAccessStatement = {
       Action: [
         's3:GetObject*',
@@ -166,7 +166,7 @@ describe('Job', () => {
         Template.fromStack(stack).hasResourceProperties('AWS::Glue::Job', {
           Command: {
             Name: 'glueetl',
-            ScriptLocation: 's3://bucketName/script',
+            ScriptLocation: 's3://bucketname/script',
           },
           Role: {
             'Fn::GetAtt': [
@@ -383,7 +383,7 @@ describe('Job', () => {
       });
 
       describe('with bucket provided', () => {
-        const sparkUIBucketName = 'sparkBucketName';
+        const sparkUIBucketName = 'sparkbucketname';
         let sparkUIBucket: s3.IBucket;
 
         beforeEach(() => {
@@ -420,7 +420,7 @@ describe('Job', () => {
                           {
                             Ref: 'AWS::Partition',
                           },
-                          ':s3:::sparkBucketName',
+                          ':s3:::sparkbucketname',
                         ],
                       ],
                     },
@@ -432,7 +432,7 @@ describe('Job', () => {
                           {
                             Ref: 'AWS::Partition',
                           },
-                          ':s3:::sparkBucketName/*',
+                          ':s3:::sparkbucketname/*',
                         ],
                       ],
                     },
@@ -460,7 +460,7 @@ describe('Job', () => {
       });
 
       describe('with bucket and path provided', () => {
-        const sparkUIBucketName = 'sparkBucketName';
+        const sparkUIBucketName = 'sparkbucketname';
         const prefix = 'some/path/';
         let sparkUIBucket: s3.IBucket;
 
@@ -516,7 +516,7 @@ describe('Job', () => {
         Template.fromStack(stack).hasResourceProperties('AWS::Glue::Job', {
           Command: {
             Name: 'glueetl',
-            ScriptLocation: 's3://bucketName/script',
+            ScriptLocation: 's3://bucketname/script',
           },
           Role: {
             'Fn::GetAtt': [
@@ -614,7 +614,7 @@ describe('Job', () => {
         GlueVersion: '2.0',
         Command: {
           Name: 'glueetl',
-          ScriptLocation: 's3://bucketName/script',
+          ScriptLocation: 's3://bucketname/script',
           PythonVersion: '3',
         },
         Role: {
@@ -625,9 +625,9 @@ describe('Job', () => {
         },
         DefaultArguments: {
           '--job-language': 'python',
-          '--extra-jars': 's3://bucketName/file1.jar,s3://bucketName/file2.jar',
-          '--extra-py-files': 's3://bucketName/file1.py,s3://bucketName/file2.py',
-          '--extra-files': 's3://bucketName/file1.txt,s3://bucketName/file2.txt',
+          '--extra-jars': 's3://bucketname/file1.jar,s3://bucketname/file2.jar',
+          '--extra-py-files': 's3://bucketname/file1.py,s3://bucketname/file2.py',
+          '--extra-files': 's3://bucketname/file1.txt,s3://bucketname/file2.txt',
           '--user-jars-first': 'true',
         },
       });
@@ -649,7 +649,7 @@ describe('Job', () => {
         GlueVersion: '2.0',
         Command: {
           Name: 'gluestreaming',
-          ScriptLocation: 's3://bucketName/script',
+          ScriptLocation: 's3://bucketname/script',
         },
         Role: {
           'Fn::GetAtt': [
@@ -660,8 +660,8 @@ describe('Job', () => {
         DefaultArguments: {
           '--job-language': 'scala',
           '--class': 'com.amazon.test.ClassName',
-          '--extra-jars': 's3://bucketName/file1.jar,s3://bucketName/file2.jar',
-          '--extra-files': 's3://bucketName/file1.txt,s3://bucketName/file2.txt',
+          '--extra-jars': 's3://bucketname/file1.jar,s3://bucketname/file2.jar',
+          '--extra-files': 's3://bucketname/file1.txt,s3://bucketname/file2.txt',
           '--user-jars-first': 'true',
         },
       });
diff --git a/packages/@aws-cdk/aws-s3-notifications/test/notifications.test.ts b/packages/@aws-cdk/aws-s3-notifications/test/notifications.test.ts
index 43922fb54cc5d..2bfe968f99279 100644
--- a/packages/@aws-cdk/aws-s3-notifications/test/notifications.test.ts
+++ b/packages/@aws-cdk/aws-s3-notifications/test/notifications.test.ts
@@ -336,7 +336,7 @@ describe('CloudWatch Events', () => {
   test('onCloudTrailPutObject contains the Bucket ARN itself when path is undefined', () => {
     const stack = new cdk.Stack();
     const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', {
-      bucketName: 'MyBucket',
+      bucketName: 'mybucket',
     });
     bucket.onCloudTrailPutObject('PutRule', {
       target: {
@@ -363,7 +363,7 @@ describe('CloudWatch Events', () => {
                     {
                       'Ref': 'AWS::Partition',
                     },
-                    ':s3:::MyBucket',
+                    ':s3:::mybucket',
                   ],
                 ],
               },
@@ -378,7 +378,7 @@ describe('CloudWatch Events', () => {
   test("onCloudTrailPutObject contains the path when it's provided", () => {
     const stack = new cdk.Stack();
     const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', {
-      bucketName: 'MyBucket',
+      bucketName: 'mybucket',
     });
     bucket.onCloudTrailPutObject('PutRule', {
       target: {
@@ -406,7 +406,7 @@ describe('CloudWatch Events', () => {
                     {
                       'Ref': 'AWS::Partition',
                     },
-                    ':s3:::MyBucket/my/path.zip',
+                    ':s3:::mybucket/my/path.zip',
                   ],
                 ],
               },
@@ -421,7 +421,7 @@ describe('CloudWatch Events', () => {
   test('onCloudTrailWriteObject matches on events CompleteMultipartUpload, CopyObject, and PutObject', () => {
     const stack = new cdk.Stack();
     const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', {
-      bucketName: 'MyBucket',
+      bucketName: 'mybucket',
     });
     bucket.onCloudTrailWriteObject('OnCloudTrailWriteObjectRule', {
       target: {
@@ -449,7 +449,7 @@ describe('CloudWatch Events', () => {
   test('onCloudTrailWriteObject matches on the requestParameter bucketName when the path is not provided', () => {
     const stack = new cdk.Stack();
     const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', {
-      bucketName: 'MyBucket',
+      bucketName: 'mybucket',
     });
     bucket.onCloudTrailWriteObject('OnCloudTrailWriteObjectRule', {
       target: {
@@ -476,7 +476,7 @@ describe('CloudWatch Events', () => {
   test('onCloudTrailWriteObject matches on the requestParameters bucketName and key when the path is provided', () => {
     const stack = new cdk.Stack();
     const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', {
-      bucketName: 'MyBucket',
+      bucketName: 'mybucket',
     });
     bucket.onCloudTrailWriteObject('OnCloudTrailWriteObjectRule', {
       target: {
diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts
index 67037f874bc3e..157aa31a3ed5f 100644
--- a/packages/@aws-cdk/aws-s3/lib/bucket.ts
+++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts
@@ -1396,6 +1396,7 @@ export class Bucket extends BucketBase {
     if (!bucketName) {
       throw new Error('Bucket name is required');
     }
+    Bucket.validateBucketName(bucketName);
 
     const newUrlFormat = attrs.bucketWebsiteNewUrlFormat === undefined
       ? false
@@ -1434,6 +1435,52 @@ export class Bucket extends BucketBase {
     });
   }
 
+  /**
+   * Thrown an exception if the given bucket name is not valid.
+   *
+   * @param physicalName name of the bucket.
+   */
+  public static validateBucketName(physicalName: string): void {
+    const bucketName = physicalName;
+    if (!bucketName || Token.isUnresolved(bucketName)) {
+      // the name is a late-bound value, not a defined string,
+      // so skip validation
+      return;
+    }
+
+    const errors: string[] = [];
+
+    // Rules codified from https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html
+    if (bucketName.length < 3 || bucketName.length > 63) {
+      errors.push('Bucket name must be at least 3 and no more than 63 characters');
+    }
+    const charsetMatch = bucketName.match(/[^a-z0-9.-]/);
+    if (charsetMatch) {
+      errors.push('Bucket name must only contain lowercase characters and the symbols, period (.) and dash (-) '
+        + `(offset: ${charsetMatch.index})`);
+    }
+    if (!/[a-z0-9]/.test(bucketName.charAt(0))) {
+      errors.push('Bucket name must start and end with a lowercase character or number '
+        + '(offset: 0)');
+    }
+    if (!/[a-z0-9]/.test(bucketName.charAt(bucketName.length - 1))) {
+      errors.push('Bucket name must start and end with a lowercase character or number '
+        + `(offset: ${bucketName.length - 1})`);
+    }
+    const consecSymbolMatch = bucketName.match(/\.-|-\.|\.\./);
+    if (consecSymbolMatch) {
+      errors.push('Bucket name must not have dash next to period, or period next to dash, or consecutive periods '
+        + `(offset: ${consecSymbolMatch.index})`);
+    }
+    if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(bucketName)) {
+      errors.push('Bucket name must not resemble an IP address');
+    }
+
+    if (errors.length > 0) {
+      throw new Error(`Invalid S3 bucket name (value: ${bucketName})${EOL}${errors.join(EOL)}`);
+    }
+  }
+
   public readonly bucketArn: string;
   public readonly bucketName: string;
   public readonly bucketDomainName: string;
@@ -1462,7 +1509,7 @@ export class Bucket extends BucketBase {
 
     const { bucketEncryption, encryptionKey } = this.parseEncryption(props);
 
-    this.validateBucketName(this.physicalName);
+    Bucket.validateBucketName(this.physicalName);
 
     const websiteConfiguration = this.renderWebsiteConfiguration(props);
     this.isWebsite = (websiteConfiguration !== undefined);
@@ -1600,47 +1647,6 @@ export class Bucket extends BucketBase {
     this.addToResourcePolicy(statement);
   }
 
-  private validateBucketName(physicalName: string): void {
-    const bucketName = physicalName;
-    if (!bucketName || Token.isUnresolved(bucketName)) {
-      // the name is a late-bound value, not a defined string,
-      // so skip validation
-      return;
-    }
-
-    const errors: string[] = [];
-
-    // Rules codified from https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html
-    if (bucketName.length < 3 || bucketName.length > 63) {
-      errors.push('Bucket name must be at least 3 and no more than 63 characters');
-    }
-    const charsetMatch = bucketName.match(/[^a-z0-9.-]/);
-    if (charsetMatch) {
-      errors.push('Bucket name must only contain lowercase characters and the symbols, period (.) and dash (-) '
-        + `(offset: ${charsetMatch.index})`);
-    }
-    if (!/[a-z0-9]/.test(bucketName.charAt(0))) {
-      errors.push('Bucket name must start and end with a lowercase character or number '
-        + '(offset: 0)');
-    }
-    if (!/[a-z0-9]/.test(bucketName.charAt(bucketName.length - 1))) {
-      errors.push('Bucket name must start and end with a lowercase character or number '
-        + `(offset: ${bucketName.length - 1})`);
-    }
-    const consecSymbolMatch = bucketName.match(/\.-|-\.|\.\./);
-    if (consecSymbolMatch) {
-      errors.push('Bucket name must not have dash next to period, or period next to dash, or consecutive periods '
-        + `(offset: ${consecSymbolMatch.index})`);
-    }
-    if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(bucketName)) {
-      errors.push('Bucket name must not resemble an IP address');
-    }
-
-    if (errors.length > 0) {
-      throw new Error(`Invalid S3 bucket name (value: ${bucketName})${EOL}${errors.join(EOL)}`);
-    }
-  }
-
   /**
    * Set up key properties and return the Bucket encryption property from the
    * user's configuration.
diff --git a/packages/@aws-cdk/aws-s3/test/bucket.test.ts b/packages/@aws-cdk/aws-s3/test/bucket.test.ts
index 3ef166722c1b6..67d263aa60ea5 100644
--- a/packages/@aws-cdk/aws-s3/test/bucket.test.ts
+++ b/packages/@aws-cdk/aws-s3/test/bucket.test.ts
@@ -3,9 +3,9 @@ import { EOL } from 'os';
 import { ResourcePart, SynthUtils, arrayWith, objectLike } from '@aws-cdk/assert-internal';
 import * as iam from '@aws-cdk/aws-iam';
 import * as kms from '@aws-cdk/aws-kms';
+import { testFutureBehavior, testLegacyBehavior } from '@aws-cdk/cdk-build-tools/lib/feature-flag';
 import * as cdk from '@aws-cdk/core';
 import * as cxapi from '@aws-cdk/cx-api';
-import { testFutureBehavior, testLegacyBehavior } from '@aws-cdk/cdk-build-tools/lib/feature-flag';
 import * as s3 from '../lib';
 
 // to make it easy to copy & paste from output:
@@ -103,8 +103,6 @@ describe('bucket', () => {
     expect(() => new s3.Bucket(stack, 'MyBucket2', {
       bucketName: '124.pp--33',
     })).not.toThrow();
-
-
   });
 
   test('bucket validation skips tokenized values', () => {
@@ -746,14 +744,24 @@ describe('bucket', () => {
       });
 
       const bucket = s3.Bucket.fromBucketAttributes(stack, 'ImportedBucket', {
-        bucketName: 'myBucket',
+        bucketName: 'mybucket',
         region: 'eu-west-1',
       });
 
-      expect(bucket.bucketRegionalDomainName).toEqual(`myBucket.s3.eu-west-1.${stack.urlSuffix}`);
-      expect(bucket.bucketWebsiteDomainName).toEqual(`myBucket.s3-website-eu-west-1.${stack.urlSuffix}`);
+      expect(bucket.bucketRegionalDomainName).toEqual(`mybucket.s3.eu-west-1.${stack.urlSuffix}`);
+      expect(bucket.bucketWebsiteDomainName).toEqual(`mybucket.s3-website-eu-west-1.${stack.urlSuffix}`);
+
 
+    });
+
+    test('import needs to specify a valid bucket name', () => {
+      const stack = new cdk.Stack(undefined, undefined, {
+        env: { region: 'us-east-1' },
+      });
 
+      expect(() => s3.Bucket.fromBucketAttributes(stack, 'MyBucket3', {
+        bucketName: 'arn:aws:s3:::example-com',
+      })).toThrow();
     });
   });
 
@@ -2129,11 +2137,11 @@ describe('bucket', () => {
     const stack = new cdk.Stack();
 
     // WHEN
-    const bucket = s3.Bucket.fromBucketArn(stack, 'my-bucket', 'arn:aws:s3:::my_corporate_bucket');
+    const bucket = s3.Bucket.fromBucketArn(stack, 'my-bucket', 'arn:aws:s3:::my-corporate-bucket');
 
     // THEN
-    expect(bucket.bucketName).toEqual('my_corporate_bucket');
-    expect(bucket.bucketArn).toEqual('arn:aws:s3:::my_corporate_bucket');
+    expect(bucket.bucketName).toEqual('my-corporate-bucket');
+    expect(bucket.bucketArn).toEqual('arn:aws:s3:::my-corporate-bucket');
 
   });
 
diff --git a/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts b/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts
index 4b5a072099469..acbce1d765f36 100644
--- a/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts
+++ b/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts
@@ -748,7 +748,7 @@ behavior('Pipeline action contains a hash that changes as the buildspec changes'
 behavior('Synth CodeBuild project role can be granted permissions', (suite) => {
   let bucket: s3.IBucket;
   beforeEach(() => {
-    bucket = s3.Bucket.fromBucketArn(pipelineStack, 'Bucket', 'arn:aws:s3:::ThisParticularBucket');
+    bucket = s3.Bucket.fromBucketArn(pipelineStack, 'Bucket', 'arn:aws:s3:::this-particular-bucket');
   });
 
 
@@ -787,7 +787,7 @@ behavior('Synth CodeBuild project role can be granted permissions', (suite) => {
       PolicyDocument: {
         Statement: Match.arrayWith([Match.objectLike({
           Action: ['s3:GetObject*', 's3:GetBucket*', 's3:List*'],
-          Resource: ['arn:aws:s3:::ThisParticularBucket', 'arn:aws:s3:::ThisParticularBucket/*'],
+          Resource: ['arn:aws:s3:::this-particular-bucket', 'arn:aws:s3:::this-particular-bucket/*'],
         })]),
       },
     });
diff --git a/packages/@aws-cdk/pipelines/test/compliance/validations.test.ts b/packages/@aws-cdk/pipelines/test/compliance/validations.test.ts
index 7a6a562a8707a..c61cd40474388 100644
--- a/packages/@aws-cdk/pipelines/test/compliance/validations.test.ts
+++ b/packages/@aws-cdk/pipelines/test/compliance/validations.test.ts
@@ -463,7 +463,7 @@ behavior('can add policy statements to shell script action', (suite) => {
 behavior('can grant permissions to shell script action', (suite) => {
   let bucket: s3.IBucket;
   beforeEach(() => {
-    bucket = s3.Bucket.fromBucketArn(pipelineStack, 'Bucket', 'arn:aws:s3:::ThisParticularBucket');
+    bucket = s3.Bucket.fromBucketArn(pipelineStack, 'Bucket', 'arn:aws:s3:::this-particular-bucket');
   });
 
   suite.legacy(() => {
@@ -505,7 +505,7 @@ behavior('can grant permissions to shell script action', (suite) => {
       PolicyDocument: {
         Statement: Match.arrayWith([Match.objectLike({
           Action: ['s3:GetObject*', 's3:GetBucket*', 's3:List*'],
-          Resource: ['arn:aws:s3:::ThisParticularBucket', 'arn:aws:s3:::ThisParticularBucket/*'],
+          Resource: ['arn:aws:s3:::this-particular-bucket', 'arn:aws:s3:::this-particular-bucket/*'],
         })]),
       },
     });

From e32b61652b5d01c44b05c2ac6d5fb1e99b50e059 Mon Sep 17 00:00:00 2001
From: Adam Ruka 
Date: Thu, 4 Nov 2021 02:53:56 -0700
Subject: [PATCH 124/148] fix(cli): no longer disable rollback by default for
 hotswap deployments (#17317)

Previously, we would default the `--rollback` flag to `false` if it wasn't explicitly provided
if the `--hotswap` option was also passed to `cdk deploy`.
However, disable rollback does not play well with deployments that cause replacements -
they fail, and leave the Stack in a weird state.
For that reason, stop disabling rollback by default.
It's still possible to disable rollback easily if a customer wants to by using the `-R` switch.

Fixes #17267

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/aws-cdk/bin/cdk.ts                    | 9 ++++++---
 packages/aws-cdk/lib/api/deploy-stack.ts       | 2 +-
 packages/aws-cdk/lib/cdk-toolkit.ts            | 1 +
 packages/aws-cdk/test/api/deploy-stack.test.ts | 4 ++--
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/packages/aws-cdk/bin/cdk.ts b/packages/aws-cdk/bin/cdk.ts
index aaaef0deb3182..b5b60f895c8ca 100644
--- a/packages/aws-cdk/bin/cdk.ts
+++ b/packages/aws-cdk/bin/cdk.ts
@@ -105,10 +105,13 @@ async function parseCommandLineArguments() {
       .option('outputs-file', { type: 'string', alias: 'O', desc: 'Path to file where stack outputs will be written as JSON', requiresArg: true })
       .option('previous-parameters', { type: 'boolean', default: true, desc: 'Use previous values for existing parameters (you must specify all parameters on every deployment if this is disabled)' })
       .option('progress', { type: 'string', choices: [StackActivityProgress.BAR, StackActivityProgress.EVENTS], desc: 'Display mode for stack activity events' })
-      .option('rollback', { type: 'boolean', desc: 'Rollback stack to stable state on failure (iterate more rapidly with --no-rollback or -R)' })
+      .option('rollback', {
+        type: 'boolean',
+        desc: "Rollback stack to stable state on failure. Defaults to 'true', iterate more rapidly with --no-rollback or -R. " +
+          'Note: do **not** disable this flag for deployments with resource replacements, as that will always fail',
+      })
       // Hack to get '-R' as an alias for '--no-rollback', suggested by: https://github.com/yargs/yargs/issues/1729
-      .option('R', { type: 'boolean', hidden: true })
-      .middleware(yargsNegativeAlias('R', 'rollback'), true)
+      .option('R', { type: 'boolean', hidden: true }).middleware(yargsNegativeAlias('R', 'rollback'), true)
       .option('hotswap', {
         type: 'boolean',
         desc: "Attempts to perform a 'hotswap' deployment, " +
diff --git a/packages/aws-cdk/lib/api/deploy-stack.ts b/packages/aws-cdk/lib/api/deploy-stack.ts
index ab662d34b517c..2d35a3a01aea0 100644
--- a/packages/aws-cdk/lib/api/deploy-stack.ts
+++ b/packages/aws-cdk/lib/api/deploy-stack.ts
@@ -317,7 +317,7 @@ async function prepareAndExecuteChangeSet(
   if (execute) {
     debug('Initiating execution of changeset %s on stack %s', changeSet.Id, deployName);
 
-    const shouldDisableRollback = (options.rollback === undefined && options.hotswap === true) || options.rollback === false;
+    const shouldDisableRollback = options.rollback === false;
     // Do a bit of contortions to only pass the `DisableRollback` flag if it's true. That way,
     // CloudFormation won't balk at the unrecognized option in regions where the feature is not available yet.
     const disableRollback = shouldDisableRollback ? { DisableRollback: true } : undefined;
diff --git a/packages/aws-cdk/lib/cdk-toolkit.ts b/packages/aws-cdk/lib/cdk-toolkit.ts
index 65aa443190a57..cd5e591dce866 100644
--- a/packages/aws-cdk/lib/cdk-toolkit.ts
+++ b/packages/aws-cdk/lib/cdk-toolkit.ts
@@ -650,6 +650,7 @@ export interface DeployOptions {
    * @default true
    */
   readonly rollback?: boolean;
+
   /*
    * Whether to perform a 'hotswap' deployment.
    * A 'hotswap' deployment will attempt to short-circuit CloudFormation
diff --git a/packages/aws-cdk/test/api/deploy-stack.test.ts b/packages/aws-cdk/test/api/deploy-stack.test.ts
index 13e4640ff01ec..4770e2ad9528f 100644
--- a/packages/aws-cdk/test/api/deploy-stack.test.ts
+++ b/packages/aws-cdk/test/api/deploy-stack.test.ts
@@ -98,7 +98,7 @@ test("does not call tryHotswapDeployment() if 'hotswap' is false", async () => {
   expect(tryHotswapDeployment).not.toHaveBeenCalled();
 });
 
-test("rollback defaults to disabled if 'hotswap' is true", async () => {
+test("rollback still defaults to enabled even if 'hotswap' is enabled", async () => {
   // WHEN
   await deployStack({
     ...standardDeployStackArguments(),
@@ -107,7 +107,7 @@ test("rollback defaults to disabled if 'hotswap' is true", async () => {
   });
 
   // THEN
-  expect(cfnMocks.executeChangeSet).toHaveBeenCalledWith(expect.objectContaining({
+  expect(cfnMocks.executeChangeSet).not.toHaveBeenCalledWith(expect.objectContaining({
     DisableRollback: true,
   }));
 });

From c8cd515b3984ce0d8bfbe2d19cd56d299785e78b Mon Sep 17 00:00:00 2001
From: Eli Polonsky 
Date: Thu, 4 Nov 2021 12:18:29 +0200
Subject: [PATCH 125/148] revert: "chore: activate 'rosetta infuse' feature
 (#17191)" (#17329)

revert: "chore: activate 'rosetta infuse' feature (#17191)"
---
 pack.sh | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/pack.sh b/pack.sh
index 3c2d7dbce6c1a..168a17f972406 100755
--- a/pack.sh
+++ b/pack.sh
@@ -39,17 +39,12 @@ function lerna_scopes() {
 # Compile examples with respect to "decdk" directory, as all packages will
 # be symlinked there so they can all be included.
 echo "Extracting code samples" >&2
-$ROSETTA extract \
+node --experimental-worker $(which $ROSETTA) \
   --compile \
   --output samples.tabl.json \
   --directory packages/decdk \
   $(cat $TMPDIR/jsii.txt)
 
-echo "Infusing examples back into assemblies" >&2
-$ROSETTA infuse \
-  samples.tabl.json \
-  $(cat $TMPDIR/jsii.txt)
-
 # Jsii packaging (all at once using jsii-pacmak)
 echo "Packaging jsii modules" >&2
 $PACMAK \

From d9f7b58a91a625ffd9bc366767794a3101b0afeb Mon Sep 17 00:00:00 2001
From: AWS CDK Automation
 <43080478+aws-cdk-automation@users.noreply.github.com>
Date: Thu, 4 Nov 2021 17:08:34 +0530
Subject: [PATCH 126/148] feat(cfnspec): cloudformation spec v46.0.0 (#17223)

* feat: cloudformation spec v46.0.0

* fix generated code for new libraries: aws-panorama, aws-rekognition, aws-wisdom

* fix ec2

* Revert "fix ec2"

This reverts commit d961ddedc5c0cb76a0e07f3ec4c798bf2cf0bb41.

* add awslint excludes to ec2 module

* fix secretsmanager - add default RemovalPolicy

* update snapshot tests in aws-docdb because of secretsmanager removal policy change

* amplify

* elasticsearch and opensearch

* esc snapshots

* rds snapshots

Co-authored-by: AWS CDK Team 
Co-authored-by: Madeline Kusters 
Co-authored-by: Eli Polonsky 
---
 .../aws-amplify/test/integ.app.expected.json  |    4 +-
 .../integ.cluster-rotation.lit.expected.json  |    4 +-
 .../test/integ.cluster.expected.json          |   14 +-
 packages/@aws-cdk/aws-ec2/package.json        |    2 +
 .../ec2/integ.secret-json-field.expected.json |    4 +-
 .../test/fargate/integ.secret.expected.json   |    4 +-
 .../integ.elasticsearch-vpc.expected.json     |   18 +-
 ...elasticsearch.custom-kms-key.expected.json |   18 +-
 .../test/integ.elasticsearch.expected.json    |   18 +-
 ...sticsearch.unsignedbasicauth.expected.json |   22 +-
 ...eg.opensearch.custom-kms-key.expected.json |   18 +-
 .../test/integ.opensearch.expected.json       |   18 +-
 ...opensearch.unsignedbasicauth.expected.json |   22 +-
 packages/@aws-cdk/aws-panorama/.eslintrc.js   |    3 +
 packages/@aws-cdk/aws-panorama/.gitignore     |   19 +
 packages/@aws-cdk/aws-panorama/.npmignore     |   29 +
 packages/@aws-cdk/aws-panorama/LICENSE        |  201 ++
 packages/@aws-cdk/aws-panorama/NOTICE         |    2 +
 packages/@aws-cdk/aws-panorama/README.md      |   20 +
 packages/@aws-cdk/aws-panorama/jest.config.js |    2 +
 packages/@aws-cdk/aws-panorama/lib/index.ts   |    2 +
 packages/@aws-cdk/aws-panorama/package.json   |  105 +
 .../aws-panorama/test/aws-panorama.test.ts    |    6 +
 .../integ.cluster-rotation.lit.expected.json  |    4 +-
 ...ance-from-generated-password.expected.json |   22 +-
 .../integ.instance-s3-postgres.expected.json  |    4 +-
 .../test/integ.instance-s3.expected.json      |   18 +-
 .../aws-rds/test/integ.instance-s3.ts         |    2 +-
 .../test/integ.instance.lit.expected.json     |   54 +-
 .../aws-rds/test/integ.instance.lit.ts        |    2 +-
 .../aws-rds/test/integ.proxy.expected.json    |   16 +-
 .../@aws-cdk/aws-rekognition/.eslintrc.js     |    3 +
 packages/@aws-cdk/aws-rekognition/.gitignore  |   19 +
 packages/@aws-cdk/aws-rekognition/.npmignore  |   29 +
 packages/@aws-cdk/aws-rekognition/LICENSE     |  201 ++
 packages/@aws-cdk/aws-rekognition/NOTICE      |    2 +
 packages/@aws-cdk/aws-rekognition/README.md   |   20 +
 .../@aws-cdk/aws-rekognition/jest.config.js   |    2 +
 .../@aws-cdk/aws-rekognition/lib/index.ts     |    2 +
 .../@aws-cdk/aws-rekognition/package.json     |  105 +
 .../test/aws-rekognition.test.ts              |    6 +
 .../@aws-cdk/aws-secretsmanager/lib/secret.ts |    6 +-
 .../test/integ.hosted-rotation.expected.json  |    4 +-
 .../test/integ.lambda-rotation.expected.json  |    4 +-
 .../test/integ.replica.expected.json          |    4 +-
 .../integ.secret-name-parsed.expected.json    |   16 +-
 .../test/integ.secret.lit.expected.json       |   10 +-
 packages/@aws-cdk/aws-wisdom/.eslintrc.js     |    3 +
 packages/@aws-cdk/aws-wisdom/.gitignore       |   19 +
 packages/@aws-cdk/aws-wisdom/.npmignore       |   29 +
 packages/@aws-cdk/aws-wisdom/LICENSE          |  201 ++
 packages/@aws-cdk/aws-wisdom/NOTICE           |    2 +
 packages/@aws-cdk/aws-wisdom/README.md        |   20 +
 packages/@aws-cdk/aws-wisdom/jest.config.js   |    2 +
 packages/@aws-cdk/aws-wisdom/lib/index.ts     |    2 +
 packages/@aws-cdk/aws-wisdom/package.json     |  105 +
 .../aws-wisdom/test/aws-wisdom.test.ts        |    6 +
 packages/@aws-cdk/cfnspec/CHANGELOG.md        |  245 ++
 packages/@aws-cdk/cfnspec/cfn.version         |    2 +-
 ...0_CloudFormationResourceSpecification.json | 2703 ++++++++++++++++-
 .../cfn-lint/StatefulResources/000.json       |    3 +-
 .../cloudformation-include/package.json       |    6 +
 packages/aws-cdk-lib/package.json             |    3 +
 packages/decdk/package.json                   |    3 +
 packages/monocdk/package.json                 |    3 +
 packages/monocdk/rosetta/basic.ts-fixture     |   12 +
 .../monocdk/rosetta/client-vpn.ts-fixture     |    2 +-
 packages/monocdk/rosetta/conns.ts-fixture     |   26 -
 packages/monocdk/rosetta/default.ts-fixture   |   82 +-
 packages/monocdk/rosetta/function.ts-fixture  |   18 -
 packages/monocdk/rosetta/init.ts-fixture      |    3 +
 .../monocdk/rosetta/with-batch-job.ts-fixture |   38 -
 .../monocdk/rosetta/with-objects.ts-fixture   |   49 +
 yarn.lock                                     |    2 +-
 74 files changed, 4361 insertions(+), 338 deletions(-)
 create mode 100644 packages/@aws-cdk/aws-panorama/.eslintrc.js
 create mode 100644 packages/@aws-cdk/aws-panorama/.gitignore
 create mode 100644 packages/@aws-cdk/aws-panorama/.npmignore
 create mode 100644 packages/@aws-cdk/aws-panorama/LICENSE
 create mode 100644 packages/@aws-cdk/aws-panorama/NOTICE
 create mode 100644 packages/@aws-cdk/aws-panorama/README.md
 create mode 100644 packages/@aws-cdk/aws-panorama/jest.config.js
 create mode 100644 packages/@aws-cdk/aws-panorama/lib/index.ts
 create mode 100644 packages/@aws-cdk/aws-panorama/package.json
 create mode 100644 packages/@aws-cdk/aws-panorama/test/aws-panorama.test.ts
 create mode 100644 packages/@aws-cdk/aws-rekognition/.eslintrc.js
 create mode 100644 packages/@aws-cdk/aws-rekognition/.gitignore
 create mode 100644 packages/@aws-cdk/aws-rekognition/.npmignore
 create mode 100644 packages/@aws-cdk/aws-rekognition/LICENSE
 create mode 100644 packages/@aws-cdk/aws-rekognition/NOTICE
 create mode 100644 packages/@aws-cdk/aws-rekognition/README.md
 create mode 100644 packages/@aws-cdk/aws-rekognition/jest.config.js
 create mode 100644 packages/@aws-cdk/aws-rekognition/lib/index.ts
 create mode 100644 packages/@aws-cdk/aws-rekognition/package.json
 create mode 100644 packages/@aws-cdk/aws-rekognition/test/aws-rekognition.test.ts
 create mode 100644 packages/@aws-cdk/aws-wisdom/.eslintrc.js
 create mode 100644 packages/@aws-cdk/aws-wisdom/.gitignore
 create mode 100644 packages/@aws-cdk/aws-wisdom/.npmignore
 create mode 100644 packages/@aws-cdk/aws-wisdom/LICENSE
 create mode 100644 packages/@aws-cdk/aws-wisdom/NOTICE
 create mode 100644 packages/@aws-cdk/aws-wisdom/README.md
 create mode 100644 packages/@aws-cdk/aws-wisdom/jest.config.js
 create mode 100644 packages/@aws-cdk/aws-wisdom/lib/index.ts
 create mode 100644 packages/@aws-cdk/aws-wisdom/package.json
 create mode 100644 packages/@aws-cdk/aws-wisdom/test/aws-wisdom.test.ts
 create mode 100644 packages/monocdk/rosetta/basic.ts-fixture
 delete mode 100644 packages/monocdk/rosetta/conns.ts-fixture
 delete mode 100644 packages/monocdk/rosetta/function.ts-fixture
 create mode 100644 packages/monocdk/rosetta/init.ts-fixture
 delete mode 100644 packages/monocdk/rosetta/with-batch-job.ts-fixture
 create mode 100644 packages/monocdk/rosetta/with-objects.ts-fixture

diff --git a/packages/@aws-cdk/aws-amplify/test/integ.app.expected.json b/packages/@aws-cdk/aws-amplify/test/integ.app.expected.json
index d7ddd233378e1..bd8f69d9f66d8 100644
--- a/packages/@aws-cdk/aws-amplify/test/integ.app.expected.json
+++ b/packages/@aws-cdk/aws-amplify/test/integ.app.expected.json
@@ -24,7 +24,9 @@
           "GenerateStringKey": "password",
           "SecretStringTemplate": "{\"username\":\"aws\"}"
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "AppF1B96344": {
       "Type": "AWS::Amplify::App",
diff --git a/packages/@aws-cdk/aws-docdb/test/integ.cluster-rotation.lit.expected.json b/packages/@aws-cdk/aws-docdb/test/integ.cluster-rotation.lit.expected.json
index 6187414b9eb75..c063376359496 100644
--- a/packages/@aws-cdk/aws-docdb/test/integ.cluster-rotation.lit.expected.json
+++ b/packages/@aws-cdk/aws-docdb/test/integ.cluster-rotation.lit.expected.json
@@ -601,7 +601,9 @@
           "PasswordLength": 41,
           "SecretStringTemplate": "{\"username\":\"docdb\"}"
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "DatabaseSecretAttachmentE5D1B020": {
       "Type": "AWS::SecretsManager::SecretTargetAttachment",
diff --git a/packages/@aws-cdk/aws-docdb/test/integ.cluster.expected.json b/packages/@aws-cdk/aws-docdb/test/integ.cluster.expected.json
index e8737956c6440..1b661827dd1ec 100644
--- a/packages/@aws-cdk/aws-docdb/test/integ.cluster.expected.json
+++ b/packages/@aws-cdk/aws-docdb/test/integ.cluster.expected.json
@@ -95,15 +95,15 @@
     "VPCPublicSubnet1NATGatewayE0556630": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet1SubnetB4246D30"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet1EIP6AD938E8",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet1SubnetB4246D30"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -192,15 +192,15 @@
     "VPCPublicSubnet2NATGateway3C070193": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet2Subnet74179F39"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet2EIP4947BC00",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet2Subnet74179F39"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -506,4 +506,4 @@
       "DeletionPolicy": "Delete"
     }
   }
-}
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-ec2/package.json b/packages/@aws-cdk/aws-ec2/package.json
index 8eaa9d1e5d64a..a82b70b68ab52 100644
--- a/packages/@aws-cdk/aws-ec2/package.json
+++ b/packages/@aws-cdk/aws-ec2/package.json
@@ -117,6 +117,7 @@
   },
   "awslint": {
     "exclude": [
+      "resource-attribute:@aws-cdk/aws-ec2.NetworkAclEntry.networkAclEntryId",
       "resource-attribute:@aws-cdk/aws-ec2.ISecurityGroup.securityGroupVpcId",
       "no-unused-type:@aws-cdk/aws-ec2.ConnectionRule",
       "no-unused-type:@aws-cdk/aws-ec2.Protocol",
@@ -131,6 +132,7 @@
       "props-physical-name:@aws-cdk/aws-ec2.InterfaceVpcEndpointProps",
       "props-physical-name:@aws-cdk/aws-ec2.VpcEndpointServiceProps",
       "from-method:@aws-cdk/aws-ec2.Instance",
+      "from-method:@aws-cdk/aws-ec2.NetworkAclEntry",
       "from-method:@aws-cdk/aws-ec2.VpcEndpointService",
       "attribute-tag:@aws-cdk/aws-ec2.BastionHostLinux.instance",
       "attribute-tag:@aws-cdk/aws-ec2.Instance.instance",
diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.secret-json-field.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.secret-json-field.expected.json
index 6fe13e7abc27e..b14c1d7855e8c 100644
--- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.secret-json-field.expected.json
+++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.secret-json-field.expected.json
@@ -7,7 +7,9 @@
           "GenerateStringKey": "password",
           "SecretStringTemplate": "{\"username\":\"user\"}"
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "TaskDefTaskRole1EDB4A67": {
       "Type": "AWS::IAM::Role",
diff --git a/packages/@aws-cdk/aws-ecs/test/fargate/integ.secret.expected.json b/packages/@aws-cdk/aws-ecs/test/fargate/integ.secret.expected.json
index 2ef36fdc4d94a..f86ae24841bbf 100644
--- a/packages/@aws-cdk/aws-ecs/test/fargate/integ.secret.expected.json
+++ b/packages/@aws-cdk/aws-ecs/test/fargate/integ.secret.expected.json
@@ -7,7 +7,9 @@
           "GenerateStringKey": "password",
           "SecretStringTemplate": "{\"username\":\"user\"}"
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "TaskDefTaskRole1EDB4A67": {
       "Type": "AWS::IAM::Role",
diff --git a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch-vpc.expected.json b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch-vpc.expected.json
index fc046ff8065b2..1883358d70fe7 100644
--- a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch-vpc.expected.json
+++ b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch-vpc.expected.json
@@ -95,15 +95,15 @@
     "VpcPublicSubnet1NATGateway4D7517AA": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VpcPublicSubnet1EIPD7E02669",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -192,15 +192,15 @@
     "VpcPublicSubnet2NATGateway9182C01D": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VpcPublicSubnet2Subnet691E08A3"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VpcPublicSubnet2EIP3C605A87",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VpcPublicSubnet2Subnet691E08A3"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -289,15 +289,15 @@
     "VpcPublicSubnet3NATGateway7640CD1D": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VpcPublicSubnet3SubnetBE12F0B6"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VpcPublicSubnet3EIP3A666A23",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VpcPublicSubnet3SubnetBE12F0B6"
-        },
         "Tags": [
           {
             "Key": "Name",
diff --git a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.custom-kms-key.expected.json b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.custom-kms-key.expected.json
index 33066ad9091b6..8cbc696c94e14 100644
--- a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.custom-kms-key.expected.json
+++ b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.custom-kms-key.expected.json
@@ -359,7 +359,7 @@
       "Properties": {
         "Code": {
           "S3Bucket": {
-            "Ref": "AssetParametersf4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924S3BucketA716C641"
+            "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E"
           },
           "S3Key": {
             "Fn::Join": [
@@ -372,7 +372,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParametersf4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924S3VersionKey2B40A946"
+                          "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632"
                         }
                       ]
                     }
@@ -385,7 +385,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParametersf4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924S3VersionKey2B40A946"
+                          "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632"
                         }
                       ]
                     }
@@ -412,17 +412,17 @@
     }
   },
   "Parameters": {
-    "AssetParametersf4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924S3BucketA716C641": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": {
       "Type": "String",
-      "Description": "S3 bucket for asset \"f4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924\""
+      "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     },
-    "AssetParametersf4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924S3VersionKey2B40A946": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": {
       "Type": "String",
-      "Description": "S3 key for asset version \"f4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924\""
+      "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     },
-    "AssetParametersf4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924ArtifactHash2B031F57": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": {
       "Type": "String",
-      "Description": "Artifact hash for asset \"f4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924\""
+      "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     }
   }
 }
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.expected.json b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.expected.json
index e976e19e502a2..3734722a35ca7 100644
--- a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.expected.json
+++ b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.expected.json
@@ -296,7 +296,7 @@
       "Properties": {
         "Code": {
           "S3Bucket": {
-            "Ref": "AssetParametersf2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3ddS3Bucket292EB571"
+            "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E"
           },
           "S3Key": {
             "Fn::Join": [
@@ -309,7 +309,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParametersf2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3ddS3VersionKeyCE9A5F79"
+                          "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632"
                         }
                       ]
                     }
@@ -322,7 +322,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParametersf2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3ddS3VersionKeyCE9A5F79"
+                          "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632"
                         }
                       ]
                     }
@@ -608,17 +608,17 @@
     }
   },
   "Parameters": {
-    "AssetParametersf2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3ddS3Bucket292EB571": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": {
       "Type": "String",
-      "Description": "S3 bucket for asset \"f2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3dd\""
+      "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     },
-    "AssetParametersf2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3ddS3VersionKeyCE9A5F79": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": {
       "Type": "String",
-      "Description": "S3 key for asset version \"f2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3dd\""
+      "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     },
-    "AssetParametersf2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3ddArtifactHash86854188": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": {
       "Type": "String",
-      "Description": "Artifact hash for asset \"f2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3dd\""
+      "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     }
   }
 }
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.unsignedbasicauth.expected.json b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.unsignedbasicauth.expected.json
index 7ff999080fed6..d74ea6423a7bd 100644
--- a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.unsignedbasicauth.expected.json
+++ b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.unsignedbasicauth.expected.json
@@ -8,7 +8,9 @@
           "GenerateStringKey": "password",
           "SecretStringTemplate": "{\"username\":\"admin\"}"
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "Domain66AC69E0": {
       "Type": "AWS::Elasticsearch::Domain",
@@ -191,7 +193,7 @@
       "Properties": {
         "Code": {
           "S3Bucket": {
-            "Ref": "AssetParameters4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02cS3BucketD609D0D9"
+            "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E"
           },
           "S3Key": {
             "Fn::Join": [
@@ -204,7 +206,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParameters4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02cS3VersionKey77CF589B"
+                          "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632"
                         }
                       ]
                     }
@@ -217,7 +219,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParameters4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02cS3VersionKey77CF589B"
+                          "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632"
                         }
                       ]
                     }
@@ -243,17 +245,17 @@
     }
   },
   "Parameters": {
-    "AssetParameters4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02cS3BucketD609D0D9": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": {
       "Type": "String",
-      "Description": "S3 bucket for asset \"4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02c\""
+      "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     },
-    "AssetParameters4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02cS3VersionKey77CF589B": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": {
       "Type": "String",
-      "Description": "S3 key for asset version \"4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02c\""
+      "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     },
-    "AssetParameters4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02cArtifactHash86CFA15D": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": {
       "Type": "String",
-      "Description": "Artifact hash for asset \"4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02c\""
+      "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     }
   }
 }
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.custom-kms-key.expected.json b/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.custom-kms-key.expected.json
index 5a2791399497d..63a1cb0c236d5 100644
--- a/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.custom-kms-key.expected.json
+++ b/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.custom-kms-key.expected.json
@@ -232,7 +232,7 @@
       "Properties": {
         "Code": {
           "S3Bucket": {
-            "Ref": "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3BucketF2AC65B6"
+            "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E"
           },
           "S3Key": {
             "Fn::Join": [
@@ -245,7 +245,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3VersionKey8025D5E5"
+                          "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632"
                         }
                       ]
                     }
@@ -258,7 +258,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3VersionKey8025D5E5"
+                          "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632"
                         }
                       ]
                     }
@@ -285,17 +285,17 @@
     }
   },
   "Parameters": {
-    "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3BucketF2AC65B6": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": {
       "Type": "String",
-      "Description": "S3 bucket for asset \"5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7d\""
+      "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     },
-    "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3VersionKey8025D5E5": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": {
       "Type": "String",
-      "Description": "S3 key for asset version \"5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7d\""
+      "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     },
-    "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dArtifactHash30B93F3B": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": {
       "Type": "String",
-      "Description": "Artifact hash for asset \"5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7d\""
+      "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     }
   }
 }
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.expected.json b/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.expected.json
index f317e3a7eb835..da98a9b24ab35 100644
--- a/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.expected.json
+++ b/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.expected.json
@@ -296,7 +296,7 @@
       "Properties": {
         "Code": {
           "S3Bucket": {
-            "Ref": "AssetParameters0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85eS3BucketF2C16119"
+            "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E"
           },
           "S3Key": {
             "Fn::Join": [
@@ -309,7 +309,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParameters0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85eS3VersionKey60E022E2"
+                          "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632"
                         }
                       ]
                     }
@@ -322,7 +322,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParameters0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85eS3VersionKey60E022E2"
+                          "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632"
                         }
                       ]
                     }
@@ -608,17 +608,17 @@
     }
   },
   "Parameters": {
-    "AssetParameters0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85eS3BucketF2C16119": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": {
       "Type": "String",
-      "Description": "S3 bucket for asset \"0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85e\""
+      "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     },
-    "AssetParameters0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85eS3VersionKey60E022E2": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": {
       "Type": "String",
-      "Description": "S3 key for asset version \"0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85e\""
+      "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     },
-    "AssetParameters0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85eArtifactHash4E1710B0": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": {
       "Type": "String",
-      "Description": "Artifact hash for asset \"0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85e\""
+      "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     }
   }
 }
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.unsignedbasicauth.expected.json b/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.unsignedbasicauth.expected.json
index c2e8d28a0d35f..b1a9048f14dc1 100644
--- a/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.unsignedbasicauth.expected.json
+++ b/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.unsignedbasicauth.expected.json
@@ -8,7 +8,9 @@
           "GenerateStringKey": "password",
           "SecretStringTemplate": "{\"username\":\"admin\"}"
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "Domain66AC69E0": {
       "Type": "AWS::OpenSearchService::Domain",
@@ -191,7 +193,7 @@
       "Properties": {
         "Code": {
           "S3Bucket": {
-            "Ref": "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3BucketF2AC65B6"
+            "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E"
           },
           "S3Key": {
             "Fn::Join": [
@@ -204,7 +206,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3VersionKey8025D5E5"
+                          "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632"
                         }
                       ]
                     }
@@ -217,7 +219,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3VersionKey8025D5E5"
+                          "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632"
                         }
                       ]
                     }
@@ -243,17 +245,17 @@
     }
   },
   "Parameters": {
-    "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3BucketF2AC65B6": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": {
       "Type": "String",
-      "Description": "S3 bucket for asset \"5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7d\""
+      "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     },
-    "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3VersionKey8025D5E5": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": {
       "Type": "String",
-      "Description": "S3 key for asset version \"5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7d\""
+      "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     },
-    "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dArtifactHash30B93F3B": {
+    "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": {
       "Type": "String",
-      "Description": "Artifact hash for asset \"5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7d\""
+      "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\""
     }
   }
 }
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-panorama/.eslintrc.js b/packages/@aws-cdk/aws-panorama/.eslintrc.js
new file mode 100644
index 0000000000000..2658ee8727166
--- /dev/null
+++ b/packages/@aws-cdk/aws-panorama/.eslintrc.js
@@ -0,0 +1,3 @@
+const baseConfig = require('@aws-cdk/cdk-build-tools/config/eslintrc');
+baseConfig.parserOptions.project = __dirname + '/tsconfig.json';
+module.exports = baseConfig;
diff --git a/packages/@aws-cdk/aws-panorama/.gitignore b/packages/@aws-cdk/aws-panorama/.gitignore
new file mode 100644
index 0000000000000..62ebc95d75ce6
--- /dev/null
+++ b/packages/@aws-cdk/aws-panorama/.gitignore
@@ -0,0 +1,19 @@
+*.js
+*.js.map
+*.d.ts
+tsconfig.json
+node_modules
+*.generated.ts
+dist
+.jsii
+
+.LAST_BUILD
+.nyc_output
+coverage
+.nycrc
+.LAST_PACKAGE
+*.snk
+nyc.config.js
+!.eslintrc.js
+!jest.config.js
+junit.xml
diff --git a/packages/@aws-cdk/aws-panorama/.npmignore b/packages/@aws-cdk/aws-panorama/.npmignore
new file mode 100644
index 0000000000000..f931fede67c44
--- /dev/null
+++ b/packages/@aws-cdk/aws-panorama/.npmignore
@@ -0,0 +1,29 @@
+# Don't include original .ts files when doing `npm pack`
+*.ts
+!*.d.ts
+coverage
+.nyc_output
+*.tgz
+
+dist
+.LAST_PACKAGE
+.LAST_BUILD
+!*.js
+
+# Include .jsii
+!.jsii
+
+*.snk
+
+*.tsbuildinfo
+
+tsconfig.json
+
+.eslintrc.js
+jest.config.js
+
+# exclude cdk artifacts
+**/cdk.out
+junit.xml
+test/
+!*.lit.ts
diff --git a/packages/@aws-cdk/aws-panorama/LICENSE b/packages/@aws-cdk/aws-panorama/LICENSE
new file mode 100644
index 0000000000000..28e4bdcec77ec
--- /dev/null
+++ b/packages/@aws-cdk/aws-panorama/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/packages/@aws-cdk/aws-panorama/NOTICE b/packages/@aws-cdk/aws-panorama/NOTICE
new file mode 100644
index 0000000000000..5fc3826926b5b
--- /dev/null
+++ b/packages/@aws-cdk/aws-panorama/NOTICE
@@ -0,0 +1,2 @@
+AWS Cloud Development Kit (AWS CDK)
+Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
diff --git a/packages/@aws-cdk/aws-panorama/README.md b/packages/@aws-cdk/aws-panorama/README.md
new file mode 100644
index 0000000000000..334264b4ea581
--- /dev/null
+++ b/packages/@aws-cdk/aws-panorama/README.md
@@ -0,0 +1,20 @@
+# AWS::Panorama Construct Library
+
+
+---
+
+![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)
+
+> All classes with the `Cfn` prefix in this module ([CFN Resources]) are always stable and safe to use.
+>
+> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib
+
+---
+
+
+
+This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project.
+
+```ts
+import aws-panorama = require('@aws-cdk/aws-panorama');
+```
diff --git a/packages/@aws-cdk/aws-panorama/jest.config.js b/packages/@aws-cdk/aws-panorama/jest.config.js
new file mode 100644
index 0000000000000..3a2fd93a1228a
--- /dev/null
+++ b/packages/@aws-cdk/aws-panorama/jest.config.js
@@ -0,0 +1,2 @@
+const baseConfig = require('@aws-cdk/cdk-build-tools/config/jest.config');
+module.exports = baseConfig;
diff --git a/packages/@aws-cdk/aws-panorama/lib/index.ts b/packages/@aws-cdk/aws-panorama/lib/index.ts
new file mode 100644
index 0000000000000..1ef8b1378379a
--- /dev/null
+++ b/packages/@aws-cdk/aws-panorama/lib/index.ts
@@ -0,0 +1,2 @@
+// AWS::Panorama CloudFormation Resources:
+export * from './panorama.generated';
diff --git a/packages/@aws-cdk/aws-panorama/package.json b/packages/@aws-cdk/aws-panorama/package.json
new file mode 100644
index 0000000000000..08af6d8c5a82d
--- /dev/null
+++ b/packages/@aws-cdk/aws-panorama/package.json
@@ -0,0 +1,105 @@
+{
+  "name": "@aws-cdk/aws-panorama",
+  "version": "0.0.0",
+  "description": "The CDK Construct Library for AWS::Panorama",
+  "main": "lib/index.js",
+  "types": "lib/index.d.ts",
+  "jsii": {
+    "outdir": "dist",
+    "projectReferences": true,
+    "targets": {
+      "dotnet": {
+        "namespace": "Amazon.CDK.AWS.Panorama",
+        "packageId": "Amazon.CDK.AWS.Panorama",
+        "signAssembly": true,
+        "assemblyOriginatorKeyFile": "../../key.snk",
+        "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png"
+      },
+      "java": {
+        "package": "software.amazon.awscdk.services.panorama",
+        "maven": {
+          "groupId": "software.amazon.awscdk",
+          "artifactId": "panorama"
+        }
+      },
+      "python": {
+        "classifiers": [
+          "Framework :: AWS CDK",
+          "Framework :: AWS CDK :: 1"
+        ],
+        "distName": "aws-cdk.aws-panorama",
+        "module": "aws_cdk.aws_panorama"
+      }
+    }
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/aws/aws-cdk.git",
+    "directory": "packages/@aws-cdk/aws-panorama"
+  },
+  "homepage": "https://github.com/aws/aws-cdk",
+  "scripts": {
+    "build": "cdk-build",
+    "watch": "cdk-watch",
+    "lint": "cdk-lint",
+    "test": "cdk-test",
+    "integ": "cdk-integ",
+    "pkglint": "pkglint -f",
+    "package": "cdk-package",
+    "awslint": "cdk-awslint",
+    "cfn2ts": "cfn2ts",
+    "build+test": "yarn build && yarn test",
+    "build+test+package": "yarn build+test && yarn package",
+    "compat": "cdk-compat",
+    "gen": "cfn2ts",
+    "rosetta:extract": "yarn --silent jsii-rosetta extract",
+    "build+extract": "yarn build && yarn rosetta:extract",
+    "build+test+extract": "yarn build+test && yarn rosetta:extract"
+  },
+  "cdk-build": {
+    "cloudformation": "AWS::Panorama",
+    "jest": true,
+    "env": {
+      "AWSLINT_BASE_CONSTRUCT": "true"
+    }
+  },
+  "keywords": [
+    "aws",
+    "cdk",
+    "constructs",
+    "AWS::Panorama",
+    "aws-panorama"
+  ],
+  "author": {
+    "name": "Amazon Web Services",
+    "url": "https://aws.amazon.com",
+    "organization": true
+  },
+  "license": "Apache-2.0",
+  "devDependencies": {
+    "@aws-cdk/assertions": "0.0.0",
+    "@aws-cdk/cdk-build-tools": "0.0.0",
+    "@aws-cdk/cfn2ts": "0.0.0",
+    "@aws-cdk/pkglint": "0.0.0",
+    "@types/jest": "^26.0.22"
+  },
+  "dependencies": {
+    "@aws-cdk/core": "0.0.0",
+    "constructs": "^3.3.69"
+  },
+  "peerDependencies": {
+    "@aws-cdk/core": "0.0.0",
+    "constructs": "^3.3.69"
+  },
+  "engines": {
+    "node": ">= 10.13.0 <13 || >=13.7.0"
+  },
+  "stability": "experimental",
+  "maturity": "cfn-only",
+  "awscdkio": {
+    "announce": false
+  },
+  "publishConfig": {
+    "tag": "latest"
+  }
+}
diff --git a/packages/@aws-cdk/aws-panorama/test/aws-panorama.test.ts b/packages/@aws-cdk/aws-panorama/test/aws-panorama.test.ts
new file mode 100644
index 0000000000000..465c7bdea0693
--- /dev/null
+++ b/packages/@aws-cdk/aws-panorama/test/aws-panorama.test.ts
@@ -0,0 +1,6 @@
+import '@aws-cdk/assertions';
+import {} from '../lib';
+
+test('No tests are specified for this package', () => {
+  expect(true).toBe(true);
+});
diff --git a/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.expected.json b/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.expected.json
index 91b189023f587..19fbeabb515b1 100644
--- a/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.expected.json
+++ b/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.expected.json
@@ -599,7 +599,9 @@
           "PasswordLength": 30,
           "SecretStringTemplate": "{\"username\":\"admin\"}"
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "DatabaseSecretAttachmentE5D1B020": {
       "Type": "AWS::SecretsManager::SecretTargetAttachment",
diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance-from-generated-password.expected.json b/packages/@aws-cdk/aws-rds/test/integ.instance-from-generated-password.expected.json
index ca2ee08c781ad..219202e5fa587 100644
--- a/packages/@aws-cdk/aws-rds/test/integ.instance-from-generated-password.expected.json
+++ b/packages/@aws-cdk/aws-rds/test/integ.instance-from-generated-password.expected.json
@@ -95,15 +95,15 @@
     "VpcPublicSubnet1NATGateway4D7517AA": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VpcPublicSubnet1EIPD7E02669",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -192,15 +192,15 @@
     "VpcPublicSubnet2NATGateway9182C01D": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VpcPublicSubnet2Subnet691E08A3"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VpcPublicSubnet2EIP3C605A87",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VpcPublicSubnet2Subnet691E08A3"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -289,15 +289,15 @@
     "VpcPublicSubnet3NATGateway7640CD1D": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VpcPublicSubnet3SubnetBE12F0B6"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VpcPublicSubnet3EIP3A666A23",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VpcPublicSubnet3SubnetBE12F0B6"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -567,7 +567,9 @@
           "PasswordLength": 30,
           "SecretStringTemplate": "{\"username\":\"admin\"}"
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "InstanceSecretAttachment83BEE581": {
       "Type": "AWS::SecretsManager::SecretTargetAttachment",
diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.expected.json b/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.expected.json
index 2a55df00bab2c..c623afaf92464 100644
--- a/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.expected.json
+++ b/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.expected.json
@@ -512,7 +512,9 @@
           "PasswordLength": 30,
           "SecretStringTemplate": "{\"username\":\"postgres\"}"
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "InstanceSecretAttachment83BEE581": {
       "Type": "AWS::SecretsManager::SecretTargetAttachment",
diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance-s3.expected.json b/packages/@aws-cdk/aws-rds/test/integ.instance-s3.expected.json
index 2b144dedcc3aa..5b851784caef0 100644
--- a/packages/@aws-cdk/aws-rds/test/integ.instance-s3.expected.json
+++ b/packages/@aws-cdk/aws-rds/test/integ.instance-s3.expected.json
@@ -95,15 +95,15 @@
     "VPCPublicSubnet1NATGatewayE0556630": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet1SubnetB4246D30"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet1EIP6AD938E8",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet1SubnetB4246D30"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -192,15 +192,15 @@
     "VPCPublicSubnet2NATGateway3C070193": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet2Subnet74179F39"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet2EIP4947BC00",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet2Subnet74179F39"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -535,7 +535,9 @@
           "PasswordLength": 30,
           "SecretStringTemplate": "{\"username\":\"admin\"}"
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "DatabaseSecretAttachmentE5D1B020": {
       "Type": "AWS::SecretsManager::SecretTargetAttachment",
@@ -570,7 +572,7 @@
           "Ref": "DatabaseSubnetGroup7D60F180"
         },
         "Engine": "sqlserver-se",
-        "EngineVersion": "14.00.3192.2.v1",
+        "EngineVersion": "14.00",
         "LicenseModel": "license-included",
         "MasterUsername": {
           "Fn::Join": [
diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance-s3.ts b/packages/@aws-cdk/aws-rds/test/integ.instance-s3.ts
index 876ac2251e8fc..317e3c74abb57 100644
--- a/packages/@aws-cdk/aws-rds/test/integ.instance-s3.ts
+++ b/packages/@aws-cdk/aws-rds/test/integ.instance-s3.ts
@@ -12,7 +12,7 @@ const importBucket = new s3.Bucket(stack, 'ImportBucket', { removalPolicy: cdk.R
 const exportBucket = new s3.Bucket(stack, 'ExportBucket', { removalPolicy: cdk.RemovalPolicy.DESTROY });
 
 new DatabaseInstance(stack, 'Database', {
-  engine: DatabaseInstanceEngine.sqlServerSe({ version: SqlServerEngineVersion.VER_14_00_3192_2_V1 }),
+  engine: DatabaseInstanceEngine.sqlServerSe({ version: SqlServerEngineVersion.VER_14 }),
   vpc,
   licenseModel: LicenseModel.LICENSE_INCLUDED,
   s3ImportBuckets: [importBucket],
diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance.lit.expected.json b/packages/@aws-cdk/aws-rds/test/integ.instance.lit.expected.json
index 5214516968486..7b4328ccc3341 100644
--- a/packages/@aws-cdk/aws-rds/test/integ.instance.lit.expected.json
+++ b/packages/@aws-cdk/aws-rds/test/integ.instance.lit.expected.json
@@ -96,15 +96,15 @@
     "VPCPublicSubnet1NATGatewayE0556630": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet1SubnetB4246D30"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet1EIP6AD938E8",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet1SubnetB4246D30"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -193,15 +193,15 @@
     "VPCPublicSubnet2NATGateway3C070193": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "VPCPublicSubnet2Subnet74179F39"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "VPCPublicSubnet2EIP4947BC00",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "VPCPublicSubnet2Subnet74179F39"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -554,7 +554,9 @@
           "PasswordLength": 30,
           "SecretStringTemplate": "{\"username\":\"syscdk\"}"
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "InstanceSecretAttachment83BEE581": {
       "Type": "AWS::SecretsManager::SecretTargetAttachment",
@@ -1006,7 +1008,7 @@
         "Runtime": "nodejs14.x",
         "Code": {
           "S3Bucket": {
-            "Ref": "AssetParameters884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147S3BucketAE1150B3"
+            "Ref": "AssetParametersdd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9S3BucketE7DA8D4B"
           },
           "S3Key": {
             "Fn::Join": [
@@ -1019,7 +1021,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParameters884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147S3VersionKeyC76660C1"
+                          "Ref": "AssetParametersdd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9S3VersionKey534293E7"
                         }
                       ]
                     }
@@ -1032,7 +1034,7 @@
                       "Fn::Split": [
                         "||",
                         {
-                          "Ref": "AssetParameters884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147S3VersionKeyC76660C1"
+                          "Ref": "AssetParametersdd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9S3VersionKey534293E7"
                         }
                       ]
                     }
@@ -1118,27 +1120,13 @@
           ]
         },
         "Handler": "index.handler",
-        "Runtime": "nodejs10.x"
+        "Runtime": "nodejs12.x"
       },
       "DependsOn": [
         "FunctionServiceRole675BB04A"
       ]
     }
   },
-  "Parameters": {
-    "AssetParameters884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147S3BucketAE1150B3": {
-      "Type": "String",
-      "Description": "S3 bucket for asset \"884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147\""
-    },
-    "AssetParameters884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147S3VersionKeyC76660C1": {
-      "Type": "String",
-      "Description": "S3 key for asset version \"884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147\""
-    },
-    "AssetParameters884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147ArtifactHash717FC602": {
-      "Type": "String",
-      "Description": "Artifact hash for asset \"884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147\""
-    }
-  },
   "Mappings": {
     "InstanceRotationSingleUserSARMappingFEA0C86E": {
       "aws": {
@@ -1150,5 +1138,19 @@
         "semanticVersion": "1.1.37"
       }
     }
+  },
+  "Parameters": {
+    "AssetParametersdd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9S3BucketE7DA8D4B": {
+      "Type": "String",
+      "Description": "S3 bucket for asset \"dd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9\""
+    },
+    "AssetParametersdd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9S3VersionKey534293E7": {
+      "Type": "String",
+      "Description": "S3 key for asset version \"dd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9\""
+    },
+    "AssetParametersdd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9ArtifactHash3CB520C3": {
+      "Type": "String",
+      "Description": "Artifact hash for asset \"dd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9\""
+    }
   }
-}
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts b/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts
index eafe7a2953735..3e869950a0a46 100644
--- a/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts
+++ b/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts
@@ -85,7 +85,7 @@ class DatabaseInstanceStack extends cdk.Stack {
     const fn = new lambda.Function(this, 'Function', {
       code: lambda.Code.fromInline('exports.handler = (event) => console.log(event);'),
       handler: 'index.handler',
-      runtime: lambda.Runtime.NODEJS_10_X,
+      runtime: lambda.Runtime.NODEJS_12_X,
     });
 
     const availabilityRule = instance.onEvent('Availability', { target: new targets.LambdaFunction(fn) });
diff --git a/packages/@aws-cdk/aws-rds/test/integ.proxy.expected.json b/packages/@aws-cdk/aws-rds/test/integ.proxy.expected.json
index a18c5f5843512..8ec23ce0fe7db 100644
--- a/packages/@aws-cdk/aws-rds/test/integ.proxy.expected.json
+++ b/packages/@aws-cdk/aws-rds/test/integ.proxy.expected.json
@@ -95,15 +95,15 @@
     "vpcPublicSubnet1NATGateway9C16659E": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "vpcPublicSubnet1Subnet2E65531E"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "vpcPublicSubnet1EIPDA49DCBE",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "vpcPublicSubnet1Subnet2E65531E"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -192,15 +192,15 @@
     "vpcPublicSubnet2NATGateway9B8AE11A": {
       "Type": "AWS::EC2::NatGateway",
       "Properties": {
+        "SubnetId": {
+          "Ref": "vpcPublicSubnet2Subnet009B674F"
+        },
         "AllocationId": {
           "Fn::GetAtt": [
             "vpcPublicSubnet2EIP9B3743B1",
             "AllocationId"
           ]
         },
-        "SubnetId": {
-          "Ref": "vpcPublicSubnet2Subnet009B674F"
-        },
         "Tags": [
           {
             "Key": "Name",
@@ -436,7 +436,9 @@
           "PasswordLength": 30,
           "SecretStringTemplate": "{\"username\":\"master\"}"
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "dbInstanceSecretAttachment88CFBDAE": {
       "Type": "AWS::SecretsManager::SecretTargetAttachment",
diff --git a/packages/@aws-cdk/aws-rekognition/.eslintrc.js b/packages/@aws-cdk/aws-rekognition/.eslintrc.js
new file mode 100644
index 0000000000000..2658ee8727166
--- /dev/null
+++ b/packages/@aws-cdk/aws-rekognition/.eslintrc.js
@@ -0,0 +1,3 @@
+const baseConfig = require('@aws-cdk/cdk-build-tools/config/eslintrc');
+baseConfig.parserOptions.project = __dirname + '/tsconfig.json';
+module.exports = baseConfig;
diff --git a/packages/@aws-cdk/aws-rekognition/.gitignore b/packages/@aws-cdk/aws-rekognition/.gitignore
new file mode 100644
index 0000000000000..62ebc95d75ce6
--- /dev/null
+++ b/packages/@aws-cdk/aws-rekognition/.gitignore
@@ -0,0 +1,19 @@
+*.js
+*.js.map
+*.d.ts
+tsconfig.json
+node_modules
+*.generated.ts
+dist
+.jsii
+
+.LAST_BUILD
+.nyc_output
+coverage
+.nycrc
+.LAST_PACKAGE
+*.snk
+nyc.config.js
+!.eslintrc.js
+!jest.config.js
+junit.xml
diff --git a/packages/@aws-cdk/aws-rekognition/.npmignore b/packages/@aws-cdk/aws-rekognition/.npmignore
new file mode 100644
index 0000000000000..f931fede67c44
--- /dev/null
+++ b/packages/@aws-cdk/aws-rekognition/.npmignore
@@ -0,0 +1,29 @@
+# Don't include original .ts files when doing `npm pack`
+*.ts
+!*.d.ts
+coverage
+.nyc_output
+*.tgz
+
+dist
+.LAST_PACKAGE
+.LAST_BUILD
+!*.js
+
+# Include .jsii
+!.jsii
+
+*.snk
+
+*.tsbuildinfo
+
+tsconfig.json
+
+.eslintrc.js
+jest.config.js
+
+# exclude cdk artifacts
+**/cdk.out
+junit.xml
+test/
+!*.lit.ts
diff --git a/packages/@aws-cdk/aws-rekognition/LICENSE b/packages/@aws-cdk/aws-rekognition/LICENSE
new file mode 100644
index 0000000000000..28e4bdcec77ec
--- /dev/null
+++ b/packages/@aws-cdk/aws-rekognition/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/packages/@aws-cdk/aws-rekognition/NOTICE b/packages/@aws-cdk/aws-rekognition/NOTICE
new file mode 100644
index 0000000000000..5fc3826926b5b
--- /dev/null
+++ b/packages/@aws-cdk/aws-rekognition/NOTICE
@@ -0,0 +1,2 @@
+AWS Cloud Development Kit (AWS CDK)
+Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
diff --git a/packages/@aws-cdk/aws-rekognition/README.md b/packages/@aws-cdk/aws-rekognition/README.md
new file mode 100644
index 0000000000000..9e158afddf5de
--- /dev/null
+++ b/packages/@aws-cdk/aws-rekognition/README.md
@@ -0,0 +1,20 @@
+# AWS::Rekognition Construct Library
+
+
+---
+
+![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)
+
+> All classes with the `Cfn` prefix in this module ([CFN Resources]) are always stable and safe to use.
+>
+> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib
+
+---
+
+
+
+This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project.
+
+```ts
+import aws-rekognition = require('@aws-cdk/aws-rekognition');
+```
diff --git a/packages/@aws-cdk/aws-rekognition/jest.config.js b/packages/@aws-cdk/aws-rekognition/jest.config.js
new file mode 100644
index 0000000000000..3a2fd93a1228a
--- /dev/null
+++ b/packages/@aws-cdk/aws-rekognition/jest.config.js
@@ -0,0 +1,2 @@
+const baseConfig = require('@aws-cdk/cdk-build-tools/config/jest.config');
+module.exports = baseConfig;
diff --git a/packages/@aws-cdk/aws-rekognition/lib/index.ts b/packages/@aws-cdk/aws-rekognition/lib/index.ts
new file mode 100644
index 0000000000000..a0fee8d99d632
--- /dev/null
+++ b/packages/@aws-cdk/aws-rekognition/lib/index.ts
@@ -0,0 +1,2 @@
+// AWS::Rekognition CloudFormation Resources:
+export * from './rekognition.generated';
diff --git a/packages/@aws-cdk/aws-rekognition/package.json b/packages/@aws-cdk/aws-rekognition/package.json
new file mode 100644
index 0000000000000..0639bc97ec905
--- /dev/null
+++ b/packages/@aws-cdk/aws-rekognition/package.json
@@ -0,0 +1,105 @@
+{
+  "name": "@aws-cdk/aws-rekognition",
+  "version": "0.0.0",
+  "description": "The CDK Construct Library for AWS::Rekognition",
+  "main": "lib/index.js",
+  "types": "lib/index.d.ts",
+  "jsii": {
+    "outdir": "dist",
+    "projectReferences": true,
+    "targets": {
+      "dotnet": {
+        "namespace": "Amazon.CDK.AWS.Rekognition",
+        "packageId": "Amazon.CDK.AWS.Rekognition",
+        "signAssembly": true,
+        "assemblyOriginatorKeyFile": "../../key.snk",
+        "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png"
+      },
+      "java": {
+        "package": "software.amazon.awscdk.services.rekognition",
+        "maven": {
+          "groupId": "software.amazon.awscdk",
+          "artifactId": "rekognition"
+        }
+      },
+      "python": {
+        "classifiers": [
+          "Framework :: AWS CDK",
+          "Framework :: AWS CDK :: 1"
+        ],
+        "distName": "aws-cdk.aws-rekognition",
+        "module": "aws_cdk.aws_rekognition"
+      }
+    }
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/aws/aws-cdk.git",
+    "directory": "packages/@aws-cdk/aws-rekognition"
+  },
+  "homepage": "https://github.com/aws/aws-cdk",
+  "scripts": {
+    "build": "cdk-build",
+    "watch": "cdk-watch",
+    "lint": "cdk-lint",
+    "test": "cdk-test",
+    "integ": "cdk-integ",
+    "pkglint": "pkglint -f",
+    "package": "cdk-package",
+    "awslint": "cdk-awslint",
+    "cfn2ts": "cfn2ts",
+    "build+test": "yarn build && yarn test",
+    "build+test+package": "yarn build+test && yarn package",
+    "compat": "cdk-compat",
+    "gen": "cfn2ts",
+    "rosetta:extract": "yarn --silent jsii-rosetta extract",
+    "build+extract": "yarn build && yarn rosetta:extract",
+    "build+test+extract": "yarn build+test && yarn rosetta:extract"
+  },
+  "cdk-build": {
+    "cloudformation": "AWS::Rekognition",
+    "jest": true,
+    "env": {
+      "AWSLINT_BASE_CONSTRUCT": "true"
+    }
+  },
+  "keywords": [
+    "aws",
+    "cdk",
+    "constructs",
+    "AWS::Rekognition",
+    "aws-rekognition"
+  ],
+  "author": {
+    "name": "Amazon Web Services",
+    "url": "https://aws.amazon.com",
+    "organization": true
+  },
+  "license": "Apache-2.0",
+  "devDependencies": {
+    "@aws-cdk/assertions": "0.0.0",
+    "@aws-cdk/cdk-build-tools": "0.0.0",
+    "@aws-cdk/cfn2ts": "0.0.0",
+    "@aws-cdk/pkglint": "0.0.0",
+    "@types/jest": "^26.0.22"
+  },
+  "dependencies": {
+    "@aws-cdk/core": "0.0.0",
+    "constructs": "^3.3.69"
+  },
+  "peerDependencies": {
+    "@aws-cdk/core": "0.0.0",
+    "constructs": "^3.3.69"
+  },
+  "engines": {
+    "node": ">= 10.13.0 <13 || >=13.7.0"
+  },
+  "stability": "experimental",
+  "maturity": "cfn-only",
+  "awscdkio": {
+    "announce": false
+  },
+  "publishConfig": {
+    "tag": "latest"
+  }
+}
diff --git a/packages/@aws-cdk/aws-rekognition/test/aws-rekognition.test.ts b/packages/@aws-cdk/aws-rekognition/test/aws-rekognition.test.ts
new file mode 100644
index 0000000000000..465c7bdea0693
--- /dev/null
+++ b/packages/@aws-cdk/aws-rekognition/test/aws-rekognition.test.ts
@@ -0,0 +1,6 @@
+import '@aws-cdk/assertions';
+import {} from '../lib';
+
+test('No tests are specified for this package', () => {
+  expect(true).toBe(true);
+});
diff --git a/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts b/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts
index 119b02ccc507d..70144db7d2dbd 100644
--- a/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts
+++ b/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts
@@ -467,9 +467,9 @@ export class Secret extends SecretBase {
       replicaRegions: Lazy.any({ produce: () => this.replicaRegions }, { omitEmptyArray: true }),
     });
 
-    if (props.removalPolicy) {
-      resource.applyRemovalPolicy(props.removalPolicy);
-    }
+    resource.applyRemovalPolicy(props.removalPolicy, {
+      default: RemovalPolicy.DESTROY,
+    });
 
     this.secretArn = this.getResourceArnAttribute(resource.ref, {
       service: 'secretsmanager',
diff --git a/packages/@aws-cdk/aws-secretsmanager/test/integ.hosted-rotation.expected.json b/packages/@aws-cdk/aws-secretsmanager/test/integ.hosted-rotation.expected.json
index be2f63be0aa79..19c9a9d4c7f1e 100644
--- a/packages/@aws-cdk/aws-secretsmanager/test/integ.hosted-rotation.expected.json
+++ b/packages/@aws-cdk/aws-secretsmanager/test/integ.hosted-rotation.expected.json
@@ -5,7 +5,9 @@
       "Type": "AWS::SecretsManager::Secret",
       "Properties": {
         "GenerateSecretString": {}
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "SecretSchedule18F2CB66": {
       "Type": "AWS::SecretsManager::RotationSchedule",
diff --git a/packages/@aws-cdk/aws-secretsmanager/test/integ.lambda-rotation.expected.json b/packages/@aws-cdk/aws-secretsmanager/test/integ.lambda-rotation.expected.json
index 12ea99df10a85..f1d540cbd42a7 100644
--- a/packages/@aws-cdk/aws-secretsmanager/test/integ.lambda-rotation.expected.json
+++ b/packages/@aws-cdk/aws-secretsmanager/test/integ.lambda-rotation.expected.json
@@ -165,7 +165,9 @@
             "Arn"
           ]
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "SecretSchedule18F2CB66": {
       "Type": "AWS::SecretsManager::RotationSchedule",
diff --git a/packages/@aws-cdk/aws-secretsmanager/test/integ.replica.expected.json b/packages/@aws-cdk/aws-secretsmanager/test/integ.replica.expected.json
index 99fd65c02e2b4..6483de751a884 100644
--- a/packages/@aws-cdk/aws-secretsmanager/test/integ.replica.expected.json
+++ b/packages/@aws-cdk/aws-secretsmanager/test/integ.replica.expected.json
@@ -9,7 +9,9 @@
             "Region": "eu-central-1"
           }
         ]
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     }
   }
 }
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-secretsmanager/test/integ.secret-name-parsed.expected.json b/packages/@aws-cdk/aws-secretsmanager/test/integ.secret-name-parsed.expected.json
index b1b91a239d649..01e9e10d4eed9 100644
--- a/packages/@aws-cdk/aws-secretsmanager/test/integ.secret-name-parsed.expected.json
+++ b/packages/@aws-cdk/aws-secretsmanager/test/integ.secret-name-parsed.expected.json
@@ -4,27 +4,35 @@
       "Type": "AWS::SecretsManager::Secret",
       "Properties": {
         "GenerateSecretString": {}
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "NamedSecret7CD5422D": {
       "Type": "AWS::SecretsManager::Secret",
       "Properties": {
         "GenerateSecretString": {},
         "Name": "namedSecret"
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "NamedSecretWithHyphen6DC9716A": {
       "Type": "AWS::SecretsManager::Secret",
       "Properties": {
         "GenerateSecretString": {},
         "Name": "named-secret-1"
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "AReallyLongLogicalIThatWillBeTrimmedBeforeItsUsedInTheName83476586": {
       "Type": "AWS::SecretsManager::Secret",
       "Properties": {
         "GenerateSecretString": {}
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "CustomIntegVerificationSecretNameMatchesCustomResourceProviderRole4A6F8B2A": {
       "Type": "AWS::IAM::Role",
diff --git a/packages/@aws-cdk/aws-secretsmanager/test/integ.secret.lit.expected.json b/packages/@aws-cdk/aws-secretsmanager/test/integ.secret.lit.expected.json
index 5411df31be1ba..7a69272a9550f 100644
--- a/packages/@aws-cdk/aws-secretsmanager/test/integ.secret.lit.expected.json
+++ b/packages/@aws-cdk/aws-secretsmanager/test/integ.secret.lit.expected.json
@@ -62,7 +62,9 @@
       "Type": "AWS::SecretsManager::Secret",
       "Properties": {
         "GenerateSecretString": {}
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "User00B015A1": {
       "Type": "AWS::IAM::User",
@@ -90,7 +92,9 @@
           "GenerateStringKey": "password",
           "SecretStringTemplate": "{\"username\":\"user\"}"
         }
-      }
+      },
+      "UpdateReplacePolicy": "Delete",
+      "DeletionPolicy": "Delete"
     },
     "OtherUser6093621C": {
       "Type": "AWS::IAM::User",
@@ -124,4 +128,4 @@
       }
     }
   }
-}
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk/aws-wisdom/.eslintrc.js b/packages/@aws-cdk/aws-wisdom/.eslintrc.js
new file mode 100644
index 0000000000000..2658ee8727166
--- /dev/null
+++ b/packages/@aws-cdk/aws-wisdom/.eslintrc.js
@@ -0,0 +1,3 @@
+const baseConfig = require('@aws-cdk/cdk-build-tools/config/eslintrc');
+baseConfig.parserOptions.project = __dirname + '/tsconfig.json';
+module.exports = baseConfig;
diff --git a/packages/@aws-cdk/aws-wisdom/.gitignore b/packages/@aws-cdk/aws-wisdom/.gitignore
new file mode 100644
index 0000000000000..62ebc95d75ce6
--- /dev/null
+++ b/packages/@aws-cdk/aws-wisdom/.gitignore
@@ -0,0 +1,19 @@
+*.js
+*.js.map
+*.d.ts
+tsconfig.json
+node_modules
+*.generated.ts
+dist
+.jsii
+
+.LAST_BUILD
+.nyc_output
+coverage
+.nycrc
+.LAST_PACKAGE
+*.snk
+nyc.config.js
+!.eslintrc.js
+!jest.config.js
+junit.xml
diff --git a/packages/@aws-cdk/aws-wisdom/.npmignore b/packages/@aws-cdk/aws-wisdom/.npmignore
new file mode 100644
index 0000000000000..f931fede67c44
--- /dev/null
+++ b/packages/@aws-cdk/aws-wisdom/.npmignore
@@ -0,0 +1,29 @@
+# Don't include original .ts files when doing `npm pack`
+*.ts
+!*.d.ts
+coverage
+.nyc_output
+*.tgz
+
+dist
+.LAST_PACKAGE
+.LAST_BUILD
+!*.js
+
+# Include .jsii
+!.jsii
+
+*.snk
+
+*.tsbuildinfo
+
+tsconfig.json
+
+.eslintrc.js
+jest.config.js
+
+# exclude cdk artifacts
+**/cdk.out
+junit.xml
+test/
+!*.lit.ts
diff --git a/packages/@aws-cdk/aws-wisdom/LICENSE b/packages/@aws-cdk/aws-wisdom/LICENSE
new file mode 100644
index 0000000000000..28e4bdcec77ec
--- /dev/null
+++ b/packages/@aws-cdk/aws-wisdom/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/packages/@aws-cdk/aws-wisdom/NOTICE b/packages/@aws-cdk/aws-wisdom/NOTICE
new file mode 100644
index 0000000000000..5fc3826926b5b
--- /dev/null
+++ b/packages/@aws-cdk/aws-wisdom/NOTICE
@@ -0,0 +1,2 @@
+AWS Cloud Development Kit (AWS CDK)
+Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
diff --git a/packages/@aws-cdk/aws-wisdom/README.md b/packages/@aws-cdk/aws-wisdom/README.md
new file mode 100644
index 0000000000000..d942b3358d363
--- /dev/null
+++ b/packages/@aws-cdk/aws-wisdom/README.md
@@ -0,0 +1,20 @@
+# AWS::Wisdom Construct Library
+
+
+---
+
+![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)
+
+> All classes with the `Cfn` prefix in this module ([CFN Resources]) are always stable and safe to use.
+>
+> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib
+
+---
+
+
+
+This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project.
+
+```ts
+import aws-wisdom = require('@aws-cdk/aws-wisdom');
+```
diff --git a/packages/@aws-cdk/aws-wisdom/jest.config.js b/packages/@aws-cdk/aws-wisdom/jest.config.js
new file mode 100644
index 0000000000000..3a2fd93a1228a
--- /dev/null
+++ b/packages/@aws-cdk/aws-wisdom/jest.config.js
@@ -0,0 +1,2 @@
+const baseConfig = require('@aws-cdk/cdk-build-tools/config/jest.config');
+module.exports = baseConfig;
diff --git a/packages/@aws-cdk/aws-wisdom/lib/index.ts b/packages/@aws-cdk/aws-wisdom/lib/index.ts
new file mode 100644
index 0000000000000..368aee100e245
--- /dev/null
+++ b/packages/@aws-cdk/aws-wisdom/lib/index.ts
@@ -0,0 +1,2 @@
+// AWS::Wisdom CloudFormation Resources:
+export * from './wisdom.generated';
diff --git a/packages/@aws-cdk/aws-wisdom/package.json b/packages/@aws-cdk/aws-wisdom/package.json
new file mode 100644
index 0000000000000..44465292a4350
--- /dev/null
+++ b/packages/@aws-cdk/aws-wisdom/package.json
@@ -0,0 +1,105 @@
+{
+  "name": "@aws-cdk/aws-wisdom",
+  "version": "0.0.0",
+  "description": "The CDK Construct Library for AWS::Wisdom",
+  "main": "lib/index.js",
+  "types": "lib/index.d.ts",
+  "jsii": {
+    "outdir": "dist",
+    "projectReferences": true,
+    "targets": {
+      "dotnet": {
+        "namespace": "Amazon.CDK.AWS.Wisdom",
+        "packageId": "Amazon.CDK.AWS.Wisdom",
+        "signAssembly": true,
+        "assemblyOriginatorKeyFile": "../../key.snk",
+        "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png"
+      },
+      "java": {
+        "package": "software.amazon.awscdk.services.wisdom",
+        "maven": {
+          "groupId": "software.amazon.awscdk",
+          "artifactId": "wisdom"
+        }
+      },
+      "python": {
+        "classifiers": [
+          "Framework :: AWS CDK",
+          "Framework :: AWS CDK :: 1"
+        ],
+        "distName": "aws-cdk.aws-wisdom",
+        "module": "aws_cdk.aws_wisdom"
+      }
+    }
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/aws/aws-cdk.git",
+    "directory": "packages/@aws-cdk/aws-wisdom"
+  },
+  "homepage": "https://github.com/aws/aws-cdk",
+  "scripts": {
+    "build": "cdk-build",
+    "watch": "cdk-watch",
+    "lint": "cdk-lint",
+    "test": "cdk-test",
+    "integ": "cdk-integ",
+    "pkglint": "pkglint -f",
+    "package": "cdk-package",
+    "awslint": "cdk-awslint",
+    "cfn2ts": "cfn2ts",
+    "build+test": "yarn build && yarn test",
+    "build+test+package": "yarn build+test && yarn package",
+    "compat": "cdk-compat",
+    "gen": "cfn2ts",
+    "rosetta:extract": "yarn --silent jsii-rosetta extract",
+    "build+extract": "yarn build && yarn rosetta:extract",
+    "build+test+extract": "yarn build+test && yarn rosetta:extract"
+  },
+  "cdk-build": {
+    "cloudformation": "AWS::Wisdom",
+    "jest": true,
+    "env": {
+      "AWSLINT_BASE_CONSTRUCT": "true"
+    }
+  },
+  "keywords": [
+    "aws",
+    "cdk",
+    "constructs",
+    "AWS::Wisdom",
+    "aws-wisdom"
+  ],
+  "author": {
+    "name": "Amazon Web Services",
+    "url": "https://aws.amazon.com",
+    "organization": true
+  },
+  "license": "Apache-2.0",
+  "devDependencies": {
+    "@aws-cdk/assertions": "0.0.0",
+    "@aws-cdk/cdk-build-tools": "0.0.0",
+    "@aws-cdk/cfn2ts": "0.0.0",
+    "@aws-cdk/pkglint": "0.0.0",
+    "@types/jest": "^26.0.22"
+  },
+  "dependencies": {
+    "@aws-cdk/core": "0.0.0",
+    "constructs": "^3.3.69"
+  },
+  "peerDependencies": {
+    "@aws-cdk/core": "0.0.0",
+    "constructs": "^3.3.69"
+  },
+  "engines": {
+    "node": ">= 10.13.0 <13 || >=13.7.0"
+  },
+  "stability": "experimental",
+  "maturity": "cfn-only",
+  "awscdkio": {
+    "announce": false
+  },
+  "publishConfig": {
+    "tag": "latest"
+  }
+}
diff --git a/packages/@aws-cdk/aws-wisdom/test/aws-wisdom.test.ts b/packages/@aws-cdk/aws-wisdom/test/aws-wisdom.test.ts
new file mode 100644
index 0000000000000..465c7bdea0693
--- /dev/null
+++ b/packages/@aws-cdk/aws-wisdom/test/aws-wisdom.test.ts
@@ -0,0 +1,6 @@
+import '@aws-cdk/assertions';
+import {} from '../lib';
+
+test('No tests are specified for this package', () => {
+  expect(true).toBe(true);
+});
diff --git a/packages/@aws-cdk/cfnspec/CHANGELOG.md b/packages/@aws-cdk/cfnspec/CHANGELOG.md
index 19c814c818182..51d94432f3293 100644
--- a/packages/@aws-cdk/cfnspec/CHANGELOG.md
+++ b/packages/@aws-cdk/cfnspec/CHANGELOG.md
@@ -1,3 +1,248 @@
+# CloudFormation Resource Specification v46.0.0
+
+## New Resource Types
+
+* AWS::Connect::HoursOfOperation
+* AWS::Connect::User
+* AWS::Connect::UserHierarchyGroup
+* AWS::EC2::CapacityReservationFleet
+* AWS::IoT::JobTemplate
+* AWS::Lightsail::Database
+* AWS::Lightsail::StaticIp
+* AWS::Panorama::ApplicationInstance
+* AWS::Panorama::Package
+* AWS::Panorama::PackageVersion
+* AWS::Rekognition::Project
+* AWS::Route53Resolver::ResolverConfig
+* AWS::Wisdom::Assistant
+* AWS::Wisdom::AssistantAssociation
+* AWS::Wisdom::KnowledgeBase
+
+## Attribute Changes
+
+* AWS::ApiGateway::Authorizer AuthorizerId (__added__)
+* AWS::AutoScaling::LifecycleHook Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html
+* AWS::EC2::NetworkAcl Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkacl.html
+* AWS::EC2::NetworkAcl Id (__added__)
+* AWS::EC2::NetworkAclEntry Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html
+* AWS::EC2::NetworkAclEntry Id (__added__)
+* AWS::EC2::RouteTable Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html
+* AWS::EC2::RouteTable RouteTableId (__added__)
+* AWS::Lightsail::Instance KeyPairName (__deleted__)
+* AWS::Lightsail::Instance UserData (__deleted__)
+* AWS::Route53Resolver::ResolverRule TargetIps.PrimitiveType (__deleted__)
+* AWS::Route53Resolver::ResolverRule TargetIps.DuplicatesAllowed (__added__)
+* AWS::Route53Resolver::ResolverRule TargetIps.ItemType (__added__)
+* AWS::Route53Resolver::ResolverRule TargetIps.Type (__added__)
+* AWS::StepFunctions::Activity Arn (__added__)
+
+## Property Changes
+
+* AWS::ApiGateway::Authorizer Name.Required (__changed__)
+  * Old: false
+  * New: true
+* AWS::ApiGateway::VpcLink Tags (__added__)
+* AWS::AutoScaling::AutoScalingGroup DesiredCapacityType (__added__)
+* AWS::AutoScaling::LifecycleHook AutoScalingGroupName.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-autoscalinggroupname
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-autoscalinggroupname
+* AWS::AutoScaling::LifecycleHook DefaultResult.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-defaultresult
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-defaultresult
+* AWS::AutoScaling::LifecycleHook HeartbeatTimeout.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-heartbeattimeout
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-heartbeattimeout
+* AWS::AutoScaling::LifecycleHook LifecycleHookName.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-autoscaling-lifecyclehook-lifecyclehookname
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-lifecyclehookname
+* AWS::AutoScaling::LifecycleHook LifecycleTransition.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-lifecycletransition
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-lifecycletransition
+* AWS::AutoScaling::LifecycleHook NotificationMetadata.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-notificationmetadata
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-notificationmetadata
+* AWS::AutoScaling::LifecycleHook NotificationTargetARN.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-notificationtargetarn
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-notificationtargetarn
+* AWS::AutoScaling::LifecycleHook RoleARN.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-rolearn
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-rolearn
+* AWS::Batch::ComputeEnvironment UnmanagedvCpus (__added__)
+* AWS::Batch::JobDefinition SchedulingPriority (__added__)
+* AWS::Batch::JobQueue SchedulingPolicyArn (__added__)
+* AWS::Budgets::BudgetsAction Subscribers.Required (__changed__)
+  * Old: false
+  * New: true
+* AWS::Cassandra::Table DefaultTimeToLive (__added__)
+* AWS::CodeStarNotifications::NotificationRule CreatedBy (__added__)
+* AWS::CodeStarNotifications::NotificationRule EventTypeId (__added__)
+* AWS::CodeStarNotifications::NotificationRule TargetAddress (__added__)
+* AWS::EC2::NetworkAcl Tags.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html#cfn-ec2-networkacl-tags
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkacl.html#cfn-ec2-networkacl-tags
+* AWS::EC2::NetworkAcl VpcId.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html#cfn-ec2-networkacl-vpcid
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkacl.html#cfn-ec2-networkacl-vpcid
+* AWS::EC2::NetworkAclEntry CidrBlock.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-cidrblock
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-cidrblock
+* AWS::EC2::NetworkAclEntry Egress.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-egress
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-egress
+* AWS::EC2::NetworkAclEntry Icmp.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-icmp
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-icmp
+* AWS::EC2::NetworkAclEntry Ipv6CidrBlock.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-ipv6cidrblock
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-ipv6cidrblock
+* AWS::EC2::NetworkAclEntry NetworkAclId.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-networkaclid
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-networkaclid
+* AWS::EC2::NetworkAclEntry PortRange.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-portrange
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-portrange
+* AWS::EC2::NetworkAclEntry Protocol.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-protocol
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-protocol
+* AWS::EC2::NetworkAclEntry RuleAction.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-ruleaction
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-ruleaction
+* AWS::EC2::NetworkAclEntry RuleNumber.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-rulenumber
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-rulenumber
+* AWS::EC2::RouteTable Tags.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html#cfn-ec2-routetable-tags
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html#cfn-ec2-routetable-tags
+* AWS::EC2::RouteTable VpcId.Documentation (__changed__)
+  * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html#cfn-ec2-routetable-vpcid
+  * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html#cfn-ec2-routetable-vpcid
+* AWS::ECS::TaskDefinition RuntimePlatform (__added__)
+* AWS::FMS::Policy ResourcesCleanUp (__added__)
+* AWS::Glue::Registry Tags.UpdateType (__changed__)
+  * Old: Immutable
+  * New: Mutable
+* AWS::Glue::Schema Tags.UpdateType (__changed__)
+  * Old: Immutable
+  * New: Mutable
+* AWS::ImageBuilder::InfrastructureConfiguration InstanceMetadataOptions (__added__)
+* AWS::Lightsail::Instance KeyPairName (__added__)
+* AWS::Lightsail::Instance UserData (__added__)
+* AWS::Location::Tracker PositionFiltering (__added__)
+* AWS::MWAA::Environment Tags.Type (__deleted__)
+* AWS::MWAA::Environment Tags.PrimitiveType (__added__)
+* AWS::MemoryDB::Cluster ACLName.Required (__changed__)
+  * Old: false
+  * New: true
+* AWS::MemoryDB::Cluster NodeType.Required (__changed__)
+  * Old: false
+  * New: true
+* AWS::MemoryDB::ParameterGroup Family.Required (__changed__)
+  * Old: false
+  * New: true
+* AWS::MemoryDB::SubnetGroup SubnetIds.Required (__changed__)
+  * Old: false
+  * New: true
+* AWS::Pinpoint::Campaign Priority (__added__)
+* AWS::QuickSight::Analysis SourceEntity.Required (__changed__)
+  * Old: false
+  * New: true
+* AWS::QuickSight::Dashboard SourceEntity.Required (__changed__)
+  * Old: false
+  * New: true
+* AWS::QuickSight::Template SourceEntity.Required (__changed__)
+  * Old: false
+  * New: true
+* AWS::Route53RecoveryControl::Cluster Tags (__added__)
+* AWS::Route53RecoveryControl::ControlPanel Tags (__added__)
+* AWS::Route53RecoveryControl::SafetyRule Tags (__added__)
+* AWS::Route53Resolver::ResolverRule Tags.DuplicatesAllowed (__added__)
+* AWS::Route53Resolver::ResolverRule TargetIps.DuplicatesAllowed (__added__)
+* AWS::SageMaker::NotebookInstance PlatformIdentifier (__added__)
+* AWS::StepFunctions::Activity Tags.DuplicatesAllowed (__added__)
+* AWS::Synthetics::Canary ArtifactConfig (__added__)
+
+## Property Type Changes
+
+* AWS::MWAA::Environment.TagMap (__removed__)
+* AWS::AppFlow::ConnectorProfile.OAuthProperties (__added__)
+* AWS::AppFlow::ConnectorProfile.SAPODataConnectorProfileCredentials (__added__)
+* AWS::AppFlow::ConnectorProfile.SAPODataConnectorProfileProperties (__added__)
+* AWS::AppFlow::Flow.S3InputFormatConfig (__added__)
+* AWS::AppFlow::Flow.SAPODataSourceProperties (__added__)
+* AWS::AutoScaling::AutoScalingGroup.AcceleratorCountRequest (__added__)
+* AWS::AutoScaling::AutoScalingGroup.AcceleratorTotalMemoryMiBRequest (__added__)
+* AWS::AutoScaling::AutoScalingGroup.BaselineEbsBandwidthMbpsRequest (__added__)
+* AWS::AutoScaling::AutoScalingGroup.InstanceRequirements (__added__)
+* AWS::AutoScaling::AutoScalingGroup.MemoryGiBPerVCpuRequest (__added__)
+* AWS::AutoScaling::AutoScalingGroup.MemoryMiBRequest (__added__)
+* AWS::AutoScaling::AutoScalingGroup.NetworkInterfaceCountRequest (__added__)
+* AWS::AutoScaling::AutoScalingGroup.TotalLocalStorageGBRequest (__added__)
+* AWS::AutoScaling::AutoScalingGroup.VCpuCountRequest (__added__)
+* AWS::EC2::EC2Fleet.AcceleratorCountRequest (__added__)
+* AWS::EC2::EC2Fleet.AcceleratorTotalMemoryMiBRequest (__added__)
+* AWS::EC2::EC2Fleet.BaselineEbsBandwidthMbpsRequest (__added__)
+* AWS::EC2::EC2Fleet.InstanceRequirementsRequest (__added__)
+* AWS::EC2::EC2Fleet.MemoryGiBPerVCpuRequest (__added__)
+* AWS::EC2::EC2Fleet.MemoryMiBRequest (__added__)
+* AWS::EC2::EC2Fleet.NetworkInterfaceCountRequest (__added__)
+* AWS::EC2::EC2Fleet.TotalLocalStorageGBRequest (__added__)
+* AWS::EC2::EC2Fleet.VCpuCountRangeRequest (__added__)
+* AWS::EC2::SpotFleet.AcceleratorCountRequest (__added__)
+* AWS::EC2::SpotFleet.AcceleratorTotalMemoryMiBRequest (__added__)
+* AWS::EC2::SpotFleet.BaselineEbsBandwidthMbpsRequest (__added__)
+* AWS::EC2::SpotFleet.InstanceRequirementsRequest (__added__)
+* AWS::EC2::SpotFleet.MemoryGiBPerVCpuRequest (__added__)
+* AWS::EC2::SpotFleet.MemoryMiBRequest (__added__)
+* AWS::EC2::SpotFleet.NetworkInterfaceCountRequest (__added__)
+* AWS::EC2::SpotFleet.TotalLocalStorageGBRequest (__added__)
+* AWS::EC2::SpotFleet.VCpuCountRangeRequest (__added__)
+* AWS::ECS::TaskDefinition.RuntimePlatform (__added__)
+* AWS::ImageBuilder::InfrastructureConfiguration.InstanceMetadataOptions (__added__)
+* AWS::Pinpoint::Campaign.CampaignInAppMessage (__added__)
+* AWS::Pinpoint::Campaign.DefaultButtonConfiguration (__added__)
+* AWS::Pinpoint::Campaign.InAppMessageBodyConfig (__added__)
+* AWS::Pinpoint::Campaign.InAppMessageButton (__added__)
+* AWS::Pinpoint::Campaign.InAppMessageContent (__added__)
+* AWS::Pinpoint::Campaign.InAppMessageHeaderConfig (__added__)
+* AWS::Pinpoint::Campaign.OverrideButtonConfiguration (__added__)
+* AWS::QuickSight::DataSource.AmazonOpenSearchParameters (__added__)
+* AWS::Synthetics::Canary.ArtifactConfig (__added__)
+* AWS::Synthetics::Canary.S3Encryption (__added__)
+* AWS::AppFlow::ConnectorProfile.ConnectorProfileCredentials SAPOData (__added__)
+* AWS::AppFlow::ConnectorProfile.ConnectorProfileProperties SAPOData (__added__)
+* AWS::AppFlow::Flow.ConnectorOperator SAPOData (__added__)
+* AWS::AppFlow::Flow.S3SourceProperties S3InputFormatConfig (__added__)
+* AWS::AppFlow::Flow.SourceConnectorProperties SAPOData (__added__)
+* AWS::AutoScaling::AutoScalingGroup.LaunchTemplateOverrides InstanceRequirements (__added__)
+* AWS::Backup::BackupSelection.BackupSelectionResourceType Conditions (__added__)
+* AWS::Backup::BackupSelection.BackupSelectionResourceType NotResources (__added__)
+* AWS::CodeBuild::Project.ProjectBuildBatchConfig BatchReportMode (__added__)
+* AWS::EC2::EC2Fleet.FleetLaunchTemplateOverridesRequest InstanceRequirements (__added__)
+* AWS::EC2::EC2Fleet.SpotOptionsRequest MaintenanceStrategies (__added__)
+* AWS::EC2::EC2Fleet.TargetCapacitySpecificationRequest TargetCapacityUnitType (__added__)
+* AWS::EC2::SpotFleet.LaunchTemplateOverrides InstanceRequirements (__added__)
+* AWS::EC2::SpotFleet.SpotCapacityRebalance TerminationDelay (__added__)
+* AWS::EC2::SpotFleet.SpotFleetLaunchSpecification InstanceRequirements (__added__)
+* AWS::EC2::SpotFleet.SpotFleetLaunchSpecification InstanceType.Required (__changed__)
+  * Old: true
+  * New: false
+* AWS::EC2::SpotFleet.SpotFleetRequestConfigData TargetCapacityUnitType (__added__)
+* AWS::ImageBuilder::ContainerRecipe.EbsInstanceBlockDeviceSpecification Throughput (__added__)
+* AWS::ImageBuilder::ImageRecipe.EbsInstanceBlockDeviceSpecification Throughput (__added__)
+* AWS::Lightsail::Instance.Networking MonthlyTransfer.Type (__added__)
+* AWS::Pinpoint::Campaign.Limits Session (__added__)
+* AWS::Pinpoint::Campaign.MessageConfiguration InAppMessage (__added__)
+* AWS::QuickSight::DataSource.DataSourceParameters AmazonOpenSearchParameters (__added__)
+
+
 # CloudFormation Resource Specification v43.0.0
 
 ## New Resource Types
diff --git a/packages/@aws-cdk/cfnspec/cfn.version b/packages/@aws-cdk/cfnspec/cfn.version
index f3986a67888db..783c5bb1ce5c2 100644
--- a/packages/@aws-cdk/cfnspec/cfn.version
+++ b/packages/@aws-cdk/cfnspec/cfn.version
@@ -1 +1 @@
-43.0.0
+46.0.0
diff --git a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json
index b5b29349fe4e4..2db5051c26ccf 100644
--- a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json
+++ b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json
@@ -2557,6 +2557,12 @@
           "Type": "RedshiftConnectorProfileCredentials",
           "UpdateType": "Mutable"
         },
+        "SAPOData": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-connectorprofilecredentials.html#cfn-appflow-connectorprofile-connectorprofilecredentials-sapodata",
+          "Required": false,
+          "Type": "SAPODataConnectorProfileCredentials",
+          "UpdateType": "Mutable"
+        },
         "Salesforce": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-connectorprofilecredentials.html#cfn-appflow-connectorprofile-connectorprofilecredentials-salesforce",
           "Required": false,
@@ -2640,6 +2646,12 @@
           "Type": "RedshiftConnectorProfileProperties",
           "UpdateType": "Mutable"
         },
+        "SAPOData": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-connectorprofileproperties.html#cfn-appflow-connectorprofile-connectorprofileproperties-sapodata",
+          "Required": false,
+          "Type": "SAPODataConnectorProfileProperties",
+          "UpdateType": "Mutable"
+        },
         "Salesforce": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-connectorprofileproperties.html#cfn-appflow-connectorprofile-connectorprofileproperties-salesforce",
           "Required": false,
@@ -2843,6 +2855,31 @@
         }
       }
     },
+    "AWS::AppFlow::ConnectorProfile.OAuthProperties": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-oauthproperties.html",
+      "Properties": {
+        "AuthCodeUrl": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-oauthproperties.html#cfn-appflow-connectorprofile-oauthproperties-authcodeurl",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "OAuthScopes": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-oauthproperties.html#cfn-appflow-connectorprofile-oauthproperties-oauthscopes",
+          "DuplicatesAllowed": false,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "TokenUrl": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-oauthproperties.html#cfn-appflow-connectorprofile-oauthproperties-tokenurl",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::AppFlow::ConnectorProfile.RedshiftConnectorProfileCredentials": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-redshiftconnectorprofilecredentials.html",
       "Properties": {
@@ -2889,6 +2926,70 @@
         }
       }
     },
+    "AWS::AppFlow::ConnectorProfile.SAPODataConnectorProfileCredentials": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofilecredentials.html",
+      "Properties": {
+        "BasicAuthCredentials": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofilecredentials.html#cfn-appflow-connectorprofile-sapodataconnectorprofilecredentials-basicauthcredentials",
+          "PrimitiveType": "Json",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "OAuthCredentials": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofilecredentials.html#cfn-appflow-connectorprofile-sapodataconnectorprofilecredentials-oauthcredentials",
+          "PrimitiveType": "Json",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::AppFlow::ConnectorProfile.SAPODataConnectorProfileProperties": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html",
+      "Properties": {
+        "ApplicationHostUrl": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-applicationhosturl",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "ApplicationServicePath": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-applicationservicepath",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "ClientNumber": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-clientnumber",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "LogonLanguage": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-logonlanguage",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "OAuthProperties": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-oauthproperties",
+          "Required": false,
+          "Type": "OAuthProperties",
+          "UpdateType": "Mutable"
+        },
+        "PortNumber": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-portnumber",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "PrivateLinkServiceName": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-privatelinkservicename",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::AppFlow::ConnectorProfile.SalesforceConnectorProfileCredentials": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-salesforceconnectorprofilecredentials.html",
       "Properties": {
@@ -3224,6 +3325,12 @@
           "Required": false,
           "UpdateType": "Mutable"
         },
+        "SAPOData": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-connectoroperator.html#cfn-appflow-flow-connectoroperator-sapodata",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "Salesforce": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-connectoroperator.html#cfn-appflow-flow-connectoroperator-salesforce",
           "PrimitiveType": "String",
@@ -3530,6 +3637,17 @@
         }
       }
     },
+    "AWS::AppFlow::Flow.S3InputFormatConfig": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-s3inputformatconfig.html",
+      "Properties": {
+        "S3InputFileType": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-s3inputformatconfig.html#cfn-appflow-flow-s3inputformatconfig-s3inputfiletype",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::AppFlow::Flow.S3OutputFormatConfig": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-s3outputformatconfig.html",
       "Properties": {
@@ -3567,6 +3685,23 @@
           "PrimitiveType": "String",
           "Required": true,
           "UpdateType": "Mutable"
+        },
+        "S3InputFormatConfig": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-s3sourceproperties.html#cfn-appflow-flow-s3sourceproperties-s3inputformatconfig",
+          "Required": false,
+          "Type": "S3InputFormatConfig",
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::AppFlow::Flow.SAPODataSourceProperties": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-sapodatasourceproperties.html",
+      "Properties": {
+        "ObjectPath": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-sapodatasourceproperties.html#cfn-appflow-flow-sapodatasourceproperties-objectpath",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Mutable"
         }
       }
     },
@@ -3771,6 +3906,12 @@
           "Type": "S3SourceProperties",
           "UpdateType": "Mutable"
         },
+        "SAPOData": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-sourceconnectorproperties.html#cfn-appflow-flow-sourceconnectorproperties-sapodata",
+          "Required": false,
+          "Type": "SAPODataSourceProperties",
+          "UpdateType": "Mutable"
+        },
         "Salesforce": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-sourceconnectorproperties.html#cfn-appflow-flow-sourceconnectorproperties-salesforce",
           "Required": false,
@@ -8309,6 +8450,202 @@
         }
       }
     },
+    "AWS::AutoScaling::AutoScalingGroup.AcceleratorCountRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-acceleratorcountrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-acceleratorcountrequest.html#cfn-autoscaling-autoscalinggroup-acceleratorcountrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-acceleratorcountrequest.html#cfn-autoscaling-autoscalinggroup-acceleratorcountrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::AutoScaling::AutoScalingGroup.AcceleratorTotalMemoryMiBRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-acceleratortotalmemorymibrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-acceleratortotalmemorymibrequest.html#cfn-autoscaling-autoscalinggroup-acceleratortotalmemorymibrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-acceleratortotalmemorymibrequest.html#cfn-autoscaling-autoscalinggroup-acceleratortotalmemorymibrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::AutoScaling::AutoScalingGroup.BaselineEbsBandwidthMbpsRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-baselineebsbandwidthmbpsrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-baselineebsbandwidthmbpsrequest.html#cfn-autoscaling-autoscalinggroup-baselineebsbandwidthmbpsrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-baselineebsbandwidthmbpsrequest.html#cfn-autoscaling-autoscalinggroup-baselineebsbandwidthmbpsrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::AutoScaling::AutoScalingGroup.InstanceRequirements": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html",
+      "Properties": {
+        "AcceleratorCount": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-acceleratorcount",
+          "Required": false,
+          "Type": "AcceleratorCountRequest",
+          "UpdateType": "Mutable"
+        },
+        "AcceleratorManufacturers": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-acceleratormanufacturers",
+          "DuplicatesAllowed": false,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "AcceleratorNames": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-acceleratornames",
+          "DuplicatesAllowed": false,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "AcceleratorTotalMemoryMiB": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-acceleratortotalmemorymib",
+          "Required": false,
+          "Type": "AcceleratorTotalMemoryMiBRequest",
+          "UpdateType": "Mutable"
+        },
+        "AcceleratorTypes": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-acceleratortypes",
+          "DuplicatesAllowed": false,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "BareMetal": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-baremetal",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "BaselineEbsBandwidthMbps": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-baselineebsbandwidthmbps",
+          "Required": false,
+          "Type": "BaselineEbsBandwidthMbpsRequest",
+          "UpdateType": "Mutable"
+        },
+        "BurstablePerformance": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-burstableperformance",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "CpuManufacturers": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-cpumanufacturers",
+          "DuplicatesAllowed": false,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "ExcludedInstanceTypes": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-excludedinstancetypes",
+          "DuplicatesAllowed": false,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "InstanceGenerations": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-instancegenerations",
+          "DuplicatesAllowed": false,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "LocalStorage": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-localstorage",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "LocalStorageTypes": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-localstoragetypes",
+          "DuplicatesAllowed": false,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "MemoryGiBPerVCpu": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-memorygibpervcpu",
+          "Required": false,
+          "Type": "MemoryGiBPerVCpuRequest",
+          "UpdateType": "Mutable"
+        },
+        "MemoryMiB": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-memorymib",
+          "Required": false,
+          "Type": "MemoryMiBRequest",
+          "UpdateType": "Mutable"
+        },
+        "NetworkInterfaceCount": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-networkinterfacecount",
+          "Required": false,
+          "Type": "NetworkInterfaceCountRequest",
+          "UpdateType": "Mutable"
+        },
+        "OnDemandMaxPricePercentageOverLowestPrice": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-ondemandmaxpricepercentageoverlowestprice",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "RequireHibernateSupport": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-requirehibernatesupport",
+          "PrimitiveType": "Boolean",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "SpotMaxPricePercentageOverLowestPrice": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-spotmaxpricepercentageoverlowestprice",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "TotalLocalStorageGB": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-totallocalstoragegb",
+          "Required": false,
+          "Type": "TotalLocalStorageGBRequest",
+          "UpdateType": "Mutable"
+        },
+        "VCpuCount": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-vcpucount",
+          "Required": false,
+          "Type": "VCpuCountRequest",
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::AutoScaling::AutoScalingGroup.InstancesDistribution": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancesdistribution.html",
       "Properties": {
@@ -8372,6 +8709,12 @@
     "AWS::AutoScaling::AutoScalingGroup.LaunchTemplateOverrides": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-launchtemplateoverrides.html",
       "Properties": {
+        "InstanceRequirements": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-launchtemplateoverrides.html#cfn-as-mixedinstancespolicy-instancerequirements",
+          "Required": false,
+          "Type": "InstanceRequirements",
+          "UpdateType": "Mutable"
+        },
         "InstanceType": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-launchtemplateoverrides.html#cfn-autoscaling-autoscalinggroup-launchtemplateoverrides-instancetype",
           "PrimitiveType": "String",
@@ -8462,6 +8805,40 @@
         }
       }
     },
+    "AWS::AutoScaling::AutoScalingGroup.MemoryGiBPerVCpuRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-memorygibpervcpurequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-memorygibpervcpurequest.html#cfn-autoscaling-autoscalinggroup-memorygibpervcpurequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-memorygibpervcpurequest.html#cfn-autoscaling-autoscalinggroup-memorygibpervcpurequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::AutoScaling::AutoScalingGroup.MemoryMiBRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-memorymibrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-memorymibrequest.html#cfn-autoscaling-autoscalinggroup-memorymibrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-memorymibrequest.html#cfn-autoscaling-autoscalinggroup-memorymibrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::AutoScaling::AutoScalingGroup.MetricsCollection": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-metricscollection.html",
       "Properties": {
@@ -8498,6 +8875,23 @@
         }
       }
     },
+    "AWS::AutoScaling::AutoScalingGroup.NetworkInterfaceCountRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-networkinterfacecountrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-networkinterfacecountrequest.html#cfn-autoscaling-autoscalinggroup-networkinterfacecountrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-networkinterfacecountrequest.html#cfn-autoscaling-autoscalinggroup-networkinterfacecountrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::AutoScaling::AutoScalingGroup.NotificationConfiguration": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-notificationconfigurations.html",
       "Properties": {
@@ -8540,6 +8934,40 @@
         }
       }
     },
+    "AWS::AutoScaling::AutoScalingGroup.TotalLocalStorageGBRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-totallocalstoragegbrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-totallocalstoragegbrequest.html#cfn-autoscaling-autoscalinggroup-totallocalstoragegbrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-totallocalstoragegbrequest.html#cfn-autoscaling-autoscalinggroup-totallocalstoragegbrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::AutoScaling::AutoScalingGroup.VCpuCountRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-vcpucountrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-vcpucountrequest.html#cfn-autoscaling-autoscalinggroup-vcpucountrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-vcpucountrequest.html#cfn-autoscaling-autoscalinggroup-vcpucountrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::AutoScaling::LaunchConfiguration.BlockDevice": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-launchconfig-blockdev-template.html",
       "Properties": {
@@ -9318,6 +9746,12 @@
     "AWS::Backup::BackupSelection.BackupSelectionResourceType": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-backup-backupselection-backupselectionresourcetype.html",
       "Properties": {
+        "Conditions": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-backup-backupselection-backupselectionresourcetype.html#cfn-backup-backupselection-backupselectionresourcetype-conditions",
+          "PrimitiveType": "Json",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
         "IamRoleArn": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-backup-backupselection-backupselectionresourcetype.html#cfn-backup-backupselection-backupselectionresourcetype-iamrolearn",
           "PrimitiveType": "String",
@@ -9332,6 +9766,14 @@
           "Type": "List",
           "UpdateType": "Immutable"
         },
+        "NotResources": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-backup-backupselection-backupselectionresourcetype.html#cfn-backup-backupselection-backupselectionresourcetype-notresources",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
         "Resources": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-backup-backupselection-backupselectionresourcetype.html#cfn-backup-backupselection-backupselectionresourcetype-resources",
           "DuplicatesAllowed": true,
@@ -12684,6 +13126,12 @@
     "AWS::CodeBuild::Project.ProjectBuildBatchConfig": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-projectbuildbatchconfig.html",
       "Properties": {
+        "BatchReportMode": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-projectbuildbatchconfig.html#cfn-codebuild-project-projectbuildbatchconfig-batchreportmode",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "CombineArtifacts": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-projectbuildbatchconfig.html#cfn-codebuild-project-projectbuildbatchconfig-combineartifacts",
           "PrimitiveType": "Boolean",
@@ -15284,6 +15732,46 @@
         }
       }
     },
+    "AWS::Connect::HoursOfOperation.HoursOfOperationConfig": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationconfig.html",
+      "Properties": {
+        "Day": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationconfig.html#cfn-connect-hoursofoperation-hoursofoperationconfig-day",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Mutable"
+        },
+        "EndTime": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationconfig.html#cfn-connect-hoursofoperation-hoursofoperationconfig-endtime",
+          "Required": true,
+          "Type": "HoursOfOperationTimeSlice",
+          "UpdateType": "Mutable"
+        },
+        "StartTime": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationconfig.html#cfn-connect-hoursofoperation-hoursofoperationconfig-starttime",
+          "Required": true,
+          "Type": "HoursOfOperationTimeSlice",
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::Connect::HoursOfOperation.HoursOfOperationTimeSlice": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationtimeslice.html",
+      "Properties": {
+        "Hours": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationtimeslice.html#cfn-connect-hoursofoperation-hoursofoperationtimeslice-hours",
+          "PrimitiveType": "Integer",
+          "Required": true,
+          "UpdateType": "Mutable"
+        },
+        "Minutes": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationtimeslice.html#cfn-connect-hoursofoperation-hoursofoperationtimeslice-minutes",
+          "PrimitiveType": "Integer",
+          "Required": true,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::Connect::QuickConnect.PhoneNumberQuickConnectConfig": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-quickconnect-phonenumberquickconnectconfig.html",
       "Properties": {
@@ -15358,6 +15846,58 @@
         }
       }
     },
+    "AWS::Connect::User.UserIdentityInfo": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-useridentityinfo.html",
+      "Properties": {
+        "Email": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-useridentityinfo.html#cfn-connect-user-useridentityinfo-email",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "FirstName": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-useridentityinfo.html#cfn-connect-user-useridentityinfo-firstname",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "LastName": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-useridentityinfo.html#cfn-connect-user-useridentityinfo-lastname",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::Connect::User.UserPhoneConfig": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-userphoneconfig.html",
+      "Properties": {
+        "AfterContactWorkTimeLimit": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-userphoneconfig.html#cfn-connect-user-userphoneconfig-aftercontactworktimelimit",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "AutoAccept": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-userphoneconfig.html#cfn-connect-user-userphoneconfig-autoaccept",
+          "PrimitiveType": "Boolean",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "DeskPhoneNumber": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-userphoneconfig.html#cfn-connect-user-userphoneconfig-deskphonenumber",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "PhoneType": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-userphoneconfig.html#cfn-connect-user-userphoneconfig-phonetype",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::CustomerProfiles::Integration.ConnectorOperator": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-customerprofiles-integration-connectoroperator.html",
       "Properties": {
@@ -19032,6 +19572,72 @@
         }
       }
     },
+    "AWS::EC2::CapacityReservationFleet.InstanceTypeSpecification": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html",
+      "Properties": {
+        "AvailabilityZone": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-availabilityzone",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "AvailabilityZoneId": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-availabilityzoneid",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "EbsOptimized": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-ebsoptimized",
+          "PrimitiveType": "Boolean",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "InstancePlatform": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-instanceplatform",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "InstanceType": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-instancetype",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Priority": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-priority",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Weight": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-weight",
+          "PrimitiveType": "Double",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::EC2::CapacityReservationFleet.TagSpecification": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-tagspecification.html",
+      "Properties": {
+        "ResourceType": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-tagspecification.html#cfn-ec2-capacityreservationfleet-tagspecification-resourcetype",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-tagspecification.html#cfn-ec2-capacityreservationfleet-tagspecification-tags",
+          "DuplicatesAllowed": true,
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::EC2::ClientVpnEndpoint.CertificateAuthenticationRequest": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-certificateauthenticationrequest.html",
       "Properties": {
@@ -19158,6 +19764,57 @@
         }
       }
     },
+    "AWS::EC2::EC2Fleet.AcceleratorCountRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-acceleratorcountrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-acceleratorcountrequest.html#cfn-ec2-ec2fleet-acceleratorcountrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-acceleratorcountrequest.html#cfn-ec2-ec2fleet-acceleratorcountrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::EC2::EC2Fleet.AcceleratorTotalMemoryMiBRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-acceleratortotalmemorymibrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-acceleratortotalmemorymibrequest.html#cfn-ec2-ec2fleet-acceleratortotalmemorymibrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-acceleratortotalmemorymibrequest.html#cfn-ec2-ec2fleet-acceleratortotalmemorymibrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::EC2::EC2Fleet.BaselineEbsBandwidthMbpsRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-baselineebsbandwidthmbpsrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-baselineebsbandwidthmbpsrequest.html#cfn-ec2-ec2fleet-baselineebsbandwidthmbpsrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-baselineebsbandwidthmbpsrequest.html#cfn-ec2-ec2fleet-baselineebsbandwidthmbpsrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::EC2::EC2Fleet.CapacityReservationOptionsRequest": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-capacityreservationoptionsrequest.html",
       "Properties": {
@@ -19197,6 +19854,12 @@
           "Required": false,
           "UpdateType": "Immutable"
         },
+        "InstanceRequirements": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest-instancerequirements",
+          "Required": false,
+          "Type": "InstanceRequirementsRequest",
+          "UpdateType": "Immutable"
+        },
         "InstanceType": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest-instancetype",
           "PrimitiveType": "String",
@@ -19258,6 +19921,202 @@
         }
       }
     },
+    "AWS::EC2::EC2Fleet.InstanceRequirementsRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html",
+      "Properties": {
+        "AcceleratorCount": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-acceleratorcount",
+          "Required": false,
+          "Type": "AcceleratorCountRequest",
+          "UpdateType": "Immutable"
+        },
+        "AcceleratorManufacturers": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-acceleratormanufacturers",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "AcceleratorNames": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-acceleratornames",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "AcceleratorTotalMemoryMiB": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-acceleratortotalmemorymib",
+          "Required": false,
+          "Type": "AcceleratorTotalMemoryMiBRequest",
+          "UpdateType": "Immutable"
+        },
+        "AcceleratorTypes": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-acceleratortypes",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "BareMetal": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-baremetal",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "BaselineEbsBandwidthMbps": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-baselineebsbandwidthmbps",
+          "Required": false,
+          "Type": "BaselineEbsBandwidthMbpsRequest",
+          "UpdateType": "Immutable"
+        },
+        "BurstablePerformance": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-burstableperformance",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "CpuManufacturers": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-cpumanufacturers",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "ExcludedInstanceTypes": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-excludedinstancetypes",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "InstanceGenerations": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-instancegenerations",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "LocalStorage": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-localstorage",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "LocalStorageTypes": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-localstoragetypes",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "MemoryGiBPerVCpu": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-memorygibpervcpu",
+          "Required": false,
+          "Type": "MemoryGiBPerVCpuRequest",
+          "UpdateType": "Immutable"
+        },
+        "MemoryMiB": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-memorymib",
+          "Required": false,
+          "Type": "MemoryMiBRequest",
+          "UpdateType": "Immutable"
+        },
+        "NetworkInterfaceCount": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-networkinterfacecount",
+          "Required": false,
+          "Type": "NetworkInterfaceCountRequest",
+          "UpdateType": "Immutable"
+        },
+        "OnDemandMaxPricePercentageOverLowestPrice": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-ondemandmaxpricepercentageoverlowestprice",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "RequireHibernateSupport": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-requirehibernatesupport",
+          "PrimitiveType": "Boolean",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "SpotMaxPricePercentageOverLowestPrice": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-spotmaxpricepercentageoverlowestprice",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "TotalLocalStorageGB": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-totallocalstoragegb",
+          "Required": false,
+          "Type": "TotalLocalStorageGBRequest",
+          "UpdateType": "Immutable"
+        },
+        "VCpuCount": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-vcpucount",
+          "Required": false,
+          "Type": "VCpuCountRangeRequest",
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::EC2::EC2Fleet.MemoryGiBPerVCpuRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorygibpervcpurequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorygibpervcpurequest.html#cfn-ec2-ec2fleet-memorygibpervcpurequest-max",
+          "PrimitiveType": "Double",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorygibpervcpurequest.html#cfn-ec2-ec2fleet-memorygibpervcpurequest-min",
+          "PrimitiveType": "Double",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::EC2::EC2Fleet.MemoryMiBRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorymibrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorymibrequest.html#cfn-ec2-ec2fleet-memorymibrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorymibrequest.html#cfn-ec2-ec2fleet-memorymibrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::EC2::EC2Fleet.NetworkInterfaceCountRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-networkinterfacecountrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-networkinterfacecountrequest.html#cfn-ec2-ec2fleet-networkinterfacecountrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-networkinterfacecountrequest.html#cfn-ec2-ec2fleet-networkinterfacecountrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::EC2::EC2Fleet.OnDemandOptionsRequest": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-ondemandoptionsrequest.html",
       "Properties": {
@@ -19373,6 +20232,12 @@
           "Required": false,
           "UpdateType": "Immutable"
         },
+        "MaintenanceStrategies": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html#cfn-ec2-ec2fleet-spotoptionsrequest-maintenancestrategies",
+          "PrimitiveType": "Json",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
         "MaxTotalPrice": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html#cfn-ec2-ec2fleet-spotoptionsrequest-maxtotalprice",
           "PrimitiveType": "String",
@@ -19439,6 +20304,12 @@
           "Required": false,
           "UpdateType": "Mutable"
         },
+        "TargetCapacityUnitType": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-targetcapacityspecificationrequest.html#cfn-ec2-ec2fleet-targetcapacityspecificationrequest-targetcapacityunittype",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "TotalTargetCapacity": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-targetcapacityspecificationrequest.html#cfn-ec2-ec2fleet-targetcapacityspecificationrequest-totaltargetcapacity",
           "PrimitiveType": "Integer",
@@ -19447,6 +20318,40 @@
         }
       }
     },
+    "AWS::EC2::EC2Fleet.TotalLocalStorageGBRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-totallocalstoragegbrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-totallocalstoragegbrequest.html#cfn-ec2-ec2fleet-totallocalstoragegbrequest-max",
+          "PrimitiveType": "Double",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-totallocalstoragegbrequest.html#cfn-ec2-ec2fleet-totallocalstoragegbrequest-min",
+          "PrimitiveType": "Double",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::EC2::EC2Fleet.VCpuCountRangeRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-vcpucountrangerequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-vcpucountrangerequest.html#cfn-ec2-ec2fleet-vcpucountrangerequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-vcpucountrangerequest.html#cfn-ec2-ec2fleet-vcpucountrangerequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::EC2::Instance.AssociationParameter": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-ssmassociations-associationparameters.html",
       "Properties": {
@@ -21478,6 +22383,57 @@
         }
       }
     },
+    "AWS::EC2::SpotFleet.AcceleratorCountRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-acceleratorcountrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-acceleratorcountrequest.html#cfn-ec2-spotfleet-acceleratorcountrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-acceleratorcountrequest.html#cfn-ec2-spotfleet-acceleratorcountrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::EC2::SpotFleet.AcceleratorTotalMemoryMiBRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-acceleratortotalmemorymibrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-acceleratortotalmemorymibrequest.html#cfn-ec2-spotfleet-acceleratortotalmemorymibrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-acceleratortotalmemorymibrequest.html#cfn-ec2-spotfleet-acceleratortotalmemorymibrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::EC2::SpotFleet.BaselineEbsBandwidthMbpsRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-baselineebsbandwidthmbpsrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-baselineebsbandwidthmbpsrequest.html#cfn-ec2-spotfleet-baselineebsbandwidthmbpsrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-baselineebsbandwidthmbpsrequest.html#cfn-ec2-spotfleet-baselineebsbandwidthmbpsrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::EC2::SpotFleet.BlockDeviceMapping": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-blockdevicemapping.html",
       "Properties": {
@@ -21705,6 +22661,151 @@
         }
       }
     },
+    "AWS::EC2::SpotFleet.InstanceRequirementsRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html",
+      "Properties": {
+        "AcceleratorCount": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-acceleratorcount",
+          "Required": false,
+          "Type": "AcceleratorCountRequest",
+          "UpdateType": "Immutable"
+        },
+        "AcceleratorManufacturers": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-acceleratormanufacturers",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "AcceleratorNames": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-acceleratornames",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "AcceleratorTotalMemoryMiB": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-acceleratortotalmemorymib",
+          "Required": false,
+          "Type": "AcceleratorTotalMemoryMiBRequest",
+          "UpdateType": "Immutable"
+        },
+        "AcceleratorTypes": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-acceleratortypes",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "BareMetal": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-baremetal",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "BaselineEbsBandwidthMbps": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-baselineebsbandwidthmbps",
+          "Required": false,
+          "Type": "BaselineEbsBandwidthMbpsRequest",
+          "UpdateType": "Immutable"
+        },
+        "BurstablePerformance": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-burstableperformance",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "CpuManufacturers": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-cpumanufacturers",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "ExcludedInstanceTypes": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-excludedinstancetypes",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "InstanceGenerations": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-instancegenerations",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "LocalStorage": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-localstorage",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "LocalStorageTypes": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-localstoragetypes",
+          "DuplicatesAllowed": true,
+          "PrimitiveItemType": "String",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "MemoryGiBPerVCpu": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-memorygibpervcpu",
+          "Required": false,
+          "Type": "MemoryGiBPerVCpuRequest",
+          "UpdateType": "Immutable"
+        },
+        "MemoryMiB": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-memorymib",
+          "Required": false,
+          "Type": "MemoryMiBRequest",
+          "UpdateType": "Immutable"
+        },
+        "NetworkInterfaceCount": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-networkinterfacecount",
+          "Required": false,
+          "Type": "NetworkInterfaceCountRequest",
+          "UpdateType": "Immutable"
+        },
+        "OnDemandMaxPricePercentageOverLowestPrice": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-ondemandmaxpricepercentageoverlowestprice",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "RequireHibernateSupport": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-requirehibernatesupport",
+          "PrimitiveType": "Boolean",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "SpotMaxPricePercentageOverLowestPrice": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-spotmaxpricepercentageoverlowestprice",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "TotalLocalStorageGB": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-totallocalstoragegb",
+          "Required": false,
+          "Type": "TotalLocalStorageGBRequest",
+          "UpdateType": "Immutable"
+        },
+        "VCpuCount": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-vcpucount",
+          "Required": false,
+          "Type": "VCpuCountRangeRequest",
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::EC2::SpotFleet.LaunchTemplateConfig": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateconfig.html",
       "Properties": {
@@ -21733,6 +22834,12 @@
           "Required": false,
           "UpdateType": "Immutable"
         },
+        "InstanceRequirements": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateoverrides.html#cfn-ec2-spotfleet-launchtemplateoverrides-instancerequirements",
+          "Required": false,
+          "Type": "InstanceRequirementsRequest",
+          "UpdateType": "Immutable"
+        },
         "InstanceType": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateoverrides.html#cfn-ec2-spotfleet-launchtemplateoverrides-instancetype",
           "PrimitiveType": "String",
@@ -21776,6 +22883,57 @@
         }
       }
     },
+    "AWS::EC2::SpotFleet.MemoryGiBPerVCpuRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-memorygibpervcpurequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-memorygibpervcpurequest.html#cfn-ec2-spotfleet-memorygibpervcpurequest-max",
+          "PrimitiveType": "Double",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-memorygibpervcpurequest.html#cfn-ec2-spotfleet-memorygibpervcpurequest-min",
+          "PrimitiveType": "Double",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::EC2::SpotFleet.MemoryMiBRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-memorymibrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-memorymibrequest.html#cfn-ec2-spotfleet-memorymibrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-memorymibrequest.html#cfn-ec2-spotfleet-memorymibrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::EC2::SpotFleet.NetworkInterfaceCountRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-networkinterfacecountrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-networkinterfacecountrequest.html#cfn-ec2-spotfleet-networkinterfacecountrequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-networkinterfacecountrequest.html#cfn-ec2-spotfleet-networkinterfacecountrequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::EC2::SpotFleet.PrivateIpAddressSpecification": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-privateipaddressspecification.html",
       "Properties": {
@@ -21801,6 +22959,12 @@
           "PrimitiveType": "String",
           "Required": false,
           "UpdateType": "Immutable"
+        },
+        "TerminationDelay": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotcapacityrebalance.html#cfn-ec2-spotfleet-spotcapacityrebalance-terminationdelay",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
         }
       }
     },
@@ -21833,10 +22997,16 @@
           "Required": true,
           "UpdateType": "Immutable"
         },
+        "InstanceRequirements": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetlaunchspecification.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-instancerequirements",
+          "Required": false,
+          "Type": "InstanceRequirementsRequest",
+          "UpdateType": "Immutable"
+        },
         "InstanceType": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetlaunchspecification.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-instancetype",
           "PrimitiveType": "String",
-          "Required": true,
+          "Required": false,
           "UpdateType": "Immutable"
         },
         "KernelId": {
@@ -22039,6 +23209,12 @@
           "Required": true,
           "UpdateType": "Mutable"
         },
+        "TargetCapacityUnitType": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-targetcapacityunittype",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "TerminateInstancesWithExpiration": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-terminateinstanceswithexpiration",
           "PrimitiveType": "Boolean",
@@ -22142,6 +23318,40 @@
         }
       }
     },
+    "AWS::EC2::SpotFleet.TotalLocalStorageGBRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-totallocalstoragegbrequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-totallocalstoragegbrequest.html#cfn-ec2-spotfleet-totallocalstoragegbrequest-max",
+          "PrimitiveType": "Double",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-totallocalstoragegbrequest.html#cfn-ec2-spotfleet-totallocalstoragegbrequest-min",
+          "PrimitiveType": "Double",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::EC2::SpotFleet.VCpuCountRangeRequest": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-vcpucountrangerequest.html",
+      "Properties": {
+        "Max": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-vcpucountrangerequest.html#cfn-ec2-spotfleet-vcpucountrangerequest-max",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Min": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-vcpucountrangerequest.html#cfn-ec2-spotfleet-vcpucountrangerequest-min",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::EC2::TrafficMirrorFilterRule.TrafficMirrorPortRange": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-trafficmirrorfilterrule-trafficmirrorportrange.html",
       "Properties": {
@@ -23419,6 +24629,23 @@
         }
       }
     },
+    "AWS::ECS::TaskDefinition.RuntimePlatform": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-runtimeplatform.html",
+      "Properties": {
+        "CpuArchitecture": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-runtimeplatform.html#cfn-ecs-taskdefinition-runtimeplatform-cpuarchitecture",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "OperatingSystemFamily": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-runtimeplatform.html#cfn-ecs-taskdefinition-runtimeplatform-operatingsystemfamily",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::ECS::TaskDefinition.Secret": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-secret.html",
       "Properties": {
@@ -32696,6 +33923,12 @@
           "Required": false,
           "UpdateType": "Immutable"
         },
+        "Throughput": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-containerrecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-containerrecipe-ebsinstanceblockdevicespecification-throughput",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
         "VolumeSize": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-containerrecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-containerrecipe-ebsinstanceblockdevicespecification-volumesize",
           "PrimitiveType": "Integer",
@@ -32971,6 +34204,12 @@
           "Required": false,
           "UpdateType": "Immutable"
         },
+        "Throughput": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification-throughput",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
         "VolumeSize": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification-volumesize",
           "PrimitiveType": "Integer",
@@ -33025,6 +34264,23 @@
         }
       }
     },
+    "AWS::ImageBuilder::InfrastructureConfiguration.InstanceMetadataOptions": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-infrastructureconfiguration-instancemetadataoptions.html",
+      "Properties": {
+        "HttpPutResponseHopLimit": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-infrastructureconfiguration-instancemetadataoptions.html#cfn-imagebuilder-infrastructureconfiguration-instancemetadataoptions-httpputresponsehoplimit",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "HttpTokens": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-infrastructureconfiguration-instancemetadataoptions.html#cfn-imagebuilder-infrastructureconfiguration-instancemetadataoptions-httptokens",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::ImageBuilder::InfrastructureConfiguration.Logging": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-infrastructureconfiguration-logging.html",
       "Properties": {
@@ -41896,6 +43152,59 @@
         }
       }
     },
+    "AWS::Lightsail::Database.RelationalDatabaseParameter": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html",
+      "Properties": {
+        "AllowedValues": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-allowedvalues",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "ApplyMethod": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-applymethod",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "ApplyType": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-applytype",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "DataType": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-datatype",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Description": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-description",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "IsModifiable": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-ismodifiable",
+          "PrimitiveType": "Boolean",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "ParameterName": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-parametername",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "ParameterValue": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-parametervalue",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::Lightsail::Disk.AddOn": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-disk-addon.html",
       "Properties": {
@@ -42070,6 +43379,7 @@
         "MonthlyTransfer": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-instance-networking.html#cfn-lightsail-instance-networking-monthlytransfer",
           "Required": false,
+          "Type": "MonthlyTransfer",
           "UpdateType": "Mutable"
         },
         "Ports": {
@@ -43106,9 +44416,6 @@
         }
       }
     },
-    "AWS::MWAA::Environment.TagMap": {
-      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-mwaa-environment-tagmap.html"
-    },
     "AWS::Macie::FindingsFilter.Criterion": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-macie-findingsfilter-criterion.html"
     },
@@ -50954,6 +52261,28 @@
         }
       }
     },
+    "AWS::Panorama::ApplicationInstance.ManifestOverridesPayload": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-panorama-applicationinstance-manifestoverridespayload.html",
+      "Properties": {
+        "PayloadData": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-panorama-applicationinstance-manifestoverridespayload.html#cfn-panorama-applicationinstance-manifestoverridespayload-payloaddata",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::Panorama::ApplicationInstance.ManifestPayload": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-panorama-applicationinstance-manifestpayload.html",
+      "Properties": {
+        "PayloadData": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-panorama-applicationinstance-manifestpayload.html#cfn-panorama-applicationinstance-manifestpayload-payloaddata",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::Pinpoint::ApplicationSettings.CampaignHook": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-applicationsettings-campaignhook.html",
       "Properties": {
@@ -51110,6 +52439,30 @@
         }
       }
     },
+    "AWS::Pinpoint::Campaign.CampaignInAppMessage": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-campaigninappmessage.html",
+      "Properties": {
+        "Content": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-campaigninappmessage.html#cfn-pinpoint-campaign-campaigninappmessage-content",
+          "ItemType": "InAppMessageContent",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "CustomConfig": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-campaigninappmessage.html#cfn-pinpoint-campaign-campaigninappmessage-customconfig",
+          "PrimitiveType": "Json",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Layout": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-campaigninappmessage.html#cfn-pinpoint-campaign-campaigninappmessage-layout",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::Pinpoint::Campaign.CampaignSmsMessage": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-campaignsmsmessage.html",
       "Properties": {
@@ -51151,6 +52504,47 @@
         }
       }
     },
+    "AWS::Pinpoint::Campaign.DefaultButtonConfiguration": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html",
+      "Properties": {
+        "BackgroundColor": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html#cfn-pinpoint-campaign-defaultbuttonconfiguration-backgroundcolor",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "BorderRadius": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html#cfn-pinpoint-campaign-defaultbuttonconfiguration-borderradius",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "ButtonAction": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html#cfn-pinpoint-campaign-defaultbuttonconfiguration-buttonaction",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Link": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html#cfn-pinpoint-campaign-defaultbuttonconfiguration-link",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Text": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html#cfn-pinpoint-campaign-defaultbuttonconfiguration-text",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "TextColor": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html#cfn-pinpoint-campaign-defaultbuttonconfiguration-textcolor",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::Pinpoint::Campaign.EventDimensions": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-eventdimensions.html",
       "Properties": {
@@ -51174,6 +52568,122 @@
         }
       }
     },
+    "AWS::Pinpoint::Campaign.InAppMessageBodyConfig": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebodyconfig.html",
+      "Properties": {
+        "Alignment": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebodyconfig.html#cfn-pinpoint-campaign-inappmessagebodyconfig-alignment",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Body": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebodyconfig.html#cfn-pinpoint-campaign-inappmessagebodyconfig-body",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "TextColor": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebodyconfig.html#cfn-pinpoint-campaign-inappmessagebodyconfig-textcolor",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::Pinpoint::Campaign.InAppMessageButton": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebutton.html",
+      "Properties": {
+        "Android": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebutton.html#cfn-pinpoint-campaign-inappmessagebutton-android",
+          "Required": false,
+          "Type": "OverrideButtonConfiguration",
+          "UpdateType": "Mutable"
+        },
+        "DefaultConfig": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebutton.html#cfn-pinpoint-campaign-inappmessagebutton-defaultconfig",
+          "Required": false,
+          "Type": "DefaultButtonConfiguration",
+          "UpdateType": "Mutable"
+        },
+        "IOS": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebutton.html#cfn-pinpoint-campaign-inappmessagebutton-ios",
+          "Required": false,
+          "Type": "OverrideButtonConfiguration",
+          "UpdateType": "Mutable"
+        },
+        "Web": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebutton.html#cfn-pinpoint-campaign-inappmessagebutton-web",
+          "Required": false,
+          "Type": "OverrideButtonConfiguration",
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::Pinpoint::Campaign.InAppMessageContent": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html",
+      "Properties": {
+        "BackgroundColor": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html#cfn-pinpoint-campaign-inappmessagecontent-backgroundcolor",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "BodyConfig": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html#cfn-pinpoint-campaign-inappmessagecontent-bodyconfig",
+          "Required": false,
+          "Type": "InAppMessageBodyConfig",
+          "UpdateType": "Mutable"
+        },
+        "HeaderConfig": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html#cfn-pinpoint-campaign-inappmessagecontent-headerconfig",
+          "Required": false,
+          "Type": "InAppMessageHeaderConfig",
+          "UpdateType": "Mutable"
+        },
+        "ImageUrl": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html#cfn-pinpoint-campaign-inappmessagecontent-imageurl",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "PrimaryBtn": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html#cfn-pinpoint-campaign-inappmessagecontent-primarybtn",
+          "Required": false,
+          "Type": "InAppMessageButton",
+          "UpdateType": "Mutable"
+        },
+        "SecondaryBtn": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html#cfn-pinpoint-campaign-inappmessagecontent-secondarybtn",
+          "Required": false,
+          "Type": "InAppMessageButton",
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::Pinpoint::Campaign.InAppMessageHeaderConfig": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessageheaderconfig.html",
+      "Properties": {
+        "Alignment": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessageheaderconfig.html#cfn-pinpoint-campaign-inappmessageheaderconfig-alignment",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Header": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessageheaderconfig.html#cfn-pinpoint-campaign-inappmessageheaderconfig-header",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "TextColor": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessageheaderconfig.html#cfn-pinpoint-campaign-inappmessageheaderconfig-textcolor",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::Pinpoint::Campaign.Limits": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-limits.html",
       "Properties": {
@@ -51195,6 +52705,12 @@
           "Required": false,
           "UpdateType": "Mutable"
         },
+        "Session": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-limits.html#cfn-pinpoint-campaign-limits-session",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "Total": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-limits.html#cfn-pinpoint-campaign-limits-total",
           "PrimitiveType": "Integer",
@@ -51319,6 +52835,12 @@
           "Type": "Message",
           "UpdateType": "Mutable"
         },
+        "InAppMessage": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-messageconfiguration.html#cfn-pinpoint-campaign-messageconfiguration-inappmessage",
+          "Required": false,
+          "Type": "CampaignInAppMessage",
+          "UpdateType": "Mutable"
+        },
         "SMSMessage": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-messageconfiguration.html#cfn-pinpoint-campaign-messageconfiguration-smsmessage",
           "Required": false,
@@ -51344,6 +52866,23 @@
         }
       }
     },
+    "AWS::Pinpoint::Campaign.OverrideButtonConfiguration": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-overridebuttonconfiguration.html",
+      "Properties": {
+        "ButtonAction": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-overridebuttonconfiguration.html#cfn-pinpoint-campaign-overridebuttonconfiguration-buttonaction",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Link": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-overridebuttonconfiguration.html#cfn-pinpoint-campaign-overridebuttonconfiguration-link",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::Pinpoint::Campaign.QuietTime": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-schedule-quiettime.html",
       "Properties": {
@@ -53139,6 +54678,17 @@
         }
       }
     },
+    "AWS::QuickSight::DataSource.AmazonOpenSearchParameters": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-amazonopensearchparameters.html",
+      "Properties": {
+        "Domain": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-amazonopensearchparameters.html#cfn-quicksight-datasource-amazonopensearchparameters-domain",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::QuickSight::DataSource.AthenaParameters": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-athenaparameters.html",
       "Properties": {
@@ -53263,6 +54813,12 @@
           "Type": "AmazonElasticsearchParameters",
           "UpdateType": "Mutable"
         },
+        "AmazonOpenSearchParameters": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-datasourceparameters.html#cfn-quicksight-datasource-datasourceparameters-amazonopensearchparameters",
+          "Required": false,
+          "Type": "AmazonOpenSearchParameters",
+          "UpdateType": "Mutable"
+        },
         "AthenaParameters": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-datasourceparameters.html#cfn-quicksight-datasource-datasourceparameters-athenaparameters",
           "Required": false,
@@ -60918,6 +62474,17 @@
         }
       }
     },
+    "AWS::Synthetics::Canary.ArtifactConfig": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-artifactconfig.html",
+      "Properties": {
+        "S3Encryption": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-artifactconfig.html#cfn-synthetics-canary-artifactconfig-s3encryption",
+          "Required": false,
+          "Type": "S3Encryption",
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::Synthetics::Canary.BaseScreenshot": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-basescreenshot.html",
       "Properties": {
@@ -61001,6 +62568,23 @@
         }
       }
     },
+    "AWS::Synthetics::Canary.S3Encryption": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-s3encryption.html",
+      "Properties": {
+        "EncryptionMode": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-s3encryption.html#cfn-synthetics-canary-s3encryption-encryptionmode",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "KmsKeyArn": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-s3encryption.html#cfn-synthetics-canary-s3encryption-kmskeyarn",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::Synthetics::Canary.Schedule": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-schedule.html",
       "Properties": {
@@ -63150,6 +64734,79 @@
         }
       }
     },
+    "AWS::Wisdom::Assistant.ServerSideEncryptionConfiguration": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-assistant-serversideencryptionconfiguration.html",
+      "Properties": {
+        "KmsKeyId": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-assistant-serversideencryptionconfiguration.html#cfn-wisdom-assistant-serversideencryptionconfiguration-kmskeyid",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::Wisdom::AssistantAssociation.AssociationData": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-assistantassociation-associationdata.html",
+      "Properties": {
+        "KnowledgeBaseId": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-assistantassociation-associationdata.html#cfn-wisdom-assistantassociation-associationdata-knowledgebaseid",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::Wisdom::KnowledgeBase.AppIntegrationsConfiguration": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-appintegrationsconfiguration.html",
+      "Properties": {
+        "AppIntegrationArn": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-appintegrationsconfiguration.html#cfn-wisdom-knowledgebase-appintegrationsconfiguration-appintegrationarn",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "ObjectFields": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-appintegrationsconfiguration.html#cfn-wisdom-knowledgebase-appintegrationsconfiguration-objectfields",
+          "PrimitiveItemType": "String",
+          "Required": true,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::Wisdom::KnowledgeBase.RenderingConfiguration": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-renderingconfiguration.html",
+      "Properties": {
+        "TemplateUri": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-renderingconfiguration.html#cfn-wisdom-knowledgebase-renderingconfiguration-templateuri",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::Wisdom::KnowledgeBase.ServerSideEncryptionConfiguration": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-serversideencryptionconfiguration.html",
+      "Properties": {
+        "KmsKeyId": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-serversideencryptionconfiguration.html#cfn-wisdom-knowledgebase-serversideencryptionconfiguration-kmskeyid",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::Wisdom::KnowledgeBase.SourceConfiguration": {
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-sourceconfiguration.html",
+      "Properties": {
+        "AppIntegrations": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-sourceconfiguration.html#cfn-wisdom-knowledgebase-sourceconfiguration-appintegrations",
+          "Required": false,
+          "Type": "AppIntegrationsConfiguration",
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::WorkSpaces::ConnectionAlias.ConnectionAliasAssociation": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-workspaces-connectionalias-connectionaliasassociation.html",
       "Properties": {
@@ -63503,7 +65160,7 @@
       }
     }
   },
-  "ResourceSpecificationVersion": "43.0.0",
+  "ResourceSpecificationVersion": "46.0.0",
   "ResourceTypes": {
     "AWS::ACMPCA::Certificate": {
       "Attributes": {
@@ -64373,6 +66030,11 @@
       }
     },
     "AWS::ApiGateway::Authorizer": {
+      "Attributes": {
+        "AuthorizerId": {
+          "PrimitiveType": "String"
+        }
+      },
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-authorizer.html",
       "Properties": {
         "AuthType": {
@@ -64414,7 +66076,7 @@
         "Name": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-authorizer.html#cfn-apigateway-authorizer-name",
           "PrimitiveType": "String",
-          "Required": false,
+          "Required": true,
           "UpdateType": "Mutable"
         },
         "ProviderARNs": {
@@ -65165,6 +66827,13 @@
           "Required": true,
           "UpdateType": "Mutable"
         },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-vpclink.html#cfn-apigateway-vpclink-tags",
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
         "TargetArns": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-vpclink.html#cfn-apigateway-vpclink-targetarns",
           "PrimitiveItemType": "String",
@@ -68042,6 +69711,12 @@
           "Required": false,
           "UpdateType": "Mutable"
         },
+        "DesiredCapacityType": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-group.html#cfn-as-group-desiredcapacitytype",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "HealthCheckGracePeriod": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-group.html#cfn-as-group-healthcheckgraceperiod",
           "PrimitiveType": "Integer",
@@ -68306,52 +69981,52 @@
       }
     },
     "AWS::AutoScaling::LifecycleHook": {
-      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html",
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html",
       "Properties": {
         "AutoScalingGroupName": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-autoscalinggroupname",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-autoscalinggroupname",
           "PrimitiveType": "String",
           "Required": true,
           "UpdateType": "Immutable"
         },
         "DefaultResult": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-defaultresult",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-defaultresult",
           "PrimitiveType": "String",
           "Required": false,
           "UpdateType": "Mutable"
         },
         "HeartbeatTimeout": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-heartbeattimeout",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-heartbeattimeout",
           "PrimitiveType": "Integer",
           "Required": false,
           "UpdateType": "Mutable"
         },
         "LifecycleHookName": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-autoscaling-lifecyclehook-lifecyclehookname",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-lifecyclehookname",
           "PrimitiveType": "String",
           "Required": false,
           "UpdateType": "Immutable"
         },
         "LifecycleTransition": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-lifecycletransition",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-lifecycletransition",
           "PrimitiveType": "String",
           "Required": true,
           "UpdateType": "Mutable"
         },
         "NotificationMetadata": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-notificationmetadata",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-notificationmetadata",
           "PrimitiveType": "String",
           "Required": false,
           "UpdateType": "Mutable"
         },
         "NotificationTargetARN": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-notificationtargetarn",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-notificationtargetarn",
           "PrimitiveType": "String",
           "Required": false,
           "UpdateType": "Mutable"
         },
         "RoleARN": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-rolearn",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-rolearn",
           "PrimitiveType": "String",
           "Required": false,
           "UpdateType": "Mutable"
@@ -68771,6 +70446,12 @@
           "PrimitiveType": "String",
           "Required": true,
           "UpdateType": "Immutable"
+        },
+        "UnmanagedvCpus": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-batch-computeenvironment.html#cfn-batch-computeenvironment-unmanagedvcpus",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
         }
       }
     },
@@ -68820,6 +70501,12 @@
           "Type": "RetryStrategy",
           "UpdateType": "Mutable"
         },
+        "SchedulingPriority": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-batch-jobdefinition.html#cfn-batch-jobdefinition-schedulingpriority",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "Tags": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-batch-jobdefinition.html#cfn-batch-jobdefinition-tags",
           "PrimitiveType": "Json",
@@ -68862,6 +70549,12 @@
           "Required": true,
           "UpdateType": "Mutable"
         },
+        "SchedulingPolicyArn": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-batch-jobqueue.html#cfn-batch-jobqueue-schedulingpolicyarn",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "State": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-batch-jobqueue.html#cfn-batch-jobqueue-state",
           "PrimitiveType": "String",
@@ -68947,7 +70640,7 @@
         "Subscribers": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-budgets-budgetsaction.html#cfn-budgets-budgetsaction-subscribers",
           "ItemType": "Subscriber",
-          "Required": false,
+          "Required": true,
           "Type": "List",
           "UpdateType": "Mutable"
         }
@@ -69202,6 +70895,12 @@
           "Type": "List",
           "UpdateType": "Immutable"
         },
+        "DefaultTimeToLive": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cassandra-table.html#cfn-cassandra-table-defaulttimetolive",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "EncryptionSpecification": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cassandra-table.html#cfn-cassandra-table-encryptionspecification",
           "Required": false,
@@ -71591,12 +73290,24 @@
       },
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html",
       "Properties": {
+        "CreatedBy": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html#cfn-codestarnotifications-notificationrule-createdby",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "DetailType": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html#cfn-codestarnotifications-notificationrule-detailtype",
           "PrimitiveType": "String",
           "Required": true,
           "UpdateType": "Mutable"
         },
+        "EventTypeId": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html#cfn-codestarnotifications-notificationrule-eventtypeid",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "EventTypeIds": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html#cfn-codestarnotifications-notificationrule-eventtypeids",
           "DuplicatesAllowed": true,
@@ -71629,6 +73340,12 @@
           "Required": false,
           "UpdateType": "Immutable"
         },
+        "TargetAddress": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html#cfn-codestarnotifications-notificationrule-targetaddress",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "Targets": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html#cfn-codestarnotifications-notificationrule-targets",
           "DuplicatesAllowed": true,
@@ -72711,6 +74428,56 @@
         }
       }
     },
+    "AWS::Connect::HoursOfOperation": {
+      "Attributes": {
+        "HoursOfOperationArn": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html",
+      "Properties": {
+        "Config": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html#cfn-connect-hoursofoperation-config",
+          "DuplicatesAllowed": false,
+          "ItemType": "HoursOfOperationConfig",
+          "Required": true,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "Description": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html#cfn-connect-hoursofoperation-description",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "InstanceArn": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html#cfn-connect-hoursofoperation-instancearn",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Mutable"
+        },
+        "Name": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html#cfn-connect-hoursofoperation-name",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Mutable"
+        },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html#cfn-connect-hoursofoperation-tags",
+          "DuplicatesAllowed": false,
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "TimeZone": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html#cfn-connect-hoursofoperation-timezone",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::Connect::QuickConnect": {
       "Attributes": {
         "QuickConnectArn": {
@@ -72753,6 +74520,108 @@
         }
       }
     },
+    "AWS::Connect::User": {
+      "Attributes": {
+        "UserArn": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html",
+      "Properties": {
+        "DirectoryUserId": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-directoryuserid",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "HierarchyGroupArn": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-hierarchygrouparn",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "IdentityInfo": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-identityinfo",
+          "Required": false,
+          "Type": "UserIdentityInfo",
+          "UpdateType": "Mutable"
+        },
+        "InstanceArn": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-instancearn",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Mutable"
+        },
+        "Password": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-password",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "PhoneConfig": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-phoneconfig",
+          "Required": true,
+          "Type": "UserPhoneConfig",
+          "UpdateType": "Mutable"
+        },
+        "RoutingProfileArn": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-routingprofilearn",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Mutable"
+        },
+        "SecurityProfileArns": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-securityprofilearns",
+          "DuplicatesAllowed": false,
+          "PrimitiveItemType": "String",
+          "Required": true,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-tags",
+          "DuplicatesAllowed": false,
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "Username": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-username",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::Connect::UserHierarchyGroup": {
+      "Attributes": {
+        "UserHierarchyGroupArn": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-userhierarchygroup.html",
+      "Properties": {
+        "InstanceArn": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-userhierarchygroup.html#cfn-connect-userhierarchygroup-instancearn",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Mutable"
+        },
+        "Name": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-userhierarchygroup.html#cfn-connect-userhierarchygroup-name",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Mutable"
+        },
+        "ParentGroupArn": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-userhierarchygroup.html#cfn-connect-userhierarchygroup-parentgrouparn",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::CustomerProfiles::Domain": {
       "Attributes": {
         "CreatedAt": {
@@ -75121,6 +76990,74 @@
         }
       }
     },
+    "AWS::EC2::CapacityReservationFleet": {
+      "Attributes": {
+        "CapacityReservationFleetId": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html",
+      "Properties": {
+        "AllocationStrategy": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-allocationstrategy",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "EndDate": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-enddate",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "InstanceMatchCriteria": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-instancematchcriteria",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "InstanceTypeSpecifications": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-instancetypespecifications",
+          "DuplicatesAllowed": false,
+          "ItemType": "InstanceTypeSpecification",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "NoRemoveEndDate": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-noremoveenddate",
+          "PrimitiveType": "Boolean",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "RemoveEndDate": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-removeenddate",
+          "PrimitiveType": "Boolean",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "TagSpecifications": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-tagspecifications",
+          "DuplicatesAllowed": true,
+          "ItemType": "TagSpecification",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "Tenancy": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-tenancy",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "TotalTargetCapacity": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-totaltargetcapacity",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::EC2::CarrierGateway": {
       "Attributes": {
         "CarrierGatewayId": {
@@ -76150,10 +78087,15 @@
       }
     },
     "AWS::EC2::NetworkAcl": {
-      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html",
+      "Attributes": {
+        "Id": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkacl.html",
       "Properties": {
         "Tags": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html#cfn-ec2-networkacl-tags",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkacl.html#cfn-ec2-networkacl-tags",
           "DuplicatesAllowed": true,
           "ItemType": "Tag",
           "Required": false,
@@ -76161,7 +78103,7 @@
           "UpdateType": "Mutable"
         },
         "VpcId": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html#cfn-ec2-networkacl-vpcid",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkacl.html#cfn-ec2-networkacl-vpcid",
           "PrimitiveType": "String",
           "Required": true,
           "UpdateType": "Immutable"
@@ -76169,58 +78111,63 @@
       }
     },
     "AWS::EC2::NetworkAclEntry": {
-      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html",
+      "Attributes": {
+        "Id": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html",
       "Properties": {
         "CidrBlock": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-cidrblock",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-cidrblock",
           "PrimitiveType": "String",
           "Required": false,
           "UpdateType": "Mutable"
         },
         "Egress": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-egress",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-egress",
           "PrimitiveType": "Boolean",
           "Required": false,
           "UpdateType": "Immutable"
         },
         "Icmp": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-icmp",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-icmp",
           "Required": false,
           "Type": "Icmp",
           "UpdateType": "Mutable"
         },
         "Ipv6CidrBlock": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-ipv6cidrblock",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-ipv6cidrblock",
           "PrimitiveType": "String",
           "Required": false,
           "UpdateType": "Mutable"
         },
         "NetworkAclId": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-networkaclid",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-networkaclid",
           "PrimitiveType": "String",
           "Required": true,
           "UpdateType": "Immutable"
         },
         "PortRange": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-portrange",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-portrange",
           "Required": false,
           "Type": "PortRange",
           "UpdateType": "Mutable"
         },
         "Protocol": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-protocol",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-protocol",
           "PrimitiveType": "Integer",
           "Required": true,
           "UpdateType": "Mutable"
         },
         "RuleAction": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-ruleaction",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-ruleaction",
           "PrimitiveType": "String",
           "Required": true,
           "UpdateType": "Mutable"
         },
         "RuleNumber": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-rulenumber",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-rulenumber",
           "PrimitiveType": "Integer",
           "Required": true,
           "UpdateType": "Immutable"
@@ -76633,10 +78580,15 @@
       }
     },
     "AWS::EC2::RouteTable": {
-      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html",
+      "Attributes": {
+        "RouteTableId": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html",
       "Properties": {
         "Tags": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html#cfn-ec2-routetable-tags",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html#cfn-ec2-routetable-tags",
           "DuplicatesAllowed": true,
           "ItemType": "Tag",
           "Required": false,
@@ -76644,7 +78596,7 @@
           "UpdateType": "Mutable"
         },
         "VpcId": {
-          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html#cfn-ec2-routetable-vpcid",
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html#cfn-ec2-routetable-vpcid",
           "PrimitiveType": "String",
           "Required": true,
           "UpdateType": "Immutable"
@@ -78693,6 +80645,12 @@
           "Type": "List",
           "UpdateType": "Immutable"
         },
+        "RuntimePlatform": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html#cfn-ecs-taskdefinition-runtimeplatform",
+          "Required": false,
+          "Type": "RuntimePlatform",
+          "UpdateType": "Immutable"
+        },
         "Tags": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html#cfn-ecs-taskdefinition-tags",
           "ItemType": "Tag",
@@ -81713,6 +83671,12 @@
           "Type": "List",
           "UpdateType": "Mutable"
         },
+        "ResourcesCleanUp": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-fms-policy.html#cfn-fms-policy-resourcescleanup",
+          "PrimitiveType": "Boolean",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "SecurityServicePolicyData": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-fms-policy.html#cfn-fms-policy-securityservicepolicydata",
           "PrimitiveType": "Json",
@@ -83325,7 +85289,7 @@
           "ItemType": "Tag",
           "Required": false,
           "Type": "List",
-          "UpdateType": "Immutable"
+          "UpdateType": "Mutable"
         }
       }
     },
@@ -83387,7 +85351,7 @@
           "ItemType": "Tag",
           "Required": false,
           "Type": "List",
-          "UpdateType": "Immutable"
+          "UpdateType": "Mutable"
         }
       }
     },
@@ -85586,6 +87550,12 @@
           "Required": false,
           "UpdateType": "Mutable"
         },
+        "InstanceMetadataOptions": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-instancemetadataoptions",
+          "Required": false,
+          "Type": "InstanceMetadataOptions",
+          "UpdateType": "Mutable"
+        },
         "InstanceProfileName": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-instanceprofilename",
           "PrimitiveType": "String",
@@ -86183,6 +88153,78 @@
         }
       }
     },
+    "AWS::IoT::JobTemplate": {
+      "Attributes": {
+        "Arn": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html",
+      "Properties": {
+        "AbortConfig": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-abortconfig",
+          "PrimitiveType": "Json",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Description": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-description",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "Document": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-document",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "DocumentSource": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-documentsource",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "JobArn": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-jobarn",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "JobExecutionsRolloutConfig": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-jobexecutionsrolloutconfig",
+          "PrimitiveType": "Json",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "JobTemplateId": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-jobtemplateid",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "PresignedUrlConfig": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-presignedurlconfig",
+          "PrimitiveType": "Json",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-tags",
+          "DuplicatesAllowed": false,
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "TimeoutConfig": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-timeoutconfig",
+          "PrimitiveType": "Json",
+          "Required": false,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::IoT::MitigationAction": {
       "Attributes": {
         "MitigationActionArn": {
@@ -88957,6 +90999,110 @@
         }
       }
     },
+    "AWS::Lightsail::Database": {
+      "Attributes": {
+        "DatabaseArn": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html",
+      "Properties": {
+        "AvailabilityZone": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-availabilityzone",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "BackupRetention": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-backupretention",
+          "PrimitiveType": "Boolean",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "CaCertificateIdentifier": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-cacertificateidentifier",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "MasterDatabaseName": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-masterdatabasename",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "MasterUserPassword": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-masteruserpassword",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "MasterUsername": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-masterusername",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "PreferredBackupWindow": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-preferredbackupwindow",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "PreferredMaintenanceWindow": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-preferredmaintenancewindow",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "PubliclyAccessible": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-publiclyaccessible",
+          "PrimitiveType": "Boolean",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "RelationalDatabaseBlueprintId": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-relationaldatabaseblueprintid",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "RelationalDatabaseBundleId": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-relationaldatabasebundleid",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "RelationalDatabaseName": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-relationaldatabasename",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "RelationalDatabaseParameters": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-relationaldatabaseparameters",
+          "DuplicatesAllowed": false,
+          "ItemType": "RelationalDatabaseParameter",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        },
+        "RotateMasterUserPassword": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-rotatemasteruserpassword",
+          "PrimitiveType": "Boolean",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-tags",
+          "DuplicatesAllowed": false,
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::Lightsail::Disk": {
       "Attributes": {
         "AttachedTo": {
@@ -89038,9 +91184,6 @@
         "IsStaticIp": {
           "PrimitiveType": "Boolean"
         },
-        "KeyPairName": {
-          "PrimitiveType": "String"
-        },
         "Location.AvailabilityZone": {
           "PrimitiveType": "String"
         },
@@ -89071,9 +91214,6 @@
         "SupportCode": {
           "PrimitiveType": "String"
         },
-        "UserData": {
-          "PrimitiveType": "String"
-        },
         "UserName": {
           "PrimitiveType": "String"
         }
@@ -89117,6 +91257,12 @@
           "Required": true,
           "UpdateType": "Immutable"
         },
+        "KeyPairName": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-instance.html#cfn-lightsail-instance-keypairname",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "Location": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-instance.html#cfn-lightsail-instance-location",
           "Required": false,
@@ -89142,6 +91288,40 @@
           "Required": false,
           "Type": "List",
           "UpdateType": "Mutable"
+        },
+        "UserData": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-instance.html#cfn-lightsail-instance-userdata",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::Lightsail::StaticIp": {
+      "Attributes": {
+        "IpAddress": {
+          "PrimitiveType": "String"
+        },
+        "IsAttached": {
+          "PrimitiveType": "Boolean"
+        },
+        "StaticIpArn": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-staticip.html",
+      "Properties": {
+        "AttachedTo": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-staticip.html#cfn-lightsail-staticip-attachedto",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "StaticIpName": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-staticip.html#cfn-lightsail-staticip-staticipname",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
         }
       }
     },
@@ -89361,6 +91541,12 @@
           "Required": false,
           "UpdateType": "Immutable"
         },
+        "PositionFiltering": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-location-tracker.html#cfn-location-tracker-positionfiltering",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
         "PricingPlan": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-location-tracker.html#cfn-location-tracker-pricingplan",
           "PrimitiveType": "String",
@@ -89941,8 +92127,8 @@
         },
         "Tags": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-mwaa-environment.html#cfn-mwaa-environment-tags",
+          "PrimitiveType": "Json",
           "Required": false,
-          "Type": "TagMap",
           "UpdateType": "Mutable"
         },
         "WebserverAccessMode": {
@@ -91230,7 +93416,7 @@
         "ACLName": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-memorydb-cluster.html#cfn-memorydb-cluster-aclname",
           "PrimitiveType": "String",
-          "Required": false,
+          "Required": true,
           "UpdateType": "Mutable"
         },
         "AutoMinorVersionUpgrade": {
@@ -91284,7 +93470,7 @@
         "NodeType": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-memorydb-cluster.html#cfn-memorydb-cluster-nodetype",
           "PrimitiveType": "String",
-          "Required": false,
+          "Required": true,
           "UpdateType": "Mutable"
         },
         "NumReplicasPerShard": {
@@ -91396,7 +93582,7 @@
         "Family": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-memorydb-parametergroup.html#cfn-memorydb-parametergroup-family",
           "PrimitiveType": "String",
-          "Required": false,
+          "Required": true,
           "UpdateType": "Immutable"
         },
         "ParameterGroupName": {
@@ -91445,7 +93631,7 @@
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-memorydb-subnetgroup.html#cfn-memorydb-subnetgroup-subnetids",
           "DuplicatesAllowed": false,
           "PrimitiveItemType": "String",
-          "Required": false,
+          "Required": true,
           "Type": "List",
           "UpdateType": "Mutable"
         },
@@ -93403,6 +95589,190 @@
         }
       }
     },
+    "AWS::Panorama::ApplicationInstance": {
+      "Attributes": {
+        "ApplicationInstanceId": {
+          "PrimitiveType": "String"
+        },
+        "Arn": {
+          "PrimitiveType": "String"
+        },
+        "CreatedTime": {
+          "PrimitiveType": "Integer"
+        },
+        "DefaultRuntimeContextDeviceName": {
+          "PrimitiveType": "String"
+        },
+        "HealthStatus": {
+          "PrimitiveType": "String"
+        },
+        "LastUpdatedTime": {
+          "PrimitiveType": "Integer"
+        },
+        "Status": {
+          "PrimitiveType": "String"
+        },
+        "StatusDescription": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html",
+      "Properties": {
+        "ApplicationInstanceIdToReplace": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-applicationinstanceidtoreplace",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "DefaultRuntimeContextDevice": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-defaultruntimecontextdevice",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "Description": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-description",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "DeviceId": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-deviceid",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "ManifestOverridesPayload": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-manifestoverridespayload",
+          "Required": false,
+          "Type": "ManifestOverridesPayload",
+          "UpdateType": "Immutable"
+        },
+        "ManifestPayload": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-manifestpayload",
+          "Required": true,
+          "Type": "ManifestPayload",
+          "UpdateType": "Immutable"
+        },
+        "Name": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-name",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "RuntimeRoleArn": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-runtimerolearn",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "StatusFilter": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-statusfilter",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-tags",
+          "DuplicatesAllowed": false,
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::Panorama::Package": {
+      "Attributes": {
+        "Arn": {
+          "PrimitiveType": "String"
+        },
+        "CreatedTime": {
+          "PrimitiveType": "Integer"
+        },
+        "PackageId": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-package.html",
+      "Properties": {
+        "PackageName": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-package.html#cfn-panorama-package-packagename",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-package.html#cfn-panorama-package-tags",
+          "DuplicatesAllowed": false,
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Mutable"
+        }
+      }
+    },
+    "AWS::Panorama::PackageVersion": {
+      "Attributes": {
+        "IsLatestPatch": {
+          "PrimitiveType": "Boolean"
+        },
+        "PackageArn": {
+          "PrimitiveType": "String"
+        },
+        "PackageName": {
+          "PrimitiveType": "String"
+        },
+        "RegisteredTime": {
+          "PrimitiveType": "Integer"
+        },
+        "Status": {
+          "PrimitiveType": "String"
+        },
+        "StatusDescription": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html",
+      "Properties": {
+        "MarkLatest": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html#cfn-panorama-packageversion-marklatest",
+          "PrimitiveType": "Boolean",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
+        "OwnerAccount": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html#cfn-panorama-packageversion-owneraccount",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "PackageId": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html#cfn-panorama-packageversion-packageid",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "PackageVersion": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html#cfn-panorama-packageversion-packageversion",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "PatchVersion": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html#cfn-panorama-packageversion-patchversion",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "UpdatedLatestPatchVersion": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html#cfn-panorama-packageversion-updatedlatestpatchversion",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Mutable"
+        }
+      }
+    },
     "AWS::Pinpoint::ADMChannel": {
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-admchannel.html",
       "Properties": {
@@ -93820,6 +96190,12 @@
           "Required": true,
           "UpdateType": "Mutable"
         },
+        "Priority": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-campaign.html#cfn-pinpoint-campaign-priority",
+          "PrimitiveType": "Integer",
+          "Required": false,
+          "UpdateType": "Mutable"
+        },
         "Schedule": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-campaign.html#cfn-pinpoint-campaign-schedule",
           "Required": true,
@@ -94487,7 +96863,7 @@
         },
         "SourceEntity": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-quicksight-analysis.html#cfn-quicksight-analysis-sourceentity",
-          "Required": false,
+          "Required": true,
           "Type": "AnalysisSourceEntity",
           "UpdateType": "Mutable"
         },
@@ -94562,7 +96938,7 @@
         },
         "SourceEntity": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-quicksight-dashboard.html#cfn-quicksight-dashboard-sourceentity",
-          "Required": false,
+          "Required": true,
           "Type": "DashboardSourceEntity",
           "UpdateType": "Mutable"
         },
@@ -94824,7 +97200,7 @@
         },
         "SourceEntity": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-quicksight-template.html#cfn-quicksight-template-sourceentity",
-          "Required": false,
+          "Required": true,
           "Type": "TemplateSourceEntity",
           "UpdateType": "Mutable"
         },
@@ -96416,6 +98792,22 @@
         }
       }
     },
+    "AWS::Rekognition::Project": {
+      "Attributes": {
+        "Arn": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rekognition-project.html",
+      "Properties": {
+        "ProjectName": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rekognition-project.html#cfn-rekognition-project-projectname",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::ResourceGroups::Group": {
       "Attributes": {
         "Arn": {
@@ -96947,6 +99339,13 @@
           "PrimitiveType": "String",
           "Required": false,
           "UpdateType": "Immutable"
+        },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-cluster.html#cfn-route53recoverycontrol-cluster-tags",
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
         }
       }
     },
@@ -96978,6 +99377,13 @@
           "PrimitiveType": "String",
           "Required": true,
           "UpdateType": "Mutable"
+        },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-controlpanel.html#cfn-route53recoverycontrol-controlpanel-tags",
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
         }
       }
     },
@@ -97052,6 +99458,13 @@
           "Required": true,
           "Type": "RuleConfig",
           "UpdateType": "Immutable"
+        },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-safetyrule.html#cfn-route53recoverycontrol-safetyrule-tags",
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
         }
       }
     },
@@ -97374,6 +99787,34 @@
         }
       }
     },
+    "AWS::Route53Resolver::ResolverConfig": {
+      "Attributes": {
+        "AutodefinedReverse": {
+          "PrimitiveType": "String"
+        },
+        "Id": {
+          "PrimitiveType": "String"
+        },
+        "OwnerId": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53resolver-resolverconfig.html",
+      "Properties": {
+        "AutodefinedReverseFlag": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53resolver-resolverconfig.html#cfn-route53resolver-resolverconfig-autodefinedreverseflag",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "ResourceId": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53resolver-resolverconfig.html#cfn-route53resolver-resolverconfig-resourceid",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::Route53Resolver::ResolverDNSSECConfig": {
       "Attributes": {
         "Id": {
@@ -97549,7 +99990,9 @@
           "PrimitiveType": "String"
         },
         "TargetIps": {
-          "PrimitiveType": "String"
+          "DuplicatesAllowed": true,
+          "ItemType": "TargetAddress",
+          "Type": "List"
         }
       },
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53resolver-resolverrule.html",
@@ -97580,6 +100023,7 @@
         },
         "Tags": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53resolver-resolverrule.html#cfn-route53resolver-resolverrule-tags",
+          "DuplicatesAllowed": true,
           "ItemType": "Tag",
           "Required": false,
           "Type": "List",
@@ -97587,6 +100031,7 @@
         },
         "TargetIps": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53resolver-resolverrule.html#cfn-route53resolver-resolverrule-targetips",
+          "DuplicatesAllowed": true,
           "ItemType": "TargetAddress",
           "Required": false,
           "Type": "List",
@@ -100361,6 +102806,12 @@
           "Required": false,
           "UpdateType": "Immutable"
         },
+        "PlatformIdentifier": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-notebookinstance.html#cfn-sagemaker-notebookinstance-platformidentifier",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
         "RoleArn": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-notebookinstance.html#cfn-sagemaker-notebookinstance-rolearn",
           "PrimitiveType": "String",
@@ -101785,6 +104236,9 @@
     },
     "AWS::StepFunctions::Activity": {
       "Attributes": {
+        "Arn": {
+          "PrimitiveType": "String"
+        },
         "Name": {
           "PrimitiveType": "String"
         }
@@ -101799,6 +104253,7 @@
         },
         "Tags": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-activity.html#cfn-stepfunctions-activity-tags",
+          "DuplicatesAllowed": true,
           "ItemType": "TagsEntry",
           "Required": false,
           "Type": "List",
@@ -101893,6 +104348,12 @@
       },
       "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-synthetics-canary.html",
       "Properties": {
+        "ArtifactConfig": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-synthetics-canary.html#cfn-synthetics-canary-artifactconfig",
+          "Required": false,
+          "Type": "ArtifactConfig",
+          "UpdateType": "Mutable"
+        },
         "ArtifactS3Location": {
           "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-synthetics-canary.html#cfn-synthetics-canary-artifacts3location",
           "PrimitiveType": "String",
@@ -102886,6 +105347,150 @@
         }
       }
     },
+    "AWS::Wisdom::Assistant": {
+      "Attributes": {
+        "AssistantArn": {
+          "PrimitiveType": "String"
+        },
+        "AssistantId": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistant.html",
+      "Properties": {
+        "Description": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistant.html#cfn-wisdom-assistant-description",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "Name": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistant.html#cfn-wisdom-assistant-name",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "ServerSideEncryptionConfiguration": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistant.html#cfn-wisdom-assistant-serversideencryptionconfiguration",
+          "Required": false,
+          "Type": "ServerSideEncryptionConfiguration",
+          "UpdateType": "Immutable"
+        },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistant.html#cfn-wisdom-assistant-tags",
+          "DuplicatesAllowed": false,
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        },
+        "Type": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistant.html#cfn-wisdom-assistant-type",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::Wisdom::AssistantAssociation": {
+      "Attributes": {
+        "AssistantArn": {
+          "PrimitiveType": "String"
+        },
+        "AssistantAssociationArn": {
+          "PrimitiveType": "String"
+        },
+        "AssistantAssociationId": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistantassociation.html",
+      "Properties": {
+        "AssistantId": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistantassociation.html#cfn-wisdom-assistantassociation-assistantid",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "Association": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistantassociation.html#cfn-wisdom-assistantassociation-association",
+          "Required": true,
+          "Type": "AssociationData",
+          "UpdateType": "Immutable"
+        },
+        "AssociationType": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistantassociation.html#cfn-wisdom-assistantassociation-associationtype",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistantassociation.html#cfn-wisdom-assistantassociation-tags",
+          "DuplicatesAllowed": false,
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        }
+      }
+    },
+    "AWS::Wisdom::KnowledgeBase": {
+      "Attributes": {
+        "KnowledgeBaseArn": {
+          "PrimitiveType": "String"
+        },
+        "KnowledgeBaseId": {
+          "PrimitiveType": "String"
+        }
+      },
+      "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html",
+      "Properties": {
+        "Description": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-description",
+          "PrimitiveType": "String",
+          "Required": false,
+          "UpdateType": "Immutable"
+        },
+        "KnowledgeBaseType": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-knowledgebasetype",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "Name": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-name",
+          "PrimitiveType": "String",
+          "Required": true,
+          "UpdateType": "Immutable"
+        },
+        "RenderingConfiguration": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-renderingconfiguration",
+          "Required": false,
+          "Type": "RenderingConfiguration",
+          "UpdateType": "Mutable"
+        },
+        "ServerSideEncryptionConfiguration": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-serversideencryptionconfiguration",
+          "Required": false,
+          "Type": "ServerSideEncryptionConfiguration",
+          "UpdateType": "Immutable"
+        },
+        "SourceConfiguration": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-sourceconfiguration",
+          "Required": false,
+          "Type": "SourceConfiguration",
+          "UpdateType": "Immutable"
+        },
+        "Tags": {
+          "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-tags",
+          "DuplicatesAllowed": false,
+          "ItemType": "Tag",
+          "Required": false,
+          "Type": "List",
+          "UpdateType": "Immutable"
+        }
+      }
+    },
     "AWS::WorkSpaces::ConnectionAlias": {
       "Attributes": {
         "AliasId": {
diff --git a/packages/@aws-cdk/cfnspec/spec-source/cfn-lint/StatefulResources/000.json b/packages/@aws-cdk/cfnspec/spec-source/cfn-lint/StatefulResources/000.json
index 7037f14238497..dbfa3dfcdd033 100644
--- a/packages/@aws-cdk/cfnspec/spec-source/cfn-lint/StatefulResources/000.json
+++ b/packages/@aws-cdk/cfnspec/spec-source/cfn-lint/StatefulResources/000.json
@@ -25,6 +25,7 @@
     "AWS::SQS::Queue" : {},
     "AWS::S3::Bucket" : {
       "DeleteRequiresEmptyResource": true
-    }
+    },
+    "AWS::SecretsManager::Secret" : {}
   }
 }
diff --git a/packages/@aws-cdk/cloudformation-include/package.json b/packages/@aws-cdk/cloudformation-include/package.json
index 28e63ecaed94c..c78117ba94df0 100644
--- a/packages/@aws-cdk/cloudformation-include/package.json
+++ b/packages/@aws-cdk/cloudformation-include/package.json
@@ -195,6 +195,7 @@
     "@aws-cdk/aws-opensearchservice": "0.0.0",
     "@aws-cdk/aws-opsworks": "0.0.0",
     "@aws-cdk/aws-opsworkscm": "0.0.0",
+    "@aws-cdk/aws-panorama": "0.0.0",
     "@aws-cdk/aws-pinpoint": "0.0.0",
     "@aws-cdk/aws-pinpointemail": "0.0.0",
     "@aws-cdk/aws-qldb": "0.0.0",
@@ -202,6 +203,7 @@
     "@aws-cdk/aws-ram": "0.0.0",
     "@aws-cdk/aws-rds": "0.0.0",
     "@aws-cdk/aws-redshift": "0.0.0",
+    "@aws-cdk/aws-rekognition": "0.0.0",
     "@aws-cdk/aws-resourcegroups": "0.0.0",
     "@aws-cdk/aws-robomaker": "0.0.0",
     "@aws-cdk/aws-route53": "0.0.0",
@@ -234,6 +236,7 @@
     "@aws-cdk/aws-waf": "0.0.0",
     "@aws-cdk/aws-wafregional": "0.0.0",
     "@aws-cdk/aws-wafv2": "0.0.0",
+    "@aws-cdk/aws-wisdom": "0.0.0",
     "@aws-cdk/aws-workspaces": "0.0.0",
     "@aws-cdk/aws-xray": "0.0.0",
     "@aws-cdk/core": "0.0.0",
@@ -370,6 +373,7 @@
     "@aws-cdk/aws-opensearchservice": "0.0.0",
     "@aws-cdk/aws-opsworks": "0.0.0",
     "@aws-cdk/aws-opsworkscm": "0.0.0",
+    "@aws-cdk/aws-panorama": "0.0.0",
     "@aws-cdk/aws-pinpoint": "0.0.0",
     "@aws-cdk/aws-pinpointemail": "0.0.0",
     "@aws-cdk/aws-qldb": "0.0.0",
@@ -377,6 +381,7 @@
     "@aws-cdk/aws-ram": "0.0.0",
     "@aws-cdk/aws-rds": "0.0.0",
     "@aws-cdk/aws-redshift": "0.0.0",
+    "@aws-cdk/aws-rekognition": "0.0.0",
     "@aws-cdk/aws-resourcegroups": "0.0.0",
     "@aws-cdk/aws-robomaker": "0.0.0",
     "@aws-cdk/aws-route53": "0.0.0",
@@ -409,6 +414,7 @@
     "@aws-cdk/aws-waf": "0.0.0",
     "@aws-cdk/aws-wafregional": "0.0.0",
     "@aws-cdk/aws-wafv2": "0.0.0",
+    "@aws-cdk/aws-wisdom": "0.0.0",
     "@aws-cdk/aws-workspaces": "0.0.0",
     "@aws-cdk/aws-xray": "0.0.0",
     "@aws-cdk/core": "0.0.0",
diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json
index 1d2d0c73daa50..3e8a5932ffcc1 100644
--- a/packages/aws-cdk-lib/package.json
+++ b/packages/aws-cdk-lib/package.json
@@ -280,6 +280,7 @@
     "@aws-cdk/aws-opensearchservice": "0.0.0",
     "@aws-cdk/aws-opsworks": "0.0.0",
     "@aws-cdk/aws-opsworkscm": "0.0.0",
+    "@aws-cdk/aws-panorama": "0.0.0",
     "@aws-cdk/aws-pinpoint": "0.0.0",
     "@aws-cdk/aws-pinpointemail": "0.0.0",
     "@aws-cdk/aws-qldb": "0.0.0",
@@ -287,6 +288,7 @@
     "@aws-cdk/aws-ram": "0.0.0",
     "@aws-cdk/aws-rds": "0.0.0",
     "@aws-cdk/aws-redshift": "0.0.0",
+    "@aws-cdk/aws-rekognition": "0.0.0",
     "@aws-cdk/aws-resourcegroups": "0.0.0",
     "@aws-cdk/aws-robomaker": "0.0.0",
     "@aws-cdk/aws-route53": "0.0.0",
@@ -327,6 +329,7 @@
     "@aws-cdk/aws-waf": "0.0.0",
     "@aws-cdk/aws-wafregional": "0.0.0",
     "@aws-cdk/aws-wafv2": "0.0.0",
+    "@aws-cdk/aws-wisdom": "0.0.0",
     "@aws-cdk/aws-workspaces": "0.0.0",
     "@aws-cdk/aws-xray": "0.0.0",
     "@aws-cdk/cdk-build-tools": "0.0.0",
diff --git a/packages/decdk/package.json b/packages/decdk/package.json
index 3d181528f325e..5867570ec77f1 100644
--- a/packages/decdk/package.json
+++ b/packages/decdk/package.json
@@ -183,6 +183,7 @@
     "@aws-cdk/aws-opensearchservice": "0.0.0",
     "@aws-cdk/aws-opsworks": "0.0.0",
     "@aws-cdk/aws-opsworkscm": "0.0.0",
+    "@aws-cdk/aws-panorama": "0.0.0",
     "@aws-cdk/aws-pinpoint": "0.0.0",
     "@aws-cdk/aws-pinpointemail": "0.0.0",
     "@aws-cdk/aws-qldb": "0.0.0",
@@ -190,6 +191,7 @@
     "@aws-cdk/aws-ram": "0.0.0",
     "@aws-cdk/aws-rds": "0.0.0",
     "@aws-cdk/aws-redshift": "0.0.0",
+    "@aws-cdk/aws-rekognition": "0.0.0",
     "@aws-cdk/aws-resourcegroups": "0.0.0",
     "@aws-cdk/aws-robomaker": "0.0.0",
     "@aws-cdk/aws-route53": "0.0.0",
@@ -230,6 +232,7 @@
     "@aws-cdk/aws-waf": "0.0.0",
     "@aws-cdk/aws-wafregional": "0.0.0",
     "@aws-cdk/aws-wafv2": "0.0.0",
+    "@aws-cdk/aws-wisdom": "0.0.0",
     "@aws-cdk/aws-workspaces": "0.0.0",
     "@aws-cdk/aws-xray": "0.0.0",
     "@aws-cdk/cfnspec": "0.0.0",
diff --git a/packages/monocdk/package.json b/packages/monocdk/package.json
index 49e11473c6be6..1f2e65a012070 100644
--- a/packages/monocdk/package.json
+++ b/packages/monocdk/package.json
@@ -277,6 +277,7 @@
     "@aws-cdk/aws-opensearchservice": "0.0.0",
     "@aws-cdk/aws-opsworks": "0.0.0",
     "@aws-cdk/aws-opsworkscm": "0.0.0",
+    "@aws-cdk/aws-panorama": "0.0.0",
     "@aws-cdk/aws-pinpoint": "0.0.0",
     "@aws-cdk/aws-pinpointemail": "0.0.0",
     "@aws-cdk/aws-qldb": "0.0.0",
@@ -284,6 +285,7 @@
     "@aws-cdk/aws-ram": "0.0.0",
     "@aws-cdk/aws-rds": "0.0.0",
     "@aws-cdk/aws-redshift": "0.0.0",
+    "@aws-cdk/aws-rekognition": "0.0.0",
     "@aws-cdk/aws-resourcegroups": "0.0.0",
     "@aws-cdk/aws-robomaker": "0.0.0",
     "@aws-cdk/aws-route53": "0.0.0",
@@ -324,6 +326,7 @@
     "@aws-cdk/aws-waf": "0.0.0",
     "@aws-cdk/aws-wafregional": "0.0.0",
     "@aws-cdk/aws-wafv2": "0.0.0",
+    "@aws-cdk/aws-wisdom": "0.0.0",
     "@aws-cdk/aws-workspaces": "0.0.0",
     "@aws-cdk/aws-xray": "0.0.0",
     "@aws-cdk/cdk-build-tools": "0.0.0",
diff --git a/packages/monocdk/rosetta/basic.ts-fixture b/packages/monocdk/rosetta/basic.ts-fixture
new file mode 100644
index 0000000000000..0cc6d1104d521
--- /dev/null
+++ b/packages/monocdk/rosetta/basic.ts-fixture
@@ -0,0 +1,12 @@
+// Fixture with packages imported, but nothing else
+import { Construct } from 'constructs';
+import { Stack, Duration } from '@aws-cdk/core';
+
+class Fixture extends Stack {
+  constructor(scope: Construct, id: string) {
+    super(scope, id);
+
+    /// here
+  }
+}
+
diff --git a/packages/monocdk/rosetta/client-vpn.ts-fixture b/packages/monocdk/rosetta/client-vpn.ts-fixture
index 4886d590211df..34c83a31ced35 100644
--- a/packages/monocdk/rosetta/client-vpn.ts-fixture
+++ b/packages/monocdk/rosetta/client-vpn.ts-fixture
@@ -9,7 +9,7 @@ class Fixture extends Stack {
 
     const vpc = new ec2.Vpc(this, 'VPC');
     const samlProvider = new iam.SamlProvider(this, 'Provider', {
-      metadataDocument: SamlMetadataDocument.fromXml('xml'),
+      metadataDocument: iam.SamlMetadataDocument.fromXml('xml'),
     })
 
     /// here
diff --git a/packages/monocdk/rosetta/conns.ts-fixture b/packages/monocdk/rosetta/conns.ts-fixture
deleted file mode 100644
index f29d9a1816a6e..0000000000000
--- a/packages/monocdk/rosetta/conns.ts-fixture
+++ /dev/null
@@ -1,26 +0,0 @@
-// Fixture with fake connectables
-import { Construct, Stack } from '@aws-cdk/core';
-import ec2 = require('@aws-cdk/aws-ec2');
-
-class Fixture extends Stack {
-  constructor(scope: Construct, id: string) {
-    super(scope, id);
-
-    const vpc = new ec2.Vpc(this, 'VPC');
-
-    const loadBalancer = new FakeConnectable();
-    const appFleet = new FakeConnectable();
-    const dbFleet = new FakeConnectable();
-    const rdsDatabase = new FakeConnectable();
-    const fleet1 = new FakeConnectable();
-    const fleet2 = new FakeConnectable();
-    const listener = new FakeConnectable();
-    const myEndpoint = new FakeConnectable();
-
-    /// here
-  }
-}
-
-class FakeConnectable implements ec2.IConnectable {
-    public readonly connections = new ec2.Connections({ securityGroups: [] });
-}
diff --git a/packages/monocdk/rosetta/default.ts-fixture b/packages/monocdk/rosetta/default.ts-fixture
index 558cc09b1c049..61a973840f007 100644
--- a/packages/monocdk/rosetta/default.ts-fixture
+++ b/packages/monocdk/rosetta/default.ts-fixture
@@ -1,65 +1,29 @@
-import * as cfn from '@aws-cdk/aws-cloudformation';
-import * as customresources from '@aws-cdk/custom-resources';
-import * as iam from '@aws-cdk/aws-iam';
-import * as lambda from '@aws-cdk/aws-lambda';
-import * as sns from '@aws-cdk/aws-sns';
-import * as sqs from '@aws-cdk/aws-sqs';
-import * as s3 from '@aws-cdk/aws-s3';
-import {
-  App,
-  Aws,
-  CfnCondition,
-  CfnDynamicReference,
-  CfnDynamicReferenceService,
-  CfnInclude,
-  CfnJson,
-  CfnMapping,
-  CfnOutput,
-  CfnParameter,
-  CfnResource,
-  CfnResourceProps,
-  ConcreteDependable,
-  Construct,
-  CustomResource,
-  CustomResourceProvider,
-  CustomResourceProviderRuntime,
-  DependableTrait,
-  Duration,
-  Fn,
-  IConstruct,
-  SecretValue,
-  Size,
-  SizeRoundingBehavior,
-  Stack,
-  StackProps,
-  Stage,
-  Token,
-} from '@aws-cdk/core';
+// Fixture with packages imported, but nothing else
+import { Construct, CfnOutput, Stage, Stack, StackProps, StageProps } from '@aws-cdk/core';
+import cdk = require('@aws-cdk/core');
+import codepipeline = require('@aws-cdk/aws-codepipeline');
+import cpactions = require('@aws-cdk/aws-codepipeline-actions');
+import codebuild = require('@aws-cdk/aws-codebuild');
+import codecommit = require('@aws-cdk/aws-codecommit');
+import dynamodb = require('@aws-cdk/aws-dynamodb');
+import ecr = require('@aws-cdk/aws-ecr');
+import ec2 = require('@aws-cdk/aws-ec2');
+import iam = require('@aws-cdk/aws-iam');
+import pipelines = require('@aws-cdk/pipelines');
+import secretsmanager = require('@aws-cdk/aws-secretsmanager');
+import sns = require('@aws-cdk/aws-sns');
+import subscriptions = require('@aws-cdk/aws-sns-subscriptions');
+import s3 = require('@aws-cdk/aws-s3');
 
-declare const app: App;
-declare const arn: 'arn:partition:service:region:account-id:resource-id';
-declare const cfnResource: CfnResource;
-declare const construct: Construct;
-declare const constructA: Construct;
-declare const constructB: Construct;
-declare const constructC: Construct;
-declare const functionProps: lambda.FunctionProps;
-declare const isCompleteHandler: lambda.Function;
-declare const myBucket: s3.IBucket;
-declare const myFunction: lambda.IFunction;
-declare const myProvider: CustomResourceProvider;
-declare const myTopic: sns.ITopic;
-declare const onEventHandler: lambda.Function;
-declare const resourceProps: CfnResourceProps;
-declare const stack: Stack;
-
-declare class MyStack extends Stack {}
-declare class YourStack extends Stack {}
+class MyApplicationStage extends Stage {
+  constructor(scope: Construct, id: string, props?: StageProps) {
+    super(scope, id, props);
+  }
+}
 
-class fixture$construct extends Construct {
-  public constructor(scope: Construct, id: string) {
+class Fixture extends Stack {
+  constructor(scope: Construct, id: string) {
     super(scope, id);
-
     /// here
   }
 }
diff --git a/packages/monocdk/rosetta/function.ts-fixture b/packages/monocdk/rosetta/function.ts-fixture
deleted file mode 100644
index 91eafe0abfcc0..0000000000000
--- a/packages/monocdk/rosetta/function.ts-fixture
+++ /dev/null
@@ -1,18 +0,0 @@
-// Fixture with function (`fn`) already created
-import * as path from 'path';
-import { Construct, Stack } from '@aws-cdk/core';
-import { Alias, Code, Function, Runtime } from '@aws-cdk/aws-lambda';
-
-class Fixture extends Stack {
-  constructor(scope: Construct, id: string) {
-    super(scope, id);
-
-    const fn = new Function(this, 'MyFunction', {
-      runtime: Runtime.NODEJS_12_X,
-      handler: 'index.handler',
-      code: Code.fromAsset(path.join(__dirname, 'lambda-handler')),
-    });
-
-    /// here
-  }
-}
diff --git a/packages/monocdk/rosetta/init.ts-fixture b/packages/monocdk/rosetta/init.ts-fixture
new file mode 100644
index 0000000000000..ce18625a2744b
--- /dev/null
+++ b/packages/monocdk/rosetta/init.ts-fixture
@@ -0,0 +1,3 @@
+import { Template } from '@aws-cdk/assertions';
+
+/// here
\ No newline at end of file
diff --git a/packages/monocdk/rosetta/with-batch-job.ts-fixture b/packages/monocdk/rosetta/with-batch-job.ts-fixture
deleted file mode 100644
index 47672ba140841..0000000000000
--- a/packages/monocdk/rosetta/with-batch-job.ts-fixture
+++ /dev/null
@@ -1,38 +0,0 @@
-// Fixture with packages imported, but nothing else
-import { Stack } from '@aws-cdk/core';
-import { Construct } from 'constructs';
-import * as sfn from '@aws-cdk/aws-stepfunctions';
-import * as tasks from '@aws-cdk/aws-stepfunctions-tasks';
-import * as batch from '@aws-cdk/aws-batch';
-import * as ec2 from '@aws-cdk/aws-ec2';
-import * as ecs from '@aws-cdk/aws-ecs';
-import * as path from 'path';
-
-class Fixture extends Stack {
-  constructor(scope: Construct, id: string) {
-    super(scope, id);
-
-    const vpc = ec2.Vpc.fromLookup(this, 'Vpc', {
-      isDefault: true,
-    });
-
-    const batchQueue = new batch.JobQueue(this, 'JobQueue', {
-      computeEnvironments: [
-        {
-          order: 1,
-          computeEnvironment: new batch.ComputeEnvironment(this, 'ComputeEnv', {
-            computeResources: { vpc },
-          }),
-        },
-      ],
-    });
-
-    const batchJobDefinition = new batch.JobDefinition(this, 'JobDefinition', {
-      container: {
-      image: ecs.ContainerImage.fromAsset(path.resolve(__dirname, 'batchjob-image')),
-      },
-    });
-
-    /// here
-  }
-}
diff --git a/packages/monocdk/rosetta/with-objects.ts-fixture b/packages/monocdk/rosetta/with-objects.ts-fixture
new file mode 100644
index 0000000000000..1251aad728423
--- /dev/null
+++ b/packages/monocdk/rosetta/with-objects.ts-fixture
@@ -0,0 +1,49 @@
+// Fixture with packages imported, but nothing else
+import { Construct, Stack } from '@aws-cdk/core';
+import appsync = require('@aws-cdk/aws-appsync');
+const pluralize = require('pluralize');
+
+const args = {
+  after: appsync.GraphqlType.string(),
+  first: appsync.GraphqlType.int(),
+  before: appsync.GraphqlType.string(),
+  last: appsync.GraphqlType.int(),
+};
+
+const Node = new appsync.InterfaceType('Node', {
+  definition: { id: appsync.GraphqlType.string() }
+});
+
+const FilmNode = new appsync.ObjectType('FilmNode', {
+  interfaceTypes: [Node],
+  definition: { filmName: appsync.GraphqlType.string() }
+});
+
+function generateEdgeAndConnection(base: appsync.ObjectType) {
+  const edge = new appsync.ObjectType(`${base.name}Edge`, {
+    definition: { node: base.attribute(), cursor: appsync.GraphqlType.string() }
+  });
+  const connection = new appsync.ObjectType(`${base.name}Connection`, {
+    definition: {
+      edges: edge.attribute({ isList: true }),
+      [pluralize(base.name)]: base.attribute({ isList: true }),
+      totalCount: appsync.GraphqlType.int(),
+    }
+  });
+  return { edge: edge, connection: connection };
+}
+
+const demo = new appsync.ObjectType('Demo', {
+  definition: {
+    id: appsync.GraphqlType.string({ isRequired: true }),
+    version: appsync.GraphqlType.string({ isRequired: true }),
+  },
+});
+
+class Fixture extends Stack {
+  constructor(scope: Construct, id: string) {
+    super(scope, id);
+
+    /// here
+  }
+}
diff --git a/yarn.lock b/yarn.lock
index 97a3298a6c72f..026281159396d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1870,7 +1870,7 @@
   dependencies:
     "@types/istanbul-lib-report" "*"
 
-"@types/jest@^26.0.24":
+"@types/jest@^26.0.22", "@types/jest@^26.0.24":
   version "26.0.24"
   resolved "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a"
   integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==

From a5e51116260dff9ccf3fb91308e6d1bb279b2778 Mon Sep 17 00:00:00 2001
From: Rico Huijbers 
Date: Thu, 4 Nov 2021 13:46:13 +0100
Subject: [PATCH 127/148] docs(codebuild): describe use of CodeBuild caching in
 more detail (#17332)

I spent a good couple of hours figuring out things that the docs
should have told me. Add this in for the future.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-codebuild/README.md | 57 +++++++++++++++++++++--
 1 file changed, 52 insertions(+), 5 deletions(-)

diff --git a/packages/@aws-cdk/aws-codebuild/README.md b/packages/@aws-cdk/aws-codebuild/README.md
index 8a5fa30ac408b..29d06892bc682 100644
--- a/packages/@aws-cdk/aws-codebuild/README.md
+++ b/packages/@aws-cdk/aws-codebuild/README.md
@@ -184,23 +184,53 @@ You can save time when your project builds by using a cache. A cache can store r
 
 ### S3 Caching
 
-With S3 caching, the cache is stored in an S3 bucket which is available from multiple hosts.
+With S3 caching, the cache is stored in an S3 bucket which is available
+regardless from what CodeBuild instance gets selected to run your CodeBuild job
+on. When using S3 caching, you must also add in a `cache` section to your
+buildspec which indicates the files to be cached:
 
 ```ts
+declare const myCachingBucket: s3.Bucket;
+
 new codebuild.Project(this, 'Project', {
   source: codebuild.Source.bitBucket({
     owner: 'awslabs',
     repo: 'aws-cdk',
   }),
-  cache: codebuild.Cache.bucket(new s3.Bucket(this, 'Bucket'))
+
+  cache: codebuild.Cache.bucket(myCachingBucket),
+
+  // BuildSpec with a 'cache' section necessary for S3 caching. This can
+  // also come from 'buildspec.yml' in your source.
+  buildSpec: codebuild.BuildSpec.fromObject({
+    version: '0.2',
+    phases: {
+      build: {
+        commands: ['...'],
+      },
+    },
+    cache: {
+      paths: [
+        // The '**/*' is required to indicate all files in this directory
+        '/root/cachedir/**/*',
+      ],
+    },
+  }),
 });
 ```
 
+Note that two different CodeBuild Projects using the same S3 bucket will *not*
+share their cache: each Project will get a unique file in the S3 bucket to store
+the cache in.
+
 ### Local Caching
 
-With local caching, the cache is stored on the codebuild instance itself. This is simple,
-cheap and fast, but CodeBuild cannot guarantee a reuse of instance and hence cannot
-guarantee cache hits. For example, when a build starts and caches files locally, if two subsequent builds start at the same time afterwards only one of those builds would get the cache. Three different cache modes are supported, which can be turned on individually.
+With local caching, the cache is stored on the codebuild instance itself. This
+is simple, cheap and fast, but CodeBuild cannot guarantee a reuse of instance
+and hence cannot guarantee cache hits. For example, when a build starts and
+caches files locally, if two subsequent builds start at the same time afterwards
+only one of those builds would get the cache. Three different cache modes are
+supported, which can be turned on individually.
 
 * `LocalCacheMode.SOURCE` caches Git metadata for primary and secondary sources.
 * `LocalCacheMode.DOCKER_LAYER` caches existing Docker layers.
@@ -214,6 +244,23 @@ new codebuild.Project(this, 'Project', {
 
   // Enable Docker AND custom caching
   cache: codebuild.Cache.local(codebuild.LocalCacheMode.DOCKER_LAYER, codebuild.LocalCacheMode.CUSTOM)
+
+  // BuildSpec with a 'cache' section necessary for 'CUSTOM' caching. This can
+  // also come from 'buildspec.yml' in your source.
+  buildSpec: codebuild.BuildSpec.fromObject({
+    version: '0.2',
+    phases: {
+      build: {
+        commands: ['...'],
+      },
+    },
+    cache: {
+      paths: [
+        // The '**/*' is required to indicate all files in this directory
+        '/root/cachedir/**/*',
+      ],
+    },
+  }),
 });
 ```
 

From ea779aa3df08f8ae3aa1720a8df51e0a60813984 Mon Sep 17 00:00:00 2001
From: Nick Lynch 
Date: Thu, 4 Nov 2021 13:40:23 +0000
Subject: [PATCH 128/148] chore(cli): v2 python init templates have incorrect
 constructs version (#17333)

The init templates were modified as part of #17062. One change was for the 'app'
and 'sample-app' templates to use 'requirements.txt' instead of 'setup.py'. In
that conversion, a quirk of the `%constructsversion%` replacement was lost; that
replacement inserts the version comparison `>=` itself, so having it in the
requirements.txt results in a broken specifier.

This was caught in the forward-merge to v2, where there are additional tests
verfying the constructs versions.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../lib/init-templates/v2/app/python/requirements.template.txt  | 2 +-
 .../v2/sample-app/python/requirements.template.txt              | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt
index 5ba3f43115a07..f8d8c52349751 100644
--- a/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt
+++ b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt
@@ -1,3 +1,3 @@
 aws-cdk-lib==%cdk-version%
 aws-cdk.assertions-alpha==%cdk-version%
-constructs>=%constructs-version%
+constructs%constructs-version%
diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt
index 5ba3f43115a07..f8d8c52349751 100644
--- a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt
+++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt
@@ -1,3 +1,3 @@
 aws-cdk-lib==%cdk-version%
 aws-cdk.assertions-alpha==%cdk-version%
-constructs>=%constructs-version%
+constructs%constructs-version%

From e0f118046c4a0350bdd614fbff4b96ba7772402e Mon Sep 17 00:00:00 2001
From: AWS CDK Automation
 <43080478+aws-cdk-automation@users.noreply.github.com>
Date: Thu, 4 Nov 2021 20:10:43 +0530
Subject: [PATCH 129/148] feat(cfnspec): cloudformation spec v46.0.0 (#17334)

Co-authored-by: AWS CDK Team 
Co-authored-by: Eli Polonsky 
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
---
 packages/monocdk/rosetta/basic-portfolio.ts-fixture | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/packages/monocdk/rosetta/basic-portfolio.ts-fixture b/packages/monocdk/rosetta/basic-portfolio.ts-fixture
index d8925e6645aa7..3029872ea1f0d 100644
--- a/packages/monocdk/rosetta/basic-portfolio.ts-fixture
+++ b/packages/monocdk/rosetta/basic-portfolio.ts-fixture
@@ -1,9 +1,9 @@
 // Fixture with packages imported, but nothing else
-import { Construct, Stack } from '@aws-cdk/core';
+import * as cdk from '@aws-cdk/core';
 import * as servicecatalog from '@aws-cdk/aws-servicecatalog';
 
-class Fixture extends Stack {
-  constructor(scope: Construct, id: string) {
+class Fixture extends cdk.Stack {
+  constructor(scope: cdk.Construct, id: string) {
     super(scope, id);
 
     const portfolio = new servicecatalog.Portfolio(this, "MyFirstPortfolio", {

From cdb0c0a79e08f7fc6587422c617556c8fde60c64 Mon Sep 17 00:00:00 2001
From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com>
Date: Thu, 4 Nov 2021 11:35:04 -0400
Subject: [PATCH 130/148] chore(sns): make examples compile (#17316)

Includes:
  - chore(sns): make examples compile
  - chore(sns-subscriptions): make examples compile

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../@aws-cdk/aws-sns-subscriptions/README.md  |  36 +++---
 .../rosetta/default.ts-fixture                |  15 +++
 packages/@aws-cdk/aws-sns/README.md           | 113 ++++++++++--------
 .../aws-sns/rosetta/default.ts-fixture        |  15 +++
 4 files changed, 106 insertions(+), 73 deletions(-)
 create mode 100644 packages/@aws-cdk/aws-sns-subscriptions/rosetta/default.ts-fixture
 create mode 100644 packages/@aws-cdk/aws-sns/rosetta/default.ts-fixture

diff --git a/packages/@aws-cdk/aws-sns-subscriptions/README.md b/packages/@aws-cdk/aws-sns-subscriptions/README.md
index ca06d08689736..048ca4dd9fdda 100644
--- a/packages/@aws-cdk/aws-sns-subscriptions/README.md
+++ b/packages/@aws-cdk/aws-sns-subscriptions/README.md
@@ -27,8 +27,6 @@ Subscriptions to Amazon SQS and AWS Lambda can be added on topics across regions
 Create an Amazon SNS Topic to add subscriptions.
 
 ```ts
-import * as sns from '@aws-cdk/aws-sns';
-
 const myTopic = new sns.Topic(this, 'MyTopic');
 ```
 
@@ -37,7 +35,7 @@ const myTopic = new sns.Topic(this, 'MyTopic');
 Add an HTTP or HTTPS Subscription to your topic:
 
 ```ts
-import * as subscriptions from '@aws-cdk/aws-sns-subscriptions';
+const myTopic = new sns.Topic(this, 'MyTopic');
 
 myTopic.addSubscription(new subscriptions.UrlSubscription('https://foobar.com/'));
 ```
@@ -48,8 +46,10 @@ parameter](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parame
 following code defines a CloudFormation parameter and uses it in a URL subscription.
 
 ```ts
+const myTopic = new sns.Topic(this, 'MyTopic');
 const url = new CfnParameter(this, 'url-param');
-myTopic.addSubscription(new subscriptions.UrlSubscription(url.valueAsString()));
+
+myTopic.addSubscription(new subscriptions.UrlSubscription(url.valueAsString));
 ```
 
 ### Amazon SQS
@@ -57,12 +57,10 @@ myTopic.addSubscription(new subscriptions.UrlSubscription(url.valueAsString()));
 Subscribe a queue to your topic:
 
 ```ts
-import * as sqs from '@aws-cdk/aws-sqs';
-import * as subscriptions from '@aws-cdk/aws-sns-subscriptions';
-
 const myQueue = new sqs.Queue(this, 'MyQueue');
+const myTopic = new sns.Topic(this, 'MyTopic');
 
-myTopic.addSubscription(new subscriptions.SqsSubscription(queue));
+myTopic.addSubscription(new subscriptions.SqsSubscription(myQueue));
 ```
 
 KMS key permissions will automatically be granted to SNS when a subscription is made to
@@ -77,14 +75,9 @@ Subscribe an AWS Lambda function to your topic:
 
 ```ts
 import * as lambda from '@aws-cdk/aws-lambda';
-import * as subscriptions from '@aws-cdk/aws-sns-subscriptions';
-
-const myFunction = new lambda.Function(this, 'Echo', {
-  handler: 'index.handler',
-  runtime: lambda.Runtime.NODEJS_12_X,
-  code: lambda.Code.fromInline(`exports.handler = ${handler.toString()}`)
-});
 
+const myTopic = new sns.Topic(this, 'myTopic');
+declare const myFunction: lambda.Function;
 myTopic.addSubscription(new subscriptions.LambdaSubscription(myFunction));
 ```
 
@@ -93,8 +86,7 @@ myTopic.addSubscription(new subscriptions.LambdaSubscription(myFunction));
 Subscribe an email address to your topic:
 
 ```ts
-import * as subscriptions from '@aws-cdk/aws-sns-subscriptions';
-
+const myTopic = new sns.Topic(this, 'MyTopic');
 myTopic.addSubscription(new subscriptions.EmailSubscription('foo@bar.com'));
 ```
 
@@ -104,8 +96,10 @@ parameter](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parame
 following code defines a CloudFormation parameter and uses it in an email subscription.
 
 ```ts
+const myTopic = new sns.Topic(this, 'Topic');
 const emailAddress = new CfnParameter(this, 'email-param');
-myTopic.addSubscription(new subscriptions.EmailSubscription(emailAddress.valueAsString()));
+
+myTopic.addSubscription(new subscriptions.EmailSubscription(emailAddress.valueAsString));
 ```
 
 Note that email subscriptions require confirmation by visiting the link sent to the
@@ -116,7 +110,7 @@ email address.
 Subscribe an sms number to your topic:
 
 ```ts
-import * as subscriptions from '@aws-cdk/aws-sns-subscriptions';
+const myTopic = new sns.Topic(this, 'Topic');
 
 myTopic.addSubscription(new subscriptions.SmsSubscription('+15551231234'));
 ```
@@ -127,6 +121,8 @@ parameter](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parame
 following code defines a CloudFormation parameter and uses it in an sms subscription.
 
 ```ts
+const myTopic = new sns.Topic(this, 'Topic');
 const smsNumber = new CfnParameter(this, 'sms-param');
-myTopic.addSubscription(new subscriptions.SmsSubscription(smsNumber.valueAsString()));
+
+myTopic.addSubscription(new subscriptions.SmsSubscription(smsNumber.valueAsString));
 ```
diff --git a/packages/@aws-cdk/aws-sns-subscriptions/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-sns-subscriptions/rosetta/default.ts-fixture
new file mode 100644
index 0000000000000..8fd7cde78ac48
--- /dev/null
+++ b/packages/@aws-cdk/aws-sns-subscriptions/rosetta/default.ts-fixture
@@ -0,0 +1,15 @@
+// Fixture with packages imported, but nothing else
+import { Construct } from 'constructs';
+import { CfnParameter, Duration, Stack } from '@aws-cdk/core';
+import * as sns from '@aws-cdk/aws-sns';
+import * as sqs from '@aws-cdk/aws-sqs';
+import * as subscriptions from '@aws-cdk/aws-sns-subscriptions';
+import * as iam from '@aws-cdk/aws-iam';
+
+class Fixture extends Stack {
+  constructor(scope: Construct, id: string) {
+    super(scope, id);
+
+    /// here
+  }
+}
diff --git a/packages/@aws-cdk/aws-sns/README.md b/packages/@aws-cdk/aws-sns/README.md
index 23ee15e4af508..72678ff0f8a3d 100644
--- a/packages/@aws-cdk/aws-sns/README.md
+++ b/packages/@aws-cdk/aws-sns/README.md
@@ -14,23 +14,19 @@
 Add an SNS Topic to your stack:
 
 ```ts
-import * as sns from '@aws-cdk/aws-sns';
-
 const topic = new sns.Topic(this, 'Topic', {
-    displayName: 'Customer subscription topic'
+  displayName: 'Customer subscription topic',
 });
 ```
 
 Add a FIFO SNS topic with content-based de-duplication to your stack:
 
 ```ts
-import * as sns from '@aws-cdk/aws-sns';
-
 const topic = new sns.Topic(this, 'Topic', {
-    contentBasedDeduplication: true,
-    displayName: 'Customer subscription topic',
-    fifo: true,
-    topicName: 'customerTopic',
+  contentBasedDeduplication: true,
+  displayName: 'Customer subscription topic',
+  fifo: true,
+  topicName: 'customerTopic',
 });
 ```
 
@@ -46,17 +42,18 @@ default implementations of which can be found in the
 Add an HTTPS Subscription to your topic:
 
 ```ts
-import * as subs from '@aws-cdk/aws-sns-subscriptions';
-
 const myTopic = new sns.Topic(this, 'MyTopic');
 
-myTopic.addSubscription(new subs.UrlSubscription('https://foobar.com/'));
+myTopic.addSubscription(new subscriptions.UrlSubscription('https://foobar.com/'));
 ```
 
 Subscribe a queue to the topic:
 
 ```ts
-myTopic.addSubscription(new subs.SqsSubscription(queue));
+declare const queue: sqs.Queue;
+const myTopic = new sns.Topic(this, 'MyTopic');
+
+myTopic.addSubscription(new subscriptions.SqsSubscription(queue));
 ```
 
 Note that subscriptions of queues in different accounts need to be manually confirmed by
@@ -69,44 +66,48 @@ A filter policy can be specified when subscribing an endpoint to a topic.
 Example with a Lambda subscription:
 
 ```ts
+import * as lambda from '@aws-cdk/aws-lambda';
+
 const myTopic = new sns.Topic(this, 'MyTopic');
-const fn = new lambda.Function(this, 'Function', ...);
+declare const fn: lambda.Function;
 
 // Lambda should receive only message matching the following conditions on attributes:
 // color: 'red' or 'orange' or begins with 'bl'
 // size: anything but 'small' or 'medium'
 // price: between 100 and 200 or greater than 300
 // store: attribute must be present
-topic.addSubscription(new subs.LambdaSubscription(fn, {
-    filterPolicy: {
-        color: sns.SubscriptionFilter.stringFilter({
-            allowlist: ['red', 'orange'],
-            matchPrefixes: ['bl']
-        }),
-        size: sns.SubscriptionFilter.stringFilter({
-            denylist: ['small', 'medium'],
-        }),
-        price: sns.SubscriptionFilter.numericFilter({
-            between: { start: 100, stop: 200 },
-            greaterThan: 300
-        }),
-        store: sns.SubscriptionFilter.existsFilter(),
-    }
+myTopic.addSubscription(new subscriptions.LambdaSubscription(fn, {
+  filterPolicy: {
+    color: sns.SubscriptionFilter.stringFilter({
+      allowlist: ['red', 'orange'],
+      matchPrefixes: ['bl'],
+    }),
+    size: sns.SubscriptionFilter.stringFilter({
+      denylist: ['small', 'medium'],
+    }),
+    price: sns.SubscriptionFilter.numericFilter({
+      between: { start: 100, stop: 200 },
+      greaterThan: 300,
+    }),
+    store: sns.SubscriptionFilter.existsFilter(),
+  },
 }));
 ```
 
 ### Example of Firehose Subscription
 
-```typescript
-  import { Subscription, SubscriptionProtocol, Topic } from '@aws-cdk/aws-sns';
-  import { DeliveryStream } from '@aws-cdk/aws-kinesisfirehose';
-  const topic = new Topic(stack, 'Topic');
-  const stream = new DeliveryStream(stack, 'DeliveryStream', ...)
-  new Subscription(stack, 'Subscription', {
-    endpoint: stream.deliveryStreamArn,
-    protocol: SubscriptionProtocol.FIREHOSE,
-    subscriptionRoleArn: "SAMPLE_ARN", //role with permissions to send messages to a firehose delivery stream
-  })
+```ts
+import { DeliveryStream } from '@aws-cdk/aws-kinesisfirehose';
+
+const topic = new sns.Topic(this, 'Topic');
+declare const stream: DeliveryStream;
+
+new sns.Subscription(this, 'Subscription', {
+  topic,
+  endpoint: stream.deliveryStreamArn,
+  protocol: sns.SubscriptionProtocol.FIREHOSE,
+  subscriptionRoleArn: "SAMPLE_ARN", //role with permissions to send messages to a firehose delivery stream
+});
 ```
 
 ## DLQ setup for SNS Subscription
@@ -117,17 +118,17 @@ See the [SNS DLQ configuration docs](https://docs.aws.amazon.com/sns/latest/dg/s
 Example of usage with user provided DLQ.
 
 ```ts
-const topic = new sns.Topic(stack, 'Topic');
-const dlQueue = new Queue(stack, 'DeadLetterQueue', {
-    queueName: 'MySubscription_DLQ',
-    retentionPeriod: cdk.Duration.days(14),
+const topic = new sns.Topic(this, 'Topic');
+const dlQueue = new sqs.Queue(this, 'DeadLetterQueue', {
+  queueName: 'MySubscription_DLQ',
+  retentionPeriod: Duration.days(14),
 });
 
-new sns.Subscription(stack, 'Subscription', {
-    endpoint: 'endpoint',
-    protocol: sns.SubscriptionProtocol.LAMBDA,
-    topic,
-    deadLetterQueue: dlQueue,
+new sns.Subscription(this, 'Subscription', {
+  endpoint: 'endpoint',
+  protocol: sns.SubscriptionProtocol.LAMBDA,
+  topic,
+  deadLetterQueue: dlQueue,
 });
 ```
 
@@ -138,9 +139,15 @@ SNS topics can be used as targets for CloudWatch event rules.
 Use the `@aws-cdk/aws-events-targets.SnsTopic`:
 
 ```ts
+import * as codecommit from '@aws-cdk/aws-codecommit';
 import * as targets from '@aws-cdk/aws-events-targets';
 
-codeCommitRepository.onCommit(new targets.SnsTopic(myTopic));
+declare const repo: codecommit.Repository;
+const myTopic = new sns.Topic(this, 'Topic');
+
+repo.onCommit('OnCommit', {
+  target: new targets.SnsTopic(myTopic),
+});
 ```
 
 This will result in adding a target to the event rule and will also modify the
@@ -153,8 +160,8 @@ one doesn't already exist. Using `addToResourcePolicy` is the simplest way to
 add policies, but a `TopicPolicy` can also be created manually.
 
 ```ts
-const topic = new sns.Topic(stack, 'Topic');
-const topicPolicy = new sns.TopicPolicy(stack, 'TopicPolicy', {
+const topic = new sns.Topic(this, 'Topic');
+const topicPolicy = new sns.TopicPolicy(this, 'TopicPolicy', {
   topics: [topic],
 });
 
@@ -168,14 +175,14 @@ topicPolicy.document.addStatements(new iam.PolicyStatement({
 A policy document can also be passed on `TopicPolicy` construction
 
 ```ts
-const topic = new sns.Topic(stack, 'Topic');
+const topic = new sns.Topic(this, 'Topic');
 const policyDocument = new iam.PolicyDocument({
   assignSids: true,
   statements: [
     new iam.PolicyStatement({
       actions: ["sns:Subscribe"],
       principals: [new iam.AnyPrincipal()],
-      resources: [topic.topicArn]
+      resources: [topic.topicArn],
     }),
   ],
 });
diff --git a/packages/@aws-cdk/aws-sns/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-sns/rosetta/default.ts-fixture
new file mode 100644
index 0000000000000..72fda381ecb7a
--- /dev/null
+++ b/packages/@aws-cdk/aws-sns/rosetta/default.ts-fixture
@@ -0,0 +1,15 @@
+// Fixture with packages imported, but nothing else
+import { Construct } from 'constructs';
+import { Duration, Stack } from '@aws-cdk/core';
+import * as sns from '@aws-cdk/aws-sns';
+import * as sqs from '@aws-cdk/aws-sqs';
+import * as subscriptions from '@aws-cdk/aws-sns-subscriptions';
+import * as iam from '@aws-cdk/aws-iam';
+
+class Fixture extends Stack {
+  constructor(scope: Construct, id: string) {
+    super(scope, id);
+
+    /// here
+  }
+}

From d24e0673e6e2f97c0a44abb845b943712745db48 Mon Sep 17 00:00:00 2001
From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com>
Date: Thu, 4 Nov 2021 12:29:42 -0400
Subject: [PATCH 131/148] chore(sqs): make examples compile (#17314)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-sqs/README.md                 |  8 ++++----
 .../@aws-cdk/aws-sqs/rosetta/default.ts-fixture     | 13 +++++++++++++
 2 files changed, 17 insertions(+), 4 deletions(-)
 create mode 100644 packages/@aws-cdk/aws-sqs/rosetta/default.ts-fixture

diff --git a/packages/@aws-cdk/aws-sqs/README.md b/packages/@aws-cdk/aws-sqs/README.md
index c824f9410e8ad..11dbb164e5c56 100644
--- a/packages/@aws-cdk/aws-sqs/README.md
+++ b/packages/@aws-cdk/aws-sqs/README.md
@@ -22,7 +22,7 @@ without losing messages or requiring other services to be available.
 
 Import to your project:
 
-```ts
+```ts nofixture
 import * as sqs from '@aws-cdk/aws-sqs';
 ```
 
@@ -44,15 +44,15 @@ can manage yourself.
 ```ts
 // Use managed key
 new sqs.Queue(this, 'Queue', {
-    encryption: QueueEncryption.KMS_MANAGED,
+  encryption: sqs.QueueEncryption.KMS_MANAGED,
 });
 
 // Use custom key
 const myKey = new kms.Key(this, 'Key');
 
 new sqs.Queue(this, 'Queue', {
-    encryption: QueueEncryption.KMS,
-    encryptionMasterKey: myKey
+  encryption: sqs.QueueEncryption.KMS,
+  encryptionMasterKey: myKey,
 });
 ```
 
diff --git a/packages/@aws-cdk/aws-sqs/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-sqs/rosetta/default.ts-fixture
new file mode 100644
index 0000000000000..968d51c8ae916
--- /dev/null
+++ b/packages/@aws-cdk/aws-sqs/rosetta/default.ts-fixture
@@ -0,0 +1,13 @@
+// Fixture with packages imported, but nothing else
+import { Construct } from 'constructs';
+import { Stack } from '@aws-cdk/core';
+import sqs = require('@aws-cdk/aws-sqs');
+import kms = require('@aws-cdk/aws-kms');
+
+class Fixture extends Stack {
+  constructor(scope: Construct, id: string) {
+    super(scope, id);
+
+    /// here
+  }
+}

From a91cc051ed319526535b5e0877b47fe5ca2161ef Mon Sep 17 00:00:00 2001
From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com>
Date: Thu, 4 Nov 2021 13:23:21 -0400
Subject: [PATCH 132/148] chore(dynamodb): make examples compile (#17313)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-dynamodb/README.md      | 47 ++++++++-----------
 .../aws-dynamodb/rosetta/default.ts-fixture   | 13 +++++
 2 files changed, 32 insertions(+), 28 deletions(-)
 create mode 100644 packages/@aws-cdk/aws-dynamodb/rosetta/default.ts-fixture

diff --git a/packages/@aws-cdk/aws-dynamodb/README.md b/packages/@aws-cdk/aws-dynamodb/README.md
index b07946c52d65f..b79b1e0efe465 100644
--- a/packages/@aws-cdk/aws-dynamodb/README.md
+++ b/packages/@aws-cdk/aws-dynamodb/README.md
@@ -14,10 +14,8 @@
 Here is a minimal deployable DynamoDB table definition:
 
 ```ts
-import * as dynamodb from '@aws-cdk/aws-dynamodb';
-
 const table = new dynamodb.Table(this, 'Table', {
-  partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }
+  partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
 });
 ```
 
@@ -28,7 +26,8 @@ factory method. This method accepts table name or table ARN which describes the
 existing table:
 
 ```ts
-const table = Table.fromTableArn(this, 'ImportedTable', 'arn:aws:dynamodb:us-east-1:111111111:table/my-table');
+declare const user: iam.User;
+const table = dynamodb.Table.fromTableArn(this, 'ImportedTable', 'arn:aws:dynamodb:us-east-1:111111111:table/my-table');
 // now you can just call methods on the table
 table.grantReadWriteData(user);
 ```
@@ -50,11 +49,9 @@ DynamoDB supports two billing modes:
 * PAY_PER_REQUEST - on-demand pricing and scaling. You only pay for what you use and there is no read and write capacity for the table or its global secondary indexes.
 
 ```ts
-import * as dynamodb from '@aws-cdk/aws-dynamodb';
-
 const table = new dynamodb.Table(this, 'Table', {
   partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
-  billingMode: dynamodb.BillingMode.PAY_PER_REQUEST
+  billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
 });
 ```
 
@@ -81,8 +78,6 @@ https://aws.amazon.com/blogs/database/how-to-use-aws-cloudformation-to-configure
 You can create DynamoDB Global Tables by setting the `replicationRegions` property on a `Table`:
 
 ```ts
-import * as dynamodb from '@aws-cdk/aws-dynamodb';
-
 const globalTable = new dynamodb.Table(this, 'Table', {
   partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
   replicationRegions: ['us-east-1', 'us-east-2', 'us-west-2'],
@@ -100,7 +95,7 @@ you have to make sure write auto-scaling is enabled for that Table:
 const globalTable = new dynamodb.Table(this, 'Table', {
   partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
   replicationRegions: ['us-east-1', 'us-east-2', 'us-west-2'],
-  billingMode: BillingMode.PROVISIONED,
+  billingMode: dynamodb.BillingMode.PROVISIONED,
 });
 
 globalTable.autoScaleWriteCapacity({
@@ -131,11 +126,9 @@ All user data stored in Amazon DynamoDB is fully encrypted at rest. When creatin
 Creating a Table encrypted with a customer managed CMK:
 
 ```ts
-import dynamodb = require('@aws-cdk/aws-dynamodb');
-
-const table = new dynamodb.Table(stack, 'MyTable', {
+const table = new dynamodb.Table(this, 'MyTable', {
   partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
-  encryption: TableEncryption.CUSTOMER_MANAGED,
+  encryption: dynamodb.TableEncryption.CUSTOMER_MANAGED,
 });
 
 // You can access the CMK that was added to the stack on your behalf by the Table construct via:
@@ -145,15 +138,14 @@ const tableEncryptionKey = table.encryptionKey;
 You can also supply your own key:
 
 ```ts
-import dynamodb = require('@aws-cdk/aws-dynamodb');
-import kms = require('@aws-cdk/aws-kms');
+import * as kms from '@aws-cdk/aws-kms';
 
-const encryptionKey = new kms.Key(stack, 'Key', {
-  enableKeyRotation: true
+const encryptionKey = new kms.Key(this, 'Key', {
+  enableKeyRotation: true,
 });
-const table = new dynamodb.Table(stack, 'MyTable', {
+const table = new dynamodb.Table(this, 'MyTable', {
   partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
-  encryption: TableEncryption.CUSTOMER_MANAGED,
+  encryption: dynamodb.TableEncryption.CUSTOMER_MANAGED,
   encryptionKey, // This will be exposed as table.encryptionKey
 });
 ```
@@ -161,11 +153,9 @@ const table = new dynamodb.Table(stack, 'MyTable', {
 In order to use the AWS managed CMK instead, change the code to:
 
 ```ts
-import dynamodb = require('@aws-cdk/aws-dynamodb');
-
-const table = new dynamodb.Table(stack, 'MyTable', {
+const table = new dynamodb.Table(this, 'MyTable', {
   partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
-  encryption: TableEncryption.AWS_MANAGED,
+  encryption: dynamodb.TableEncryption.AWS_MANAGED,
 });
 
 // In this case, the CMK _cannot_ be accessed through table.encryptionKey.
@@ -176,11 +166,13 @@ const table = new dynamodb.Table(stack, 'MyTable', {
 To get the partition key and sort key of the table or indexes you have configured:
 
 ```ts
-const { partitionKey, sortKey } = table.schema();
+declare const table: dynamodb.Table;
+const schema = table.schema();
+const partitionKey = schema.partitionKey;
+const sortKey = schema.sortKey;
 
 // In case you want to get schema details for any secondary index
-
-const { partitionKey, sortKey } = table.schema(INDEX_NAME);
+// const { partitionKey, sortKey } = table.schema(INDEX_NAME);
 ```
 
 ## Kinesis Stream
@@ -188,7 +180,6 @@ const { partitionKey, sortKey } = table.schema(INDEX_NAME);
 A Kinesis Data Stream can be configured on the DynamoDB table to capture item-level changes.
 
 ```ts
-import * as dynamodb from '@aws-cdk/aws-dynamodb';
 import * as kinesis from '@aws-cdk/aws-kinesis';
 
 const stream = new kinesis.Stream(this, 'Stream');
diff --git a/packages/@aws-cdk/aws-dynamodb/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-dynamodb/rosetta/default.ts-fixture
new file mode 100644
index 0000000000000..1f9bb33819183
--- /dev/null
+++ b/packages/@aws-cdk/aws-dynamodb/rosetta/default.ts-fixture
@@ -0,0 +1,13 @@
+// Fixture with packages imported, but nothing else
+import { Construct } from 'constructs';
+import { Duration, Stack } from '@aws-cdk/core';
+import dynamodb = require('@aws-cdk/aws-dynamodb');
+import iam = require('@aws-cdk/aws-iam');
+
+class Fixture extends Stack {
+  constructor(scope: Construct, id: string) {
+    super(scope, id);
+
+    /// here
+  }
+}

From bc00427fa6540d10ef994ace152ea4b85ccf81d5 Mon Sep 17 00:00:00 2001
From: Otavio Macedo 
Date: Thu, 4 Nov 2021 18:18:45 +0000
Subject: [PATCH 133/148] chore: stripping stability banners for Cfn constructs
 on alpha modules (#17327)

Alpha modules don't have Cfn constructs, so it doesn't make sense to have a stability banner for them on the README.

Fixes #17038.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../individual-pkg-gen/transform-packages.ts  | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/tools/@aws-cdk/individual-pkg-gen/transform-packages.ts b/tools/@aws-cdk/individual-pkg-gen/transform-packages.ts
index b56e39c788f2b..a2855fb2fa1b3 100644
--- a/tools/@aws-cdk/individual-pkg-gen/transform-packages.ts
+++ b/tools/@aws-cdk/individual-pkg-gen/transform-packages.ts
@@ -6,6 +6,21 @@ const lerna_project = require('@lerna/project');
 // eslint-disable-next-line @typescript-eslint/no-require-imports
 const ver = require('../../../scripts/resolve-version');
 
+const CFN_STABILITY_BANNER = [
+  '![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)',
+  '',
+  '> All classes with the `Cfn` prefix in this module ([CFN Resources]) are always stable and safe to use.',
+  '>',
+  '> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib',
+].join('\n');
+
+const FEATURE_CFN_STABILITY_BANNER = `> **CFN Resources:** All classes with the \`Cfn\` prefix in this module ([CFN Resources]) are always
+> stable and safe to use.
+>
+> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib`;
+
+const FEATURE_CFN_STABILITY_LINE = /CFN Resources\s+\| !\[Stable]\(https:\/\/img\.shields\.io\/badge\/stable-success\.svg\?style=for-the-badge\)\n/gm;
+
 /**
  * @aws-cdk/ scoped packages that may be present in devDependencies and need to
  * be retained (or else pkglint might declare the package unworthy).
@@ -109,6 +124,13 @@ function transformPackages(): void {
           packageUnscopedName: `${pkg.name.substring('@aws-cdk/'.length)}`,
         });
         fs.outputFileSync(destination, sourceCodeOutput);
+      } else if (sourceFileName === 'README.md') {
+        // Remove the stability banner for Cfn constructs, since they don't exist in the alpha modules
+        let sourceCode = fs.readFileSync(source).toString();
+        [CFN_STABILITY_BANNER, FEATURE_CFN_STABILITY_BANNER, FEATURE_CFN_STABILITY_LINE].forEach(pattern => {
+          sourceCode = sourceCode.replace(pattern, '');
+        });
+        fs.outputFileSync(destination, sourceCode);
       } else {
         const stat = fs.statSync(source);
         if (stat.isDirectory()) {

From 57ad1e087edef653d672c1426b920b12962f0f0f Mon Sep 17 00:00:00 2001
From: Calvin Combs <66279577+comcalvi@users.noreply.github.com>
Date: Thu, 4 Nov 2021 12:15:06 -0700
Subject: [PATCH 134/148] feat(cli): added `build` field to cdk.json (#17176)

Adds a `build` field to `cdk.json`. The command specified in the `build` will be executed before synthesis. This can be used to build any code that needs to be built before synthesis (for example, CDK App code or Lambda Function code).

This is part of the changes needed for the `cdk watch` command
(https://github.com/aws/aws-cdk-rfcs/pull/383).

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/aws-cdk/README.md                    |  7 ++++
 packages/aws-cdk/lib/api/cxapp/exec.ts        | 11 +++--
 packages/aws-cdk/lib/settings.ts              |  4 ++
 packages/aws-cdk/test/api/exec.test.ts        | 40 ++++++++++++++++---
 packages/aws-cdk/test/usersettings.test.ts    | 20 ++++++++++
 .../aws-cdk/test/util/mock-child_process.ts   | 21 +++-------
 6 files changed, 79 insertions(+), 24 deletions(-)

diff --git a/packages/aws-cdk/README.md b/packages/aws-cdk/README.md
index e4566b7bbb690..0a2270b08fc90 100644
--- a/packages/aws-cdk/README.md
+++ b/packages/aws-cdk/README.md
@@ -464,6 +464,7 @@ Some of the interesting keys that can be used in the JSON configuration files:
 ```json5
 {
     "app": "node bin/main.js",        // Command to start the CDK app      (--app='node bin/main.js')
+    "build": "mvn package",           // Specify pre-synth build           (no command line option)
     "context": {                      // Context entries                   (--context=key=value)
         "key": "value"
     },
@@ -473,6 +474,12 @@ Some of the interesting keys that can be used in the JSON configuration files:
 }
 ```
 
+If specified, the command in the `build` key will be executed immediately before synthesis.
+This can be used to build Lambda Functions, CDK Application code, or other assets. 
+`build` cannot be specified on the command line or in the User configuration, 
+and must be specified in the Project configuration. The command specified
+in `build` will be executed by the "watch" process before deployment.
+
 ### Environment
 
 The following environment variables affect aws-cdk:
diff --git a/packages/aws-cdk/lib/api/cxapp/exec.ts b/packages/aws-cdk/lib/api/cxapp/exec.ts
index facaf24a3bfe0..bcc298deaeea2 100644
--- a/packages/aws-cdk/lib/api/cxapp/exec.ts
+++ b/packages/aws-cdk/lib/api/cxapp/exec.ts
@@ -46,6 +46,11 @@ export async function execProgram(aws: SdkProvider, config: Configuration): Prom
   debug('context:', context);
   env[cxapi.CONTEXT_ENV] = JSON.stringify(context);
 
+  const build = config.settings.get(['build']);
+  if (build) {
+    await exec(build);
+  }
+
   const app = config.settings.get(['app']);
   if (!app) {
     throw new Error(`--app is required either in command-line, in ${PROJECT_CONFIG} or in ${USER_DEFAULTS}`);
@@ -74,7 +79,7 @@ export async function execProgram(aws: SdkProvider, config: Configuration): Prom
 
   debug('env:', env);
 
-  await exec();
+  await exec(commandLine.join(' '));
 
   return createAssembly(outdir);
 
@@ -91,7 +96,7 @@ export async function execProgram(aws: SdkProvider, config: Configuration): Prom
     }
   }
 
-  async function exec() {
+  async function exec(commandAndArgs: string) {
     return new Promise((ok, fail) => {
       // We use a slightly lower-level interface to:
       //
@@ -103,7 +108,7 @@ export async function execProgram(aws: SdkProvider, config: Configuration): Prom
       //   anyway, and if the subprocess is printing to it for debugging purposes the
       //   user gets to see it sooner. Plus, capturing doesn't interact nicely with some
       //   processes like Maven.
-      const proc = childProcess.spawn(commandLine[0], commandLine.slice(1), {
+      const proc = childProcess.spawn(commandAndArgs, {
         stdio: ['ignore', 'inherit', 'inherit'],
         detached: false,
         shell: true,
diff --git a/packages/aws-cdk/lib/settings.ts b/packages/aws-cdk/lib/settings.ts
index 4bfafd447d607..6182ecc26e0c3 100644
--- a/packages/aws-cdk/lib/settings.ts
+++ b/packages/aws-cdk/lib/settings.ts
@@ -113,6 +113,10 @@ export class Configuration {
 
     const readUserContext = this.props.readUserContext ?? true;
 
+    if (userConfig.get(['build'])) {
+      throw new Error('The `build` key cannot be specified in the user config (~/.cdk.json), specify it in the project config (cdk.json) instead');
+    }
+
     const contextSources = [
       this.commandLineContext,
       this.projectConfig.subSettings([CONTEXT_KEY]).makeReadOnly(),
diff --git a/packages/aws-cdk/test/api/exec.test.ts b/packages/aws-cdk/test/api/exec.test.ts
index d2e65907527fa..b9c5637acce1a 100644
--- a/packages/aws-cdk/test/api/exec.test.ts
+++ b/packages/aws-cdk/test/api/exec.test.ts
@@ -137,7 +137,7 @@ test('the application set in --app is executed', async () => {
   // GIVEN
   config.settings.set(['app'], 'cloud-executable');
   mockSpawn({
-    commandLine: ['cloud-executable'],
+    commandLine: 'cloud-executable',
     sideEffect: () => writeOutputAssembly(),
   });
 
@@ -149,7 +149,7 @@ test('the application set in --app is executed as-is if it contains a filename t
   // GIVEN
   config.settings.set(['app'], 'does-not-exist');
   mockSpawn({
-    commandLine: ['does-not-exist'],
+    commandLine: 'does-not-exist',
     sideEffect: () => writeOutputAssembly(),
   });
 
@@ -161,7 +161,7 @@ test('the application set in --app is executed with arguments', async () => {
   // GIVEN
   config.settings.set(['app'], 'cloud-executable an-arg');
   mockSpawn({
-    commandLine: ['cloud-executable', 'an-arg'],
+    commandLine: 'cloud-executable an-arg',
     sideEffect: () => writeOutputAssembly(),
   });
 
@@ -174,7 +174,7 @@ test('application set in --app as `*.js` always uses handler on windows', async
   sinon.stub(process, 'platform').value('win32');
   config.settings.set(['app'], 'windows.js');
   mockSpawn({
-    commandLine: [process.execPath, 'windows.js'],
+    commandLine: process.execPath + ' windows.js',
     sideEffect: () => writeOutputAssembly(),
   });
 
@@ -186,7 +186,7 @@ test('application set in --app is `*.js` and executable', async () => {
   // GIVEN
   config.settings.set(['app'], 'executable-app.js');
   mockSpawn({
-    commandLine: ['executable-app.js'],
+    commandLine: 'executable-app.js',
     sideEffect: () => writeOutputAssembly(),
   });
 
@@ -194,6 +194,36 @@ test('application set in --app is `*.js` and executable', async () => {
   await execProgram(sdkProvider, config);
 });
 
+test('cli throws when the `build` script fails', async () => {
+  // GIVEN
+  config.settings.set(['build'], 'fake-command');
+  mockSpawn({
+    commandLine: 'fake-command',
+    exitCode: 127,
+  });
+
+  // WHEN
+  await expect(execProgram(sdkProvider, config)).rejects.toEqual(new Error('Subprocess exited with error 127'));
+}, TEN_SECOND_TIMEOUT);
+
+test('cli does not throw when the `build` script succeeds', async () => {
+  // GIVEN
+  config.settings.set(['build'], 'real command');
+  config.settings.set(['app'], 'executable-app.js');
+  mockSpawn({
+    commandLine: 'real command', // `build` key is not split on whitespace
+    exitCode: 0,
+  },
+  {
+    commandLine: 'executable-app.js',
+    sideEffect: () => writeOutputAssembly(),
+  });
+
+  // WHEN
+  await execProgram(sdkProvider, config);
+}, TEN_SECOND_TIMEOUT);
+
+
 function writeOutputAssembly() {
   const asm = testAssembly({
     stacks: [],
diff --git a/packages/aws-cdk/test/usersettings.test.ts b/packages/aws-cdk/test/usersettings.test.ts
index 948b3b3f907bc..92d7db4a44025 100644
--- a/packages/aws-cdk/test/usersettings.test.ts
+++ b/packages/aws-cdk/test/usersettings.test.ts
@@ -69,4 +69,24 @@ test('load context from all 3 files if available', async () => {
   expect(config.context.get('project')).toBe('foobar');
   expect(config.context.get('foo')).toBe('bar');
   expect(config.context.get('test')).toBe('bar');
+});
+
+test('throws an error if the `build` key is specified in the user config', async () => {
+  // GIVEN
+  const GIVEN_CONFIG: Map = new Map([
+    [USER_CONFIG, {
+      build: 'foobar',
+    }],
+  ]);
+
+  // WHEN
+  mockedFs.pathExists.mockImplementation(path => {
+    return GIVEN_CONFIG.has(path);
+  });
+  mockedFs.readJSON.mockImplementation(path => {
+    return GIVEN_CONFIG.get(path);
+  });
+
+  // THEN
+  await expect(new Configuration().load()).rejects.toEqual(new Error('The `build` key cannot be specified in the user config (~/.cdk.json), specify it in the project config (cdk.json) instead'));
 });
\ No newline at end of file
diff --git a/packages/aws-cdk/test/util/mock-child_process.ts b/packages/aws-cdk/test/util/mock-child_process.ts
index 539fd06273399..d7645b4c2ce1a 100644
--- a/packages/aws-cdk/test/util/mock-child_process.ts
+++ b/packages/aws-cdk/test/util/mock-child_process.ts
@@ -6,16 +6,11 @@ if (!(child_process as any).spawn.mockImplementationOnce) {
 }
 
 export interface Invocation {
-  commandLine: string[];
+  commandLine: string;
   cwd?: string;
   exitCode?: number;
   stdout?: string;
 
-  /**
-   * Only match a prefix of the command (don't care about the details of the arguments)
-   */
-  prefix?: boolean;
-
   /**
    * Run this function as a side effect, if present
    */
@@ -26,14 +21,8 @@ export function mockSpawn(...invocations: Invocation[]) {
   let mock = (child_process.spawn as any);
   for (const _invocation of invocations) {
     const invocation = _invocation; // Mirror into variable for closure
-    mock = mock.mockImplementationOnce((binary: string, args: string[], options: child_process.SpawnOptions) => {
-      if (invocation.prefix) {
-        // Match command line prefix
-        expect([binary, ...args].slice(0, invocation.commandLine.length)).toEqual(invocation.commandLine);
-      } else {
-        // Match full command line
-        expect([binary, ...args]).toEqual(invocation.commandLine);
-      }
+    mock = mock.mockImplementationOnce((binary: string, options: child_process.SpawnOptions) => {
+      expect(binary).toEqual(invocation.commandLine);
 
       if (invocation.cwd != null) {
         expect(options.cwd).toBe(invocation.cwd);
@@ -60,8 +49,8 @@ export function mockSpawn(...invocations: Invocation[]) {
     });
   }
 
-  mock.mockImplementation((binary: string, args: string[], _options: any) => {
-    throw new Error(`Did not expect call of ${JSON.stringify([binary, ...args])}`);
+  mock.mockImplementation((binary: string, _options: any) => {
+    throw new Error(`Did not expect call of ${binary}`);
   });
 }
 

From ea56e6925422ebb987dbd87952511f23832ac7b6 Mon Sep 17 00:00:00 2001
From: suds-sky <85171367+suds-sky@users.noreply.github.com>
Date: Thu, 4 Nov 2021 20:09:13 +0000
Subject: [PATCH 135/148] feat(lambda-nodejs): add sourcesContent in
 BundlingOptions (#17280)

Support excluding sourcesContent from `esbuild` generated source map

Closes #17256

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-lambda-nodejs/README.md            | 1 +
 packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts      | 2 ++
 packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts         | 9 +++++++++
 .../@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts     | 5 +++--
 4 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/packages/@aws-cdk/aws-lambda-nodejs/README.md b/packages/@aws-cdk/aws-lambda-nodejs/README.md
index 9bf47f0631d57..1d3eaa66a2a4a 100644
--- a/packages/@aws-cdk/aws-lambda-nodejs/README.md
+++ b/packages/@aws-cdk/aws-lambda-nodejs/README.md
@@ -174,6 +174,7 @@ new lambda.NodejsFunction(this, 'my-handler', {
     minify: true, // minify code, defaults to false
     sourceMap: true, // include source map, defaults to false
     sourceMapMode: SourceMapMode.INLINE, // defaults to SourceMapMode.DEFAULT
+    sourcesContent: false, // do not include original source into source map, defaults to true
     target: 'es2020', // target environment for the generated JavaScript code
     loader: { // Use the 'dataurl' loader for '.png' files
       '.png': 'dataurl',
diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts
index 3bd05a7ccb39d..5b7c6ce416b2c 100644
--- a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts
+++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts
@@ -182,6 +182,7 @@ export class Bundling implements cdk.BundlingOptions {
     const sourceMapEnabled = this.props.sourceMapMode ?? this.props.sourceMap;
     const sourceMapMode = this.props.sourceMapMode ?? SourceMapMode.DEFAULT;
     const sourceMapValue = sourceMapMode === SourceMapMode.DEFAULT ? '' : `=${this.props.sourceMapMode}`;
+    const sourcesContent = this.props.sourcesContent ?? true;
 
     const esbuildCommand: string[] = [
       options.esbuildRunner,
@@ -191,6 +192,7 @@ export class Bundling implements cdk.BundlingOptions {
       `--outfile="${pathJoin(options.outputDir, 'index.js')}"`,
       ...this.props.minify ? ['--minify'] : [],
       ...sourceMapEnabled ? [`--sourcemap${sourceMapValue}`] : [],
+      ...sourcesContent ? [] : [`--sources-content=${sourcesContent}`],
       ...this.externals.map(external => `--external:${external}`),
       ...loaders.map(([ext, name]) => `--loader:${ext}=${name}`),
       ...defines.map(([key, value]) => `--define:${key}=${JSON.stringify(value)}`),
diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts
index 55606f66b2507..87d3de0eec1fc 100644
--- a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts
+++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts
@@ -26,6 +26,15 @@ export interface BundlingOptions {
    */
   readonly sourceMapMode?: SourceMapMode;
 
+  /**
+   * Whether to include original source code in source maps when bundling.
+   *
+   * @see https://esbuild.github.io/api/#sources-content
+   *
+   * @default true
+   */
+  readonly sourcesContent?: boolean;
+
   /**
    * Target environment for the generated JavaScript code.
    *
diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts
index f4e974c08fdce..ae871b67cb69f 100644
--- a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts
+++ b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts
@@ -188,6 +188,7 @@ test('esbuild bundling with esbuild options', () => {
     architecture: Architecture.X86_64,
     minify: true,
     sourceMap: true,
+    sourcesContent: false,
     target: 'es2020',
     loader: {
       '.png': 'dataurl',
@@ -218,7 +219,7 @@ test('esbuild bundling with esbuild options', () => {
         [
           'esbuild --bundle "/asset-input/lib/handler.ts"',
           '--target=es2020 --platform=node --outfile="/asset-output/index.js"',
-          '--minify --sourcemap --external:aws-sdk --loader:.png=dataurl',
+          '--minify --sourcemap --sources-content=false --external:aws-sdk --loader:.png=dataurl',
           defineInstructions,
           '--log-level=silent --keep-names --tsconfig=/asset-input/lib/custom-tsconfig.ts',
           '--metafile=/asset-output/index.meta.json --banner:js="/* comments */" --footer:js="/* comments */"',
@@ -656,4 +657,4 @@ test('esbuild bundling with pre compilations and undefined tsconfig ( Should thr
     });
   }).toThrow('Cannot find a tsconfig.json, please specify the prop: tsconfig');
 
-});
\ No newline at end of file
+});

From b9c00f09d7f489e2dc53618bbc1e481b48e36533 Mon Sep 17 00:00:00 2001
From: Eli Polonsky 
Date: Thu, 4 Nov 2021 23:28:01 +0200
Subject: [PATCH 136/148] chore: remove invalid test (#17337)

---
 .../test/integ/cli/bootstrapping.integtest.ts | 24 +------------------
 1 file changed, 1 insertion(+), 23 deletions(-)

diff --git a/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts b/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts
index d7716a2ac3e70..1298c77a5fca8 100644
--- a/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts
+++ b/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts
@@ -1,6 +1,6 @@
 import * as fs from 'fs';
 import * as path from 'path';
-import { MAJOR_VERSION, randomString, withDefaultFixture } from '../helpers/cdk';
+import { randomString, withDefaultFixture } from '../helpers/cdk';
 import { integTest } from '../helpers/test-helpers';
 
 const timeout = process.env.CODEBUILD_BUILD_ID ? // if the process is running in CodeBuild
@@ -129,28 +129,6 @@ integTest('deploy old style synthesis to new style bootstrap', withDefaultFixtur
   });
 }));
 
-if (MAJOR_VERSION === '1') {
-  // For v2, the default bootstrap is the modern bootstrap, so this test is predicated on invalid
-  // assumptions.
-
-  integTest('deploying new style synthesis to old style bootstrap fails', withDefaultFixture(async (fixture) => {
-    const bootstrapStackName = fixture.bootstrapStackName;
-
-    await fixture.cdkBootstrapLegacy({
-      toolkitStackName: bootstrapStackName,
-    });
-
-    // Deploy stack that uses file assets, this fails because the bootstrap stack
-    // is version checked.
-    await expect(fixture.cdkDeploy('lambda', {
-      options: [
-        '--toolkit-stack-name', bootstrapStackName,
-        '--context', '@aws-cdk/core:newStyleStackSynthesis=1',
-      ],
-    })).rejects.toThrow('exited with error');
-  }));
-}
-
 integTest('can create a legacy bootstrap stack with --public-access-block-configuration=false', withDefaultFixture(async (fixture) => {
   const bootstrapStackName = fixture.bootstrapStackName;
 

From e412308bc81ede16b079077cfa4774ceaa2fadeb Mon Sep 17 00:00:00 2001
From: Tatsuya Yamamoto 
Date: Fri, 5 Nov 2021 07:51:11 +0900
Subject: [PATCH 137/148] feat(iot): allow setting `errorAction` of TopicRule 
 (#17287)

I'm trying to implement aws-iot L2 Constructs.

This PR is one of steps after following PR:
- https://github.com/aws/aws-cdk/pull/16681#issuecomment-942233029

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 packages/@aws-cdk/aws-iot/README.md           | 18 +++++++++++++
 packages/@aws-cdk/aws-iot/lib/topic-rule.ts   |  8 ++++++
 .../@aws-cdk/aws-iot/test/topic-rule.test.ts  | 25 +++++++++++++++++++
 3 files changed, 51 insertions(+)

diff --git a/packages/@aws-cdk/aws-iot/README.md b/packages/@aws-cdk/aws-iot/README.md
index 42ab651f26f81..402036b531dfc 100644
--- a/packages/@aws-cdk/aws-iot/README.md
+++ b/packages/@aws-cdk/aws-iot/README.md
@@ -75,6 +75,22 @@ const topicRule = new iot.TopicRule(this, 'TopicRule', {
 topicRule.addAction(new actions.LambdaFunctionAction(func))
 ```
 
+You can also supply `errorAction` as following,
+and the IoT Rule will trigger it if a rule's action is unable to perform:
+
+```ts
+import * as iot from '@aws-cdk/aws-iot';
+import * as actions from '@aws-cdk/aws-iot-actions';
+import * as logs from '@aws-cdk/aws-logs';
+
+const logGroup = new logs.LogGroup(this, 'MyLogGroup');
+
+new iot.TopicRule(this, 'TopicRule', {
+  sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, timestamp() as timestamp FROM 'device/+/data'"),
+  errorAction: new actions.CloudWatchLogsAction(logGroup),
+});
+```
+
 If you wanna make the topic rule disable, add property `enabled: false` as following:
 
 ```ts
@@ -83,3 +99,5 @@ new iot.TopicRule(this, 'TopicRule', {
   enabled: false,
 });
 ```
+
+See also [@aws-cdk/aws-iot-actions](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-iot-actions-readme.html) for other actions.
diff --git a/packages/@aws-cdk/aws-iot/lib/topic-rule.ts b/packages/@aws-cdk/aws-iot/lib/topic-rule.ts
index 8860a611e4af3..89f40c3797d97 100644
--- a/packages/@aws-cdk/aws-iot/lib/topic-rule.ts
+++ b/packages/@aws-cdk/aws-iot/lib/topic-rule.ts
@@ -48,6 +48,13 @@ export interface TopicRuleProps {
    */
   readonly description?: string;
 
+  /**
+   * The action AWS IoT performs when it is unable to perform a rule's action.
+   *
+   * @default - no action will be performed
+   */
+  readonly errorAction?: IAction;
+
   /**
    * Specifies whether the rule is enabled.
    *
@@ -117,6 +124,7 @@ export class TopicRule extends Resource implements ITopicRule {
         actions: Lazy.any({ produce: () => this.actions }),
         awsIotSqlVersion: sqlConfig.awsIotSqlVersion,
         description: props.description,
+        errorAction: props.errorAction?.bind(this).configuration,
         ruleDisabled: props.enabled === undefined ? undefined : !props.enabled,
         sql: sqlConfig.sql,
       },
diff --git a/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts b/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts
index 6e4a49c234e60..5f84201a37e5d 100644
--- a/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts
+++ b/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts
@@ -233,6 +233,31 @@ test('cannot add an action that have multiple keys', () => {
   }).toThrow('An action property cannot have multiple keys, received: http,lambda');
 });
 
+test('can set errorAction', () => {
+  const stack = new cdk.Stack();
+
+  const action: iot.IAction = {
+    bind: () => ({
+      configuration: {
+        http: { url: 'http://example.com' },
+      },
+    }),
+  };
+
+  new iot.TopicRule(stack, 'MyTopicRule', {
+    errorAction: action,
+    sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"),
+  });
+
+  Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
+    TopicRulePayload: {
+      ErrorAction: {
+        Http: { Url: 'http://example.com' },
+      },
+    },
+  });
+});
+
 test('can import a TopicRule by ARN', () => {
   const stack = new cdk.Stack();
 

From c66ac89f43d3d2cee2b5842c54dc00e14ccdd2f4 Mon Sep 17 00:00:00 2001
From: Rayjan Wilson 
Date: Thu, 4 Nov 2021 19:46:39 -0400
Subject: [PATCH 138/148] feat(codepipeline): add construct for registering
 custom Actions (#17041)

fixes #17039

all it does is add `./common` and `./custom-action-registration` to the modules `index.ts`

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../aws-codepipeline-actions/lib/index.ts     |  1 +
 .../lib/jenkins/jenkins-provider.ts           |  3 +-
 packages/@aws-cdk/aws-codepipeline/README.md  | 34 ++++++++++++++
 .../lib/custom-action-registration.ts         | 45 ++++++++++---------
 .../@aws-cdk/aws-codepipeline/lib/index.ts    |  1 +
 5 files changed, 62 insertions(+), 22 deletions(-)
 rename packages/@aws-cdk/{aws-codepipeline-actions => aws-codepipeline}/lib/custom-action-registration.ts (76%)

diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/index.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/index.ts
index 254b2764f2684..e861161ab39c1 100644
--- a/packages/@aws-cdk/aws-codepipeline-actions/lib/index.ts
+++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/index.ts
@@ -18,3 +18,4 @@ export * from './s3/source-action';
 export * from './stepfunctions/invoke-action';
 export * from './servicecatalog/deploy-action-beta1';
 export * from './action';
+
diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-provider.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-provider.ts
index 923b1a1e39e7c..6e0d179859916 100644
--- a/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-provider.ts
+++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-provider.ts
@@ -1,7 +1,6 @@
 import * as codepipeline from '@aws-cdk/aws-codepipeline';
 import * as cdk from '@aws-cdk/core';
 import { Construct } from 'constructs';
-import { CustomActionRegistration } from '../custom-action-registration';
 
 // keep this import separate from other imports to reduce chance for merge conflicts with v2-main
 // eslint-disable-next-line no-duplicate-imports, import/order
@@ -190,7 +189,7 @@ export class JenkinsProvider extends BaseJenkinsProvider {
   }
 
   private registerJenkinsCustomAction(id: string, category: codepipeline.ActionCategory) {
-    new CustomActionRegistration(this, id, {
+    new codepipeline.CustomActionRegistration(this, id, {
       category,
       artifactBounds: jenkinsArtifactsBounds,
       provider: this.providerName,
diff --git a/packages/@aws-cdk/aws-codepipeline/README.md b/packages/@aws-cdk/aws-codepipeline/README.md
index 23f86b9293e92..976c9932ca210 100644
--- a/packages/@aws-cdk/aws-codepipeline/README.md
+++ b/packages/@aws-cdk/aws-codepipeline/README.md
@@ -109,6 +109,40 @@ or you can use the `IStage.addAction()` method to mutate an existing Stage:
 sourceStage.addAction(someAction);
 ```
 
+## Custom Action Registration
+
+To make your own custom CodePipeline Action requires registering the action provider. Look to the `JenkinsProvider` in `@aws-cdk/aws-codepipeline-actions` for an implementation example.
+
+```ts
+new codepipeline.CustomActionRegistration(this, 'GenericGitSourceProviderResource', {
+  category: codepipeline.ActionCategory.SOURCE,
+  artifactBounds: { minInputs: 0, maxInputs: 0, minOutputs: 1, maxOutputs: 1 },
+  provider: 'GenericGitSource',
+  version: '1',
+  entityUrl: 'https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-create-custom-action.html',
+  executionUrl: 'https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-create-custom-action.html',
+  actionProperties: [
+    {
+      name: 'Branch',
+      required: true,
+      key: false,
+      secret: false,
+      queryable: false,
+      description: 'Git branch to pull',
+      type: 'String',
+    },
+    {
+      name: 'GitUrl',
+      required: true,
+      key: false,
+      secret: false,
+      queryable: false,
+      description: 'SSH git clone URL',
+      type: 'String',
+    },
+  ]
+```
+
 ## Cross-account CodePipelines
 
 > Cross-account Pipeline actions require that the Pipeline has *not* been
diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/custom-action-registration.ts b/packages/@aws-cdk/aws-codepipeline/lib/custom-action-registration.ts
similarity index 76%
rename from packages/@aws-cdk/aws-codepipeline-actions/lib/custom-action-registration.ts
rename to packages/@aws-cdk/aws-codepipeline/lib/custom-action-registration.ts
index dad9e84a47094..f32a952a24d83 100644
--- a/packages/@aws-cdk/aws-codepipeline-actions/lib/custom-action-registration.ts
+++ b/packages/@aws-cdk/aws-codepipeline/lib/custom-action-registration.ts
@@ -1,8 +1,10 @@
-import * as codepipeline from '@aws-cdk/aws-codepipeline';
+import { Construct } from 'constructs';
+import { ActionCategory, ActionArtifactBounds } from './action';
+import { CfnCustomActionType } from './codepipeline.generated';
 
 // keep this import separate from other imports to reduce chance for merge conflicts with v2-main
 // eslint-disable-next-line no-duplicate-imports, import/order
-import { Construct } from '@aws-cdk/core';
+import { Construct as CoreConstruct } from '@aws-cdk/core';
 
 /**
  * The creation attributes used for defining a configuration property
@@ -13,14 +15,14 @@ export interface CustomActionProperty {
    * The name of the property.
    * You use this name in the `configuration` attribute when defining your custom Action class.
    */
-  name: string;
+  readonly name: string;
 
   /**
    * The description of the property.
    *
    * @default the description will be empty
    */
-  description?: string;
+  readonly description?: string;
 
   /**
    * Whether this property is a key.
@@ -28,7 +30,7 @@ export interface CustomActionProperty {
    * @default false
    * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codepipeline-customactiontype-configurationproperties.html#cfn-codepipeline-customactiontype-configurationproperties-key
    */
-  key?: boolean;
+  readonly key?: boolean;
 
   /**
    * Whether this property is queryable.
@@ -37,12 +39,12 @@ export interface CustomActionProperty {
    * @default false
    * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codepipeline-customactiontype-configurationproperties.html#cfn-codepipeline-customactiontype-configurationproperties-queryable
    */
-  queryable?: boolean;
+  readonly queryable?: boolean;
 
   /**
    * Whether this property is required.
    */
-  required: boolean;
+  readonly required: boolean;
 
   /**
    * Whether this property is secret,
@@ -50,7 +52,7 @@ export interface CustomActionProperty {
    *
    * @default false
    */
-  secret?: boolean;
+  readonly secret?: boolean;
 
   /**
    * The type of the property,
@@ -58,7 +60,7 @@ export interface CustomActionProperty {
    *
    * @default 'String'
    */
-  type?: string;
+  readonly type?: string;
 }
 
 /**
@@ -68,41 +70,44 @@ export interface CustomActionRegistrationProps {
   /**
    * The category of the Action.
    */
-  category: codepipeline.ActionCategory;
+  readonly category: ActionCategory;
 
   /**
    * The artifact bounds of the Action.
    */
-  artifactBounds: codepipeline.ActionArtifactBounds;
+  readonly artifactBounds: ActionArtifactBounds;
 
   /**
    * The provider of the Action.
+   * @example 'MyCustomActionProvider'
    */
-  provider: string;
+  readonly provider: string;
 
   /**
    * The version of your Action.
    *
    * @default '1'
    */
-  version?: string;
+  readonly version?: string;
 
   /**
    * The URL shown for the entire Action in the Pipeline UI.
+   * @default none
    */
-  entityUrl?: string;
+  readonly entityUrl?: string;
 
   /**
    * The URL shown for a particular execution of an Action in the Pipeline UI.
+   * @default none
    */
-  executionUrl?: string;
+  readonly executionUrl?: string;
 
   /**
    * The properties used for customizing the instance of your Action.
    *
    * @default []
    */
-  actionProperties?: CustomActionProperty[];
+  readonly actionProperties?: CustomActionProperty[];
 }
 
 /**
@@ -112,11 +117,11 @@ export interface CustomActionRegistrationProps {
  * representing your custom Action, extending the Action class,
  * and taking the `actionProperties` as properly typed, construction properties.
  */
-export class CustomActionRegistration extends Construct {
-  constructor(parent: Construct, id: string, props: CustomActionRegistrationProps) {
-    super(parent, id);
+export class CustomActionRegistration extends CoreConstruct {
+  constructor(scope: Construct, id: string, props: CustomActionRegistrationProps) {
+    super(scope, id);
 
-    new codepipeline.CfnCustomActionType(this, 'Resource', {
+    new CfnCustomActionType(this, 'Resource', {
       category: props.category,
       inputArtifactDetails: {
         minimumCount: props.artifactBounds.minInputs,
diff --git a/packages/@aws-cdk/aws-codepipeline/lib/index.ts b/packages/@aws-cdk/aws-codepipeline/lib/index.ts
index c62d8dda6b33f..81b855f904184 100644
--- a/packages/@aws-cdk/aws-codepipeline/lib/index.ts
+++ b/packages/@aws-cdk/aws-codepipeline/lib/index.ts
@@ -1,6 +1,7 @@
 export * from './action';
 export * from './artifact';
 export * from './pipeline';
+export * from './custom-action-registration';
 
 // AWS::CodePipeline CloudFormation Resources:
 export * from './codepipeline.generated';

From 7bbd10deb322daf8ef1504ceb84ad3c895f291ae Mon Sep 17 00:00:00 2001
From: Ryan Parker 
Date: Thu, 4 Nov 2021 17:42:07 -0700
Subject: [PATCH 139/148] fix(aws-eks): proxy support and allow assigning a
 security group to all cluster handler functions (#17200)

## Summary

This PR is intended for CDK EKS users who require all traffic to be routed through a proxy. Currently if a user does not allow internet connections to the VPC without going through a proxy, then deploying an EKS cluster will result in a timeout error:

```sh
Received response status [FAILED] from custom resource. Message returned: Error: 2021-10-20T14:20:47.028Z d86e3ef4-45ce-4130-988f-c4663f7f8c80 Task timed out after 60.06 seconds
```
Fixes: https://github.com/aws/aws-cdk/issues/12469, SIM D29159517
Related to but does not resolve: `https://github.com/aws/aws-cdk/issues/12171`

## :gear: Changes

_Expand each list item for additional details._

Corrected "Cluster Handler" docs to clarify that 2 lambdas are created (onEventHandler, isCompleteHandler)
Our docs [currently describe the "Cluster Handler" as one Lambda function that interacts with the EKS API](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-eks-readme.html#cluster-handler). However this is not accurate. The "Cluster Handler" actually creates [two Lambdas](https://github.com/aws/aws-cdk/blob/0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21/packages/%40aws-cdk/aws-eks/lib/cluster-resource-provider.ts#L69-L96) for the Custom Resource, `onEventHandler` and `isCompleteHandler`, both interact with the AWS API.
Passes the clusterHandlerEnvironment to both Cluster Handler Lambdas
The `clusterHandlerEnvironment` is the [recommended method](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-eks-readme.html#cluster-handler) of passing a proxy url (i.g. `http_proxy: 'http://my-proxy.com:3128'`) to the Cluster Handler. Currently the `clusterHandlerEnvironment` is only passed to the Cluster Handler's `onEventHandler` Lambda. [The `onEventHandler` was believed to be the only Cluster Handler Lambda that interacts with the AWS EKS API](https://github.com/aws/aws-cdk/issues/12469#issuecomment-758674418), however this is not entirely true. Both the `onEventHandler` and `isCompleteHandler` call the AWS EKS API. Following the execution process of `isCompleteHandler` when creating an EKS cluster: 1. [`index.isComplete()` (this is the Lambda handler)](https://github.com/aws/aws-cdk/blob/0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21/packages/%40aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts#L48) 2. [`common.isComplete()`](https://github.com/aws/aws-cdk/blob/0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21/packages/%40aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts#L59) 3. [`cluster.isCreateComplete()`](https://github.com/aws/aws-cdk/blob/0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21/packages/%40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L56) 4. [`cluster.isActive()`](https://github.com/aws/aws-cdk/blob/0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21/packages/%40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L196) 5. [Request to EKS API](https://github.com/aws/aws-cdk/blob/0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21/packages/%40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L198) (results in timeout because proxy is not used) This change allows the user to pass proxy urls as environment variables to **both** Lambdas using `clusterHandlerEnvironment`.
Renames the prop onEventLayer -> proxyAgentLayer, and provides the layer to both Cluster Handler Lambdas
The proxy-agent layer is now used in both `onEventHandler` and `isCompleteHandler` lambdas in order to support proxy configurations. Because of this change, i've deprecated the original `onEventLayer` and created a new prop `proxyAgentLayer` since we will now be passing this prop into more than just the `onEventHandler` Lambda. The `onEventLayer` prop was introduced [a few weeks ago (sept 24)](https://github.com/aws/aws-cdk/pull/16657) so it should not impact many users (if any). The prop would only be used if the user wishes to bundle the layer themselves with a custom proxy agent. This prop follows the [same user customization we allow with the kubectl handler](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-eks.Cluster.html#kubectllayer). Another suitable name for this prop could have been `clusterHandlerLayer` but I chose `proxyAgentLayer` because it represents **what** the layer is used for, instead of describing **where** it's used. This also follows the convention of the pre-existing [`kubectlLayer` prop](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-eks.Cluster.html#kubectllayer).
Adds the EKS cluster prop clusterHandlerSecurityGroup
If a proxy address is provided to the Cluster Handler Lambdas, but the proxy instance is not open to the world, then the dynamic IPs of the Cluster Handler Lambdas will be denied access. To solve this, i've implemented a new Cluster prop `clusterHandlerSecurityGroup`. This `clusterHandlerSecurityGroup` prop will allow the user to pass a Security Group to both Lambda functions and the Custom Resource provider. This is very similar to how we [already allow users to pass Security Groups to the Kubectl Handler](https://github.com/aws/aws-cdk/blob/7f194000697b85deb410ae0d7f7d4ac3c2654bcc/packages/%40aws-cdk/aws-eks/lib/kubectl-provider.ts#L83)
---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-eks/README.md | 17 ++-- .../lib/cluster-resource-handler/common.ts | 6 -- .../lib/cluster-resource-handler/index.ts | 6 ++ .../aws-eks/lib/cluster-resource-provider.ts | 33 ++++--- .../@aws-cdk/aws-eks/lib/cluster-resource.ts | 2 + packages/@aws-cdk/aws-eks/lib/cluster.ts | 96 ++++++++++++++----- packages/@aws-cdk/aws-eks/package.json | 2 - .../@aws-cdk/aws-eks/test/cluster.test.ts | 34 +++++++ 8 files changed, 145 insertions(+), 51 deletions(-) diff --git a/packages/@aws-cdk/aws-eks/README.md b/packages/@aws-cdk/aws-eks/README.md index cd6e324ecf788..e1d78b774450d 100644 --- a/packages/@aws-cdk/aws-eks/README.md +++ b/packages/@aws-cdk/aws-eks/README.md @@ -102,8 +102,8 @@ The following is a qualitative diagram of the various possible components involv ```text +-----------------------------------------------+ +-----------------+ - | EKS Cluster | kubectl | | - |-----------------------------------------------|<-------------+| Kubectl Handler | + | EKS Cluster | kubectl | | + | ----------- |<-------------+| Kubectl Handler | | | | | | | +-----------------+ | +--------------------+ +-----------------+ | @@ -539,16 +539,21 @@ If the endpoint does not expose private access (via `EndpointAccess.PUBLIC`) **o #### Cluster Handler -The `ClusterHandler` is a Lambda function responsible to interact with the EKS API in order to control the cluster lifecycle. To provision this function inside the VPC, set the `placeClusterHandlerInVpc` property to `true`. This will place the function inside the private subnets of the VPC based on the selection strategy specified in the [`vpcSubnets`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-eks.Cluster.html#vpcsubnetsspan-classapi-icon-api-icon-experimental-titlethis-api-element-is-experimental-it-may-change-without-noticespan) property. +The `ClusterHandler` is a set of Lambda functions (`onEventHandler`, `isCompleteHandler`) responsible for interacting with the EKS API in order to control the cluster lifecycle. To provision these functions inside the VPC, set the `placeClusterHandlerInVpc` property to `true`. This will place the functions inside the private subnets of the VPC based on the selection strategy specified in the [`vpcSubnets`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-eks.Cluster.html#vpcsubnetsspan-classapi-icon-api-icon-experimental-titlethis-api-element-is-experimental-it-may-change-without-noticespan) property. -You can configure the environment of this function by specifying it at cluster instantiation. For example, this can be useful in order to configure an http proxy: +You can configure the environment of the Cluster Handler functions by specifying it at cluster instantiation. For example, this can be useful in order to configure an http proxy: ```ts const cluster = new eks.Cluster(this, 'hello-eks', { version: eks.KubernetesVersion.V1_21, clusterHandlerEnvironment: { - 'http_proxy': 'http://proxy.myproxy.com' - } + https_proxy: 'http://proxy.myproxy.com' + }, + /** + * If the proxy is not open publicly, you can pass a security group to the + * Cluster Handler Lambdas so that it can reach the proxy. + */ + clusterHandlerSecurityGroup: proxyInstanceSecurityGroup }); ``` diff --git a/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts b/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts index 8f563de833bf6..21cf958df5a68 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts @@ -41,12 +41,6 @@ export abstract class ResourceHandler { } public onEvent() { - // eslint-disable-next-line @typescript-eslint/no-require-imports, import/no-extraneous-dependencies - const ProxyAgent: any = require('proxy-agent'); - aws.config.update({ - httpOptions: { agent: new ProxyAgent() }, - }); - switch (this.requestType) { case 'Create': return this.onCreate(); case 'Update': return this.onUpdate(); diff --git a/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts b/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts index e7fc357846259..258f5d8b04545 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts @@ -8,7 +8,13 @@ import { EksClient } from './common'; import * as consts from './consts'; import { FargateProfileResourceHandler } from './fargate'; +// eslint-disable-next-line @typescript-eslint/no-require-imports, import/no-extraneous-dependencies +const ProxyAgent = require('proxy-agent'); + aws.config.logger = console; +aws.config.update({ + httpOptions: { agent: new ProxyAgent() }, +}); let eks: aws.EKS | undefined; diff --git a/packages/@aws-cdk/aws-eks/lib/cluster-resource-provider.ts b/packages/@aws-cdk/aws-eks/lib/cluster-resource-provider.ts index f425b0a1eaba6..9bb65be4f56b2 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster-resource-provider.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster-resource-provider.ts @@ -36,11 +36,18 @@ export interface ClusterResourceProviderProps { readonly environment?: { [key: string]: string }; /** - * An AWS Lambda layer that includes the NPM dependency `proxy-agent`. - * - * If not defined, a default layer will be used. - */ + * An AWS Lambda layer that includes the NPM dependency `proxy-agent`. + * + * If not defined, a default layer will be used. + */ readonly onEventLayer?: lambda.ILayerVersion; + + /** + * The security group to associate with the functions. + * + * @default - No security group. + */ + readonly securityGroup?: ec2.ISecurityGroup; } /** @@ -66,6 +73,9 @@ export class ClusterResourceProvider extends NestedStack { private constructor(scope: Construct, id: string, props: ClusterResourceProviderProps) { super(scope as CoreConstruct, id); + // The NPM dependency proxy-agent is required in order to support proxy routing with the AWS JS SDK. + const nodeProxyAgentLayer = new NodeProxyAgentLayer(this, 'NodeProxyAgentLayer'); + const onEvent = new lambda.Function(this, 'OnEventHandler', { code: lambda.Code.fromAsset(HANDLER_DIR), description: 'onEvent handler for EKS cluster resource provider', @@ -75,24 +85,22 @@ export class ClusterResourceProvider extends NestedStack { timeout: Duration.minutes(1), vpc: props.subnets ? props.vpc : undefined, vpcSubnets: props.subnets ? { subnets: props.subnets } : undefined, + securityGroups: props.securityGroup ? [props.securityGroup] : undefined, + // Allow user to override the layer. + layers: props.onEventLayer ? [props.onEventLayer] : [nodeProxyAgentLayer], }); - // Allow user to customize the layer - if (!props.onEventLayer) { - // `NodeProxyAgentLayer` provides `proxy-agent` which is needed to configure `aws-sdk-js` with a user provided proxy. - onEvent.addLayers(new NodeProxyAgentLayer(this, 'NodeProxyAgentLayer')); - } else { - onEvent.addLayers(props.onEventLayer); - } - const isComplete = new lambda.Function(this, 'IsCompleteHandler', { code: lambda.Code.fromAsset(HANDLER_DIR), description: 'isComplete handler for EKS cluster resource provider', runtime: HANDLER_RUNTIME, + environment: props.environment, handler: 'index.isComplete', timeout: Duration.minutes(1), vpc: props.subnets ? props.vpc : undefined, vpcSubnets: props.subnets ? { subnets: props.subnets } : undefined, + securityGroups: props.securityGroup ? [props.securityGroup] : undefined, + layers: [nodeProxyAgentLayer], }); this.provider = new cr.Provider(this, 'Provider', { @@ -102,6 +110,7 @@ export class ClusterResourceProvider extends NestedStack { queryInterval: Duration.minutes(1), vpc: props.subnets ? props.vpc : undefined, vpcSubnets: props.subnets ? { subnets: props.subnets } : undefined, + securityGroups: props.securityGroup ? [props.securityGroup] : undefined, }); props.adminRole.grant(onEvent.role!, 'sts:AssumeRole'); diff --git a/packages/@aws-cdk/aws-eks/lib/cluster-resource.ts b/packages/@aws-cdk/aws-eks/lib/cluster-resource.ts index 88f3cd0138344..ed0852338a527 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster-resource.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster-resource.ts @@ -27,6 +27,7 @@ export interface ClusterResourceProps { readonly subnets?: ec2.ISubnet[]; readonly secretsEncryptionKey?: kms.IKey; readonly onEventLayer?: lambda.ILayerVersion; + readonly clusterHandlerSecurityGroup?: ec2.ISecurityGroup; } /** @@ -66,6 +67,7 @@ export class ClusterResource extends CoreConstruct { vpc: props.vpc, environment: props.environment, onEventLayer: props.onEventLayer, + securityGroup: props.clusterHandlerSecurityGroup, }); const resource = new CustomResource(this, 'Resource', { diff --git a/packages/@aws-cdk/aws-eks/lib/cluster.ts b/packages/@aws-cdk/aws-eks/lib/cluster.ts index c1d00a9dcd767..2c762ab666327 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster.ts @@ -130,10 +130,21 @@ export interface ICluster extends IResource, ec2.IConnectable { readonly kubectlMemory?: Size; /** - * An AWS Lambda layer that includes the NPM dependency `proxy-agent`. - * - * If not defined, a default layer will be used. - */ + * A security group to associate with the Cluster Handler's Lambdas. + * The Cluster Handler's Lambdas are responsible for calling AWS's EKS API. + * + * Requires `placeClusterHandlerInVpc` to be set to true. + * + * @default - No security group. + * @attribute + */ + readonly clusterHandlerSecurityGroup?: ec2.ISecurityGroup; + + /** + * An AWS Lambda layer that includes the NPM dependency `proxy-agent`. + * + * If not defined, a default layer will be used. + */ readonly onEventLayer?: lambda.ILayerVersion; /** @@ -309,6 +320,14 @@ export interface ClusterAttributes { */ readonly kubectlMemory?: Size; + /** + * A security group id to associate with the Cluster Handler's Lambdas. + * The Cluster Handler's Lambdas are responsible for calling AWS's EKS API. + * + * @default - No security group. + */ + readonly clusterHandlerSecurityGroupId?: string; + /** * An AWS Lambda Layer which includes the NPM dependency `proxy-agent`. This layer * is used by the onEvent handler to route AWS SDK requests through a proxy. @@ -452,13 +471,6 @@ export interface ClusterOptions extends CommonClusterOptions { */ readonly kubectlEnvironment?: { [key: string]: string }; - /** - * Custom environment variables when interacting with the EKS endpoint to manage the cluster lifecycle. - * - * @default - No environment variables. - */ - readonly clusterHandlerEnvironment?: { [key: string]: string }; - /** * An AWS Lambda Layer which includes `kubectl`, Helm and the AWS CLI. * @@ -491,26 +503,40 @@ export interface ClusterOptions extends CommonClusterOptions { readonly kubectlMemory?: Size; /** - * An AWS Lambda Layer which includes the NPM dependency `proxy-agent`. + * Custom environment variables when interacting with the EKS endpoint to manage the cluster lifecycle. + * + * @default - No environment variables. + */ + readonly clusterHandlerEnvironment?: { [key: string]: string }; + + /** + * A security group to associate with the Cluster Handler's Lambdas. + * The Cluster Handler's Lambdas are responsible for calling AWS's EKS API. + * + * Requires `placeClusterHandlerInVpc` to be set to true. + * + * @default - No security group. + */ + readonly clusterHandlerSecurityGroup?: ec2.ISecurityGroup; + + /** + * An AWS Lambda Layer which includes the NPM dependency `proxy-agent`. This layer + * is used by the onEvent handler to route AWS SDK requests through a proxy. * * By default, the provider will use the layer included in the * "aws-lambda-layer-node-proxy-agent" SAR application which is available in all * commercial regions. * - * To deploy the layer locally, visit - * https://github.com/aws-samples/aws-lambda-layer-node-proxy-agent/blob/master/cdk/README.md - * for instructions on how to prepare the .zip file and then define it in your - * app as follows: + * To deploy the layer locally define it in your app as follows: * * ```ts - * const layer = new lambda.LayerVersion(this, 'node-proxy-agent-layer', { + * const layer = new lambda.LayerVersion(this, 'proxy-agent-layer', { * code: lambda.Code.fromAsset(`${__dirname}/layer.zip`)), - * compatibleRuntimes: [lambda.Runtime.NODEJS_14_X] + * compatibleRuntimes: [lambda.Runtime.NODEJS_12_X] * }) * ``` * - * @default - the layer provided by the `aws-lambda-layer-node-proxy-agent` SAR app. - * @see https://github.com/aws-samples/aws-lambda-layer-node-proxy-agent + * @default - a layer bundled with this module. */ readonly onEventLayer?: lambda.ILayerVersion; @@ -749,6 +775,7 @@ abstract class ClusterBase extends Resource implements ICluster { public abstract readonly kubectlSecurityGroup?: ec2.ISecurityGroup; public abstract readonly kubectlPrivateSubnets?: ec2.ISubnet[]; public abstract readonly kubectlMemory?: Size; + public abstract readonly clusterHandlerSecurityGroup?: ec2.ISecurityGroup; public abstract readonly prune: boolean; public abstract readonly openIdConnectProvider: iam.IOpenIdConnectProvider; public abstract readonly awsAuth: AwsAuth; @@ -902,7 +929,7 @@ abstract class ClusterBase extends Resource implements ICluster { // cluster or if `mapRole` is set to false. By default this should happen. let mapRole = options.mapRole ?? true; if (mapRole && !(this instanceof Cluster)) { - // do the mapping... + // do the mapping... Annotations.of(autoScalingGroup).addWarning('Auto-mapping aws-auth role for imported cluster is not supported, please map role manually'); mapRole = false; } @@ -1099,11 +1126,21 @@ export class Cluster extends ClusterBase { */ public readonly kubectlMemory?: Size; + /** + * A security group to associate with the Cluster Handler's Lambdas. + * The Cluster Handler's Lambdas are responsible for calling AWS's EKS API. + * + * Requires `placeClusterHandlerInVpc` to be set to true. + * + * @default - No security group. + */ + public readonly clusterHandlerSecurityGroup?: ec2.ISecurityGroup; + /** * The AWS Lambda layer that contains the NPM dependency `proxy-agent`. If * undefined, a SAR app that contains this layer will be used. */ - public readonly onEventLayer?: lambda.ILayerVersion; + readonly onEventLayer?: lambda.ILayerVersion; /** * Determines if Kubernetes resources can be pruned automatically. @@ -1188,9 +1225,11 @@ export class Cluster extends ClusterBase { this.endpointAccess = props.endpointAccess ?? EndpointAccess.PUBLIC_AND_PRIVATE; this.kubectlEnvironment = props.kubectlEnvironment; this.kubectlLayer = props.kubectlLayer; - this.onEventLayer = props.onEventLayer; this.kubectlMemory = props.kubectlMemory; + this.onEventLayer = props.onEventLayer; + this.clusterHandlerSecurityGroup = props.clusterHandlerSecurityGroup; + const privateSubnets = this.selectPrivateSubnets().slice(0, 16); const publicAccessDisabled = !this.endpointAccess._config.publicAccess; const publicAccessRestricted = !publicAccessDisabled @@ -1215,6 +1254,10 @@ export class Cluster extends ClusterBase { throw new Error('Cannot place cluster handler in the VPC since no private subnets could be selected'); } + if (props.clusterHandlerSecurityGroup && !placeClusterHandlerInVpc) { + throw new Error('Cannot specify clusterHandlerSecurityGroup without placeClusterHandlerInVpc set to true'); + } + const resource = this._clusterResource = new ClusterResource(this, 'Resource', { name: this.physicalName, environment: props.clusterHandlerEnvironment, @@ -1241,6 +1284,7 @@ export class Cluster extends ClusterBase { secretsEncryptionKey: props.secretsEncryptionKey, vpc: this.vpc, subnets: placeClusterHandlerInVpc ? privateSubnets : undefined, + clusterHandlerSecurityGroup: this.clusterHandlerSecurityGroup, onEventLayer: this.onEventLayer, }); @@ -1827,8 +1871,9 @@ class ImportedCluster extends ClusterBase { public readonly kubectlSecurityGroup?: ec2.ISecurityGroup | undefined; public readonly kubectlPrivateSubnets?: ec2.ISubnet[] | undefined; public readonly kubectlLayer?: lambda.ILayerVersion; - public readonly onEventLayer?: lambda.ILayerVersion; public readonly kubectlMemory?: Size; + public readonly clusterHandlerSecurityGroup?: ec2.ISecurityGroup | undefined; + public readonly onEventLayer?: lambda.ILayerVersion; public readonly prune: boolean; // so that `clusterSecurityGroup` on `ICluster` can be configured without optionality, avoiding users from having @@ -1845,8 +1890,9 @@ class ImportedCluster extends ClusterBase { this.kubectlEnvironment = props.kubectlEnvironment; this.kubectlPrivateSubnets = props.kubectlPrivateSubnetIds ? props.kubectlPrivateSubnetIds.map((subnetid, index) => ec2.Subnet.fromSubnetId(this, `KubectlSubnet${index}`, subnetid)) : undefined; this.kubectlLayer = props.kubectlLayer; - this.onEventLayer = props.onEventLayer; this.kubectlMemory = props.kubectlMemory; + this.clusterHandlerSecurityGroup = props.clusterHandlerSecurityGroupId ? ec2.SecurityGroup.fromSecurityGroupId(this, 'ClusterHandlerSecurityGroup', props.clusterHandlerSecurityGroupId) : undefined; + this.onEventLayer = props.onEventLayer; this.prune = props.prune ?? true; let i = 1; diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json index e5c7869f9bc13..35db07123cae8 100644 --- a/packages/@aws-cdk/aws-eks/package.json +++ b/packages/@aws-cdk/aws-eks/package.json @@ -93,7 +93,6 @@ "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kms": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", - "@aws-cdk/aws-lambda-nodejs": "0.0.0", "@aws-cdk/aws-ssm": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/custom-resources": "0.0.0", @@ -113,7 +112,6 @@ "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kms": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", - "@aws-cdk/aws-lambda-nodejs": "0.0.0", "@aws-cdk/aws-ssm": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/custom-resources": "0.0.0", diff --git a/packages/@aws-cdk/aws-eks/test/cluster.test.ts b/packages/@aws-cdk/aws-eks/test/cluster.test.ts index 295092509ffd2..63a17d9c5d64d 100644 --- a/packages/@aws-cdk/aws-eks/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-eks/test/cluster.test.ts @@ -38,6 +38,25 @@ describe('cluster', () => { expect(template.Resources.OnEventHandler42BEBAE0.Properties.Environment).toEqual({ Variables: { foo: 'bar' } }); }); + test('can specify security group to cluster resource handler', () => { + const { stack, vpc } = testFixture(); + const securityGroup = new ec2.SecurityGroup(stack, 'ProxyInstanceSG', { + vpc, + allowAllOutbound: false, + }); + + new eks.Cluster(stack, 'Cluster', { + version: CLUSTER_VERSION, + placeClusterHandlerInVpc: true, + clusterHandlerSecurityGroup: securityGroup, + }); + + const nested = stack.node.tryFindChild('@aws-cdk/aws-eks.ClusterResourceProvider') as cdk.NestedStack; + + const template = SynthUtils.toCloudFormation(nested); + expect(template.Resources.OnEventHandler42BEBAE0.Properties.VpcConfig.SecurityGroupIds).toEqual([{ Ref: 'referencetoStackProxyInstanceSG80B79D87GroupId' }]); + }); + test('throws when trying to place cluster handlers in a vpc with no private subnets', () => { const { stack } = testFixture(); @@ -55,6 +74,21 @@ describe('cluster', () => { }); + test('throws when provided `clusterHandlerSecurityGroup` without `placeClusterHandlerInVpc: true`', () => { + const { stack, vpc } = testFixture(); + const securityGroup = new ec2.SecurityGroup(stack, 'ProxyInstanceSG', { + vpc, + allowAllOutbound: false, + }); + + expect(() => { + new eks.Cluster(stack, 'Cluster', { + version: CLUSTER_VERSION, + clusterHandlerSecurityGroup: securityGroup, + }); + }).toThrow(/Cannot specify clusterHandlerSecurityGroup without placeClusterHandlerInVpc set to true/); + }); + describe('imported Vpc from unparseable list tokens', () => { let stack: cdk.Stack; let vpc: ec2.IVpc; From 0adc8b7e13011956929fc945e083f75edec16698 Mon Sep 17 00:00:00 2001 From: Adam Ruka Date: Thu, 4 Nov 2021 19:33:59 -0700 Subject: [PATCH 140/148] feat(cli): introduce the 'watch' command (#17240) This PR introduces the "watch" command, in two variants: as a separate new `cdk watch` command, and as an argument to the existing `cdk deploy` command. The "watch" process will observe the project files, defined by the new `"include"` and `"exclude"` settings in `cdk.json` (see https://github.com/aws/aws-cdk-rfcs/pull/383 for details), and will trigger a `cdk deploy` when it detects any changes. The deployment will by default use the new "hotswap" deployments for maximum speed. Since `cdk deploy` is a relatively slow process for a "watch" command, there is some logic to perform intelligent queuing of any file events that happen while `cdk deploy` is running. We will batch all of those events, and trigger a single `cdk deploy` after the current one finishes. This ensures only a single `cdk deploy` command ever executes at a time. The observing of the files, and reacting to their changes, is accomplished using the [`chokidar` library](https://www.npmjs.com/package/chokidar). ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/README.md | 63 ++++++ packages/aws-cdk/bin/cdk.ts | 59 +++++ .../lib/api/cloudformation-deployments.ts | 2 +- .../aws-cdk/lib/api/cxapp/cloud-executable.ts | 10 +- packages/aws-cdk/lib/api/deploy-stack.ts | 2 +- packages/aws-cdk/lib/cdk-toolkit.ts | 214 ++++++++++++++---- packages/aws-cdk/package.json | 1 + packages/aws-cdk/test/cdk-toolkit.test.ts | 190 ++++++++++++++++ yarn.lock | 48 +++- 9 files changed, 535 insertions(+), 54 deletions(-) diff --git a/packages/aws-cdk/README.md b/packages/aws-cdk/README.md index 0a2270b08fc90..1bd9e491e34e4 100644 --- a/packages/aws-cdk/README.md +++ b/packages/aws-cdk/README.md @@ -372,6 +372,69 @@ For this reason, only use it for development purposes. **โš  Note #2**: This command is considered experimental, and might have breaking changes in the future. +### `cdk watch` + +The `watch` command is similar to `deploy`, +but instead of being a one-shot operation, +the command continuously monitors the files of the project, +and triggers a deployment whenever it detects any changes: + +```console +$ cdk watch DevelopmentStack +Detected change to 'lambda-code/index.js' (type: change). Triggering 'cdk deploy' +DevelopmentStack: deploying... + + โœ… DevelopmentStack + +^C +``` + +To end a `cdk watch` session, interrupt the process by pressing Ctrl+C. + +What files are observed is determined by the `"watch"` setting in your `cdk.json` file. +It has two sub-keys, `"include"` and `"exclude"`, each of which can be either a single string, or an array of strings. +Each entry is interpreted as a path relative to the location of the `cdk.json` file. +Globs, both `*` and `**`, are allowed to be used. +Example: + +```json +{ + "app": "mvn -e -q compile exec:java", + "watch": { + "include": "src/main/**", + "exclude": "target/*" + } +} +``` + +The default for `"include"` is `"**/*"` +(which means all files and directories in the root of the project), +and `"exclude"` is optional +(note that we always ignore files and directories starting with `.`, +the CDK output directory, and the `node_modules` directory), +so the minimal settings to enable `watch` are `"watch": {}`. + +If either your CDK code, or application code, needs a build step before being deployed, +`watch` works with the `"build"` key in the `cdk.json` file, +for example: + +```json +{ + "app": "mvn -e -q exec:java", + "build": "mvn package", + "watch": { + "include": "src/main/**", + "exclude": "target/*" + } +} +``` + +Note that `watch` by default uses hotswap deployments (see above for details) -- +to turn them off, pass the `--no-hotswap` option when invoking it. + +**Note**: This command is considered experimental, +and might have breaking changes in the future. + ### `cdk destroy` Deletes a stack from it's environment. This will cause the resources in the stack to be destroyed (unless they were diff --git a/packages/aws-cdk/bin/cdk.ts b/packages/aws-cdk/bin/cdk.ts index b5b60f895c8ca..a938b00f3c02f 100644 --- a/packages/aws-cdk/bin/cdk.ts +++ b/packages/aws-cdk/bin/cdk.ts @@ -118,6 +118,45 @@ async function parseCommandLineArguments() { 'which skips CloudFormation and updates the resources directly, ' + 'and falls back to a full deployment if that is not possible. ' + 'Do not use this in production environments', + }) + .option('watch', { + type: 'boolean', + desc: 'Continuously observe the project files, ' + + 'and deploy the given stack(s) automatically when changes are detected. ' + + 'Implies --hotswap by default', + }), + ) + .command('watch [STACKS..]', "Shortcut for 'deploy --watch'", yargs => yargs + // I'm fairly certain none of these options, present for 'deploy', make sense for 'watch': + // .option('all', { type: 'boolean', default: false, desc: 'Deploy all available stacks' }) + // .option('ci', { type: 'boolean', desc: 'Force CI detection', default: process.env.CI !== undefined }) + // @deprecated(v2) -- tags are part of the Cloud Assembly and tags specified here will be overwritten on the next deployment + // .option('tags', { type: 'array', alias: 't', desc: 'Tags to add to the stack (KEY=VALUE), overrides tags from Cloud Assembly (deprecated)', nargs: 1, requiresArg: true }) + // .option('execute', { type: 'boolean', desc: 'Whether to execute ChangeSet (--no-execute will NOT execute the ChangeSet)', default: true }) + // These options, however, are more subtle - I could be convinced some of these should also be available for 'watch': + // .option('require-approval', { type: 'string', choices: [RequireApproval.Never, RequireApproval.AnyChange, RequireApproval.Broadening], desc: 'What security-sensitive changes need manual approval' }) + // .option('parameters', { type: 'array', desc: 'Additional parameters passed to CloudFormation at deploy time (STACK:KEY=VALUE)', nargs: 1, requiresArg: true, default: {} }) + // .option('previous-parameters', { type: 'boolean', default: true, desc: 'Use previous values for existing parameters (you must specify all parameters on every deployment if this is disabled)' }) + // .option('outputs-file', { type: 'string', alias: 'O', desc: 'Path to file where stack outputs will be written as JSON', requiresArg: true }) + // .option('notification-arns', { type: 'array', desc: 'ARNs of SNS topics that CloudFormation will notify with stack related events', nargs: 1, requiresArg: true }) + .option('build-exclude', { type: 'array', alias: 'E', nargs: 1, desc: 'Do not rebuild asset with the given ID. Can be specified multiple times', default: [] }) + .option('exclusively', { type: 'boolean', alias: 'e', desc: 'Only deploy requested stacks, don\'t include dependencies' }) + .option('change-set-name', { type: 'string', desc: 'Name of the CloudFormation change set to create' }) + .option('force', { alias: 'f', type: 'boolean', desc: 'Always deploy stack even if templates are identical', default: false }) + .option('progress', { type: 'string', choices: [StackActivityProgress.BAR, StackActivityProgress.EVENTS], desc: 'Display mode for stack activity events' }) + .option('rollback', { + type: 'boolean', + desc: "Rollback stack to stable state on failure. Defaults to 'true', iterate more rapidly with --no-rollback or -R. " + + 'Note: do **not** disable this flag for deployments with resource replacements, as that will always fail', + }) + // same hack for -R as above in 'deploy' + .option('R', { type: 'boolean', hidden: true }).middleware(yargsNegativeAlias('R', 'rollback'), true) + .option('hotswap', { + type: 'boolean', + desc: "Attempts to perform a 'hotswap' deployment, " + + 'which skips CloudFormation and updates the resources directly, ' + + 'and falls back to a full deployment if that is not possible. ' + + "'true' by default, use --no-hotswap to turn off", }), ) .command('destroy [STACKS..]', 'Destroy the stack(s) named STACKS', yargs => yargs @@ -335,6 +374,26 @@ async function initCommandLine() { ci: args.ci, rollback: configuration.settings.get(['rollback']), hotswap: args.hotswap, + watch: args.watch, + }); + + case 'watch': + return cli.watch({ + selector, + // parameters: parameterMap, + // usePreviousParameters: args['previous-parameters'], + // outputsFile: configuration.settings.get(['outputsFile']), + // requireApproval: configuration.settings.get(['requireApproval']), + // notificationArns: args.notificationArns, + exclusively: args.exclusively, + toolkitStackName, + roleArn: args.roleArn, + reuseAssets: args['build-exclude'], + changeSetName: args.changeSetName, + force: args.force, + progress: configuration.settings.get(['progress']), + rollback: configuration.settings.get(['rollback']), + hotswap: args.hotswap, }); case 'destroy': diff --git a/packages/aws-cdk/lib/api/cloudformation-deployments.ts b/packages/aws-cdk/lib/api/cloudformation-deployments.ts index 914efd51cd574..da8db43ae8005 100644 --- a/packages/aws-cdk/lib/api/cloudformation-deployments.ts +++ b/packages/aws-cdk/lib/api/cloudformation-deployments.ts @@ -142,7 +142,7 @@ export interface DeployStackOptions { * A 'hotswap' deployment will attempt to short-circuit CloudFormation * and update the affected resources like Lambda functions directly. * - * @default - false (do not perform a 'hotswap' deployment) + * @default - false for regular deployments, true for 'watch' deployments */ readonly hotswap?: boolean; } diff --git a/packages/aws-cdk/lib/api/cxapp/cloud-executable.ts b/packages/aws-cdk/lib/api/cxapp/cloud-executable.ts index eeebec8e90f44..9bbb607de44fb 100644 --- a/packages/aws-cdk/lib/api/cxapp/cloud-executable.ts +++ b/packages/aws-cdk/lib/api/cxapp/cloud-executable.ts @@ -46,10 +46,14 @@ export class CloudExecutable { } /** - * Synthesize a set of stacks + * Synthesize a set of stacks. + * + * @param cacheCloudAssembly whether to cache the Cloud Assembly after it has been first synthesized. + * This is 'true' by default, and only set to 'false' for 'cdk watch', + * which needs to re-synthesize the Assembly each time it detects a change to the project files */ - public async synthesize(): Promise { - if (!this._cloudAssembly) { + public async synthesize(cacheCloudAssembly: boolean = true): Promise { + if (!this._cloudAssembly || !cacheCloudAssembly) { this._cloudAssembly = await this.doSynthesize(); } return this._cloudAssembly; diff --git a/packages/aws-cdk/lib/api/deploy-stack.ts b/packages/aws-cdk/lib/api/deploy-stack.ts index 2d35a3a01aea0..f73eebed57f54 100644 --- a/packages/aws-cdk/lib/api/deploy-stack.ts +++ b/packages/aws-cdk/lib/api/deploy-stack.ts @@ -179,7 +179,7 @@ export interface DeployStackOptions { * A 'hotswap' deployment will attempt to short-circuit CloudFormation * and update the affected resources like Lambda functions directly. * - * @default - false (do not perform a 'hotswap' deployment) + * @default - false for regular deployments, true for 'watch' deployments */ readonly hotswap?: boolean; } diff --git a/packages/aws-cdk/lib/cdk-toolkit.ts b/packages/aws-cdk/lib/cdk-toolkit.ts index cd5e591dce866..95da6dd39e139 100644 --- a/packages/aws-cdk/lib/cdk-toolkit.ts +++ b/packages/aws-cdk/lib/cdk-toolkit.ts @@ -1,6 +1,7 @@ import * as path from 'path'; import { format } from 'util'; import * as cxapi from '@aws-cdk/cx-api'; +import * as chokidar from 'chokidar'; import * as colors from 'colors/safe'; import * as fs from 'fs-extra'; import * as promptly from 'promptly'; @@ -12,9 +13,9 @@ import { CloudAssembly, DefaultSelection, ExtendedStackSelection, StackCollectio import { CloudExecutable } from './api/cxapp/cloud-executable'; import { StackActivityProgress } from './api/util/cloudformation/stack-activity-monitor'; import { printSecurityDiff, printStackDiff, RequireApproval } from './diff'; -import { data, error, highlight, print, success, warning } from './logging'; +import { data, debug, error, highlight, print, success, warning } from './logging'; import { deserializeStructure } from './serialize'; -import { Configuration } from './settings'; +import { Configuration, PROJECT_CONFIG } from './settings'; import { numberFromBool, partition } from './util'; export interface CdkToolkitProps { @@ -112,7 +113,11 @@ export class CdkToolkit { } public async deploy(options: DeployOptions) { - const stacks = await this.selectStacksForDeploy(options.selector, options.exclusively); + if (options.watch) { + return this.watch(options); + } + + const stacks = await this.selectStacksForDeploy(options.selector, options.exclusively, options.cacheCloudAssembly); const requireApproval = options.requireApproval ?? RequireApproval.Broadening; @@ -243,6 +248,85 @@ export class CdkToolkit { } } + public async watch(options: WatchOptions) { + const rootDir = path.dirname(path.resolve(PROJECT_CONFIG)); + debug("root directory used for 'watch' is: %s", rootDir); + + const watchSettings: { include?: string | string[], exclude: string | string [] } | undefined = + this.props.configuration.settings.get(['watch']); + if (!watchSettings) { + throw new Error("Cannot use the 'watch' command without specifying at least one directory to monitor. " + + 'Make sure to add a "watch" key to your cdk.json'); + } + + // For the "include" subkey under the "watch" key, the behavior is: + // 1. No "watch" setting? We error out. + // 2. "watch" setting without an "include" key? We default to observing "./**". + // 3. "watch" setting with an empty "include" key? We default to observing "./**". + // 4. Non-empty "include" key? Just use the "include" key. + const watchIncludes = this.patternsArrayForWatch(watchSettings.include, { rootDir, returnRootDirIfEmpty: true }); + debug("'include' patterns for 'watch': %s", watchIncludes); + + // For the "exclude" subkey under the "watch" key, + // the behavior is to add some default excludes in addition to the ones specified by the user: + // 1. The CDK output directory. + // 2. Any file whose name starts with a dot. + // 3. Any directory's content whose name starts with a dot. + // 4. Any node_modules and its content (even if it's not a JS/TS project, you might be using a local aws-cli package) + const outputDir = this.props.configuration.settings.get(['output']); + const watchExcludes = this.patternsArrayForWatch(watchSettings.exclude, { rootDir, returnRootDirIfEmpty: false }).concat( + `${outputDir}/**`, + '**/.*', + '**/.*/**', + '**/node_modules/**', + ); + debug("'exclude' patterns for 'watch': %s", watchExcludes); + + // Since 'cdk deploy' is a relatively slow operation for a 'watch' process, + // introduce a concurrency latch that tracks the state. + // This way, if file change events arrive when a 'cdk deploy' is still executing, + // we will batch them, and trigger another 'cdk deploy' after the current one finishes, + // making sure 'cdk deploy's always execute one at a time. + // Here's a diagram showing the state transitions: + // -------------- -------- file changed -------------- file changed -------------- file changed + // | | ready event | | ------------------> | | ------------------> | | --------------| + // | pre-ready | -------------> | open | | deploying | | queued | | + // | | | | <------------------ | | <------------------ | | <-------------| + // -------------- -------- 'cdk deploy' done -------------- 'cdk deploy' done -------------- + let latch: 'pre-ready' | 'open' | 'deploying' | 'queued' = 'pre-ready'; + chokidar.watch(watchIncludes, { + ignored: watchExcludes, + cwd: rootDir, + // ignoreInitial: true, + }).on('ready', () => { + latch = 'open'; + debug("'watch' received the 'ready' event. From now on, all file changes will trigger a deployment"); + }).on('all', async (event, filePath) => { + if (latch === 'pre-ready') { + print(`'watch' is observing ${event === 'addDir' ? 'directory' : 'the file'} '%s' for changes`, filePath); + } else if (latch === 'open') { + latch = 'deploying'; + print("Detected change to '%s' (type: %s). Triggering 'cdk deploy'", filePath, event); + await this.invokeDeployFromWatch(options); + + // If latch is still 'deploying' after the 'await', that's fine, + // but if it's 'queued', that means we need to deploy again + while ((latch as 'deploying' | 'queued') === 'queued') { + // TypeScript doesn't realize latch can change between 'awaits', + // and thinks the above 'while' condition is always 'false' without the cast + latch = 'deploying'; + print("Detected file changes during deployment. Invoking 'cdk deploy' again"); + await this.invokeDeployFromWatch(options); + } + latch = 'open'; + } else { // this means latch is either 'deploying' or 'queued' + latch = 'queued'; + print("Detected change to '%s' (type: %s) while 'cdk deploy' is still running. " + + 'Will queue for another deployment after this one finishes', filePath, event); + } + }); + } + public async destroy(options: DestroyOptions) { let stacks = await this.selectStacksForDestroy(options.selector, options.exclusively); @@ -397,8 +481,8 @@ export class CdkToolkit { return stacks; } - private async selectStacksForDeploy(selector: StackSelector, exclusively?: boolean): Promise { - const assembly = await this.assembly(); + private async selectStacksForDeploy(selector: StackSelector, exclusively?: boolean, cacheCloudAssembly?: boolean): Promise { + const assembly = await this.assembly(cacheCloudAssembly); const stacks = await assembly.selectStacks(selector, { extend: exclusively ? ExtendedStackSelection.None : ExtendedStackSelection.Upstream, defaultBehavior: DefaultSelection.OnlySingle, @@ -480,10 +564,38 @@ export class CdkToolkit { return assembly.stackById(stacks.firstStack.id); } - private assembly(): Promise { - return this.props.cloudExecutable.synthesize(); + private assembly(cacheCloudAssembly?: boolean): Promise { + return this.props.cloudExecutable.synthesize(cacheCloudAssembly); } + private patternsArrayForWatch(patterns: string | string[] | undefined, options: { rootDir: string, returnRootDirIfEmpty: boolean }): string[] { + const patternsArray: string[] = patterns !== undefined + ? (Array.isArray(patterns) ? patterns : [patterns]) + : []; + return patternsArray.length > 0 + ? patternsArray + : (options.returnRootDirIfEmpty ? [options.rootDir] : []); + } + + private async invokeDeployFromWatch(options: WatchOptions): Promise { + // 'watch' has different defaults than regular 'deploy' + const deployOptions: DeployOptions = { + ...options, + requireApproval: RequireApproval.Never, + // if 'watch' is called by invoking 'cdk deploy --watch', + // we need to make sure to not call 'deploy' with 'watch' again, + // as that would lead to a cycle + watch: false, + cacheCloudAssembly: false, + hotswap: options.hotswap === undefined ? true : options.hotswap, + }; + + try { + await this.deploy(deployOptions); + } catch (e) { + // just continue - deploy will show the error + } + } } export interface DiffOptions { @@ -542,7 +654,7 @@ export interface DiffOptions { securityOnly?: boolean; } -export interface DeployOptions { +interface WatchOptions { /** * Criteria for selecting stacks to deploy */ @@ -567,6 +679,49 @@ export interface DeployOptions { */ roleArn?: string; + /** + * Reuse the assets with the given asset IDs + */ + reuseAssets?: string[]; + + /** + * Optional name to use for the CloudFormation change set. + * If not provided, a name will be generated automatically. + */ + changeSetName?: string; + + /** + * Always deploy, even if templates are identical. + * @default false + */ + force?: boolean; + + /** + * Display mode for stack deployment progress. + * + * @default - StackActivityProgress.Bar - stack events will be displayed for + * the resource currently being deployed. + */ + progress?: StackActivityProgress; + + /** + * Rollback failed deployments + * + * @default true + */ + readonly rollback?: boolean; + + /** + * Whether to perform a 'hotswap' deployment. + * A 'hotswap' deployment will attempt to short-circuit CloudFormation + * and update the affected resources like Lambda functions directly. + * + * @default - false for regular deployments, true for 'watch' deployments + */ + readonly hotswap?: boolean; +} + +export interface DeployOptions extends WatchOptions { /** * ARNs of SNS topics that CloudFormation will notify with stack related events */ @@ -579,11 +734,6 @@ export interface DeployOptions { */ requireApproval?: RequireApproval; - /** - * Reuse the assets with the given asset IDs - */ - reuseAssets?: string[]; - /** * Tags to pass to CloudFormation for deployment */ @@ -596,18 +746,6 @@ export interface DeployOptions { */ execute?: boolean; - /** - * Optional name to use for the CloudFormation change set. - * If not provided, a name will be generated automatically. - */ - changeSetName?: string; - - /** - * Always deploy, even if templates are identical. - * @default false - */ - force?: boolean; - /** * Additional parameters for CloudFormation at deploy time * @default {} @@ -623,14 +761,6 @@ export interface DeployOptions { */ usePreviousParameters?: boolean; - /** - * Display mode for stack deployment progress. - * - * @default - StackActivityProgress.Bar - stack events will be displayed for - * the resource currently being deployed. - */ - progress?: StackActivityProgress; - /** * Path to file where stack outputs will be written after a successful deploy as JSON * @default - Outputs are not written to any file @@ -645,20 +775,20 @@ export interface DeployOptions { readonly ci?: boolean; /** - * Rollback failed deployments + * Whether this 'deploy' command should actually delegate to the 'watch' command. * - * @default true + * @default false */ - readonly rollback?: boolean; + readonly watch?: boolean; - /* - * Whether to perform a 'hotswap' deployment. - * A 'hotswap' deployment will attempt to short-circuit CloudFormation - * and update the affected resources like Lambda functions directly. + /** + * Whether we should cache the Cloud Assembly after the first time it has been synthesized. + * The default is 'true', we only don't want to do it in case the deployment is triggered by + * 'cdk watch'. * - * @default - false (do not perform a 'hotswap' deployment) + * @default true */ - readonly hotswap?: boolean; + readonly cacheCloudAssembly?: boolean; } export interface DestroyOptions { diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index c71dddbf206f4..40fa126a94cb4 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -76,6 +76,7 @@ "aws-sdk": "^2.979.0", "camelcase": "^6.2.0", "cdk-assets": "0.0.0", + "chokidar": "^3.5.2", "colors": "^1.4.0", "decamelize": "^5.0.1", "fs-extra": "^9.1.0", diff --git a/packages/aws-cdk/test/cdk-toolkit.test.ts b/packages/aws-cdk/test/cdk-toolkit.test.ts index 19276b15b7b7b..e8445da68a6b6 100644 --- a/packages/aws-cdk/test/cdk-toolkit.test.ts +++ b/packages/aws-cdk/test/cdk-toolkit.test.ts @@ -1,3 +1,52 @@ +// We need to mock the chokidar library, used by 'cdk watch' +const mockChokidarWatcherOn = jest.fn(); +const fakeChokidarWatcher = { + on: mockChokidarWatcherOn, +}; +const fakeChokidarWatcherOn = { + get readyCallback(): () => void { + expect(mockChokidarWatcherOn.mock.calls.length).toBeGreaterThanOrEqual(1); + // The call to the first 'watcher.on()' in the production code is the one we actually want here. + // This is a pretty fragile, but at least with this helper class, + // we would have to change it only in one place if it ever breaks + const firstCall = mockChokidarWatcherOn.mock.calls[0]; + // let's make sure the first argument is the 'ready' event, + // just to be double safe + expect(firstCall[0]).toBe('ready'); + // the second argument is the callback + return firstCall[1]; + }, + + get fileEventCallback(): (event: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir', path: string) => Promise { + expect(mockChokidarWatcherOn.mock.calls.length).toBeGreaterThanOrEqual(2); + const secondCall = mockChokidarWatcherOn.mock.calls[1]; + // let's make sure the first argument is not the 'ready' event, + // just to be double safe + expect(secondCall[0]).not.toBe('ready'); + // the second argument is the callback + return secondCall[1]; + }, +}; + +const mockChokidarWatch = jest.fn(); +jest.mock('chokidar', () => ({ + watch: mockChokidarWatch, +})); +const fakeChokidarWatch = { + get includeArgs(): string[] { + expect(mockChokidarWatch.mock.calls.length).toBe(1); + // the include args are the first parameter to the 'watch()' call + return mockChokidarWatch.mock.calls[0][0]; + }, + + get excludeArgs(): string[] { + expect(mockChokidarWatch.mock.calls.length).toBe(1); + // the ignore args are a property of the second parameter to the 'watch()' call + const chokidarWatchOpts = mockChokidarWatch.mock.calls[0][1]; + return chokidarWatchOpts.ignored; + }, +}; + import * as cxschema from '@aws-cdk/cloud-assembly-schema'; import * as cxapi from '@aws-cdk/cx-api'; import { Bootstrapper } from '../lib/api/bootstrap'; @@ -11,6 +60,12 @@ import { instanceMockFrom, MockCloudExecutable, TestStackArtifact } from './util let cloudExecutable: MockCloudExecutable; let bootstrapper: jest.Mocked; beforeEach(() => { + jest.resetAllMocks(); + + mockChokidarWatch.mockReturnValue(fakeChokidarWatcher); + // on() in chokidar's Watcher returns 'this' + mockChokidarWatcherOn.mockReturnValue(fakeChokidarWatcher); + bootstrapper = instanceMockFrom(Bootstrapper); bootstrapper.bootstrapEnvironment.mockResolvedValue({ noOp: false, outputs: {} } as any); @@ -191,6 +246,141 @@ describe('deploy', () => { }); }); +describe('watch', () => { + test("fails when no 'watch' settings are found", async () => { + const toolkit = defaultToolkitSetup(); + + await expect(() => { + return toolkit.watch({ selector: { patterns: [] } }); + }).rejects.toThrow("Cannot use the 'watch' command without specifying at least one directory to monitor. " + + 'Make sure to add a "watch" key to your cdk.json'); + }); + + test('observes only the root directory by default', async () => { + cloudExecutable.configuration.settings.set(['watch'], {}); + const toolkit = defaultToolkitSetup(); + + await toolkit.watch({ selector: { patterns: [] } }); + + const includeArgs = fakeChokidarWatch.includeArgs; + expect(includeArgs.length).toBe(1); + }); + + test("allows providing a single string in 'watch.include'", async () => { + cloudExecutable.configuration.settings.set(['watch'], { + include: 'my-dir', + }); + const toolkit = defaultToolkitSetup(); + + await toolkit.watch({ selector: { patterns: [] } }); + + expect(fakeChokidarWatch.includeArgs).toStrictEqual(['my-dir']); + }); + + test("allows providing an array of strings in 'watch.include'", async () => { + cloudExecutable.configuration.settings.set(['watch'], { + include: ['my-dir1', '**/my-dir2/*'], + }); + const toolkit = defaultToolkitSetup(); + + await toolkit.watch({ selector: { patterns: [] } }); + + expect(fakeChokidarWatch.includeArgs).toStrictEqual(['my-dir1', '**/my-dir2/*']); + }); + + test('ignores the output dir, dot files, dot directories, and node_modules by default', async () => { + cloudExecutable.configuration.settings.set(['watch'], {}); + cloudExecutable.configuration.settings.set(['output'], 'cdk.out'); + const toolkit = defaultToolkitSetup(); + + await toolkit.watch({ selector: { patterns: [] } }); + + expect(fakeChokidarWatch.excludeArgs).toStrictEqual([ + 'cdk.out/**', + '**/.*', + '**/.*/**', + '**/node_modules/**', + ]); + }); + + test("allows providing a single string in 'watch.exclude'", async () => { + cloudExecutable.configuration.settings.set(['watch'], { + exclude: 'my-dir', + }); + const toolkit = defaultToolkitSetup(); + + await toolkit.watch({ selector: { patterns: [] } }); + + const excludeArgs = fakeChokidarWatch.excludeArgs; + expect(excludeArgs.length).toBe(5); + expect(excludeArgs[0]).toBe('my-dir'); + }); + + test("allows providing an array of strings in 'watch.exclude'", async () => { + cloudExecutable.configuration.settings.set(['watch'], { + exclude: ['my-dir1', '**/my-dir2'], + }); + const toolkit = defaultToolkitSetup(); + + await toolkit.watch({ selector: { patterns: [] } }); + + const excludeArgs = fakeChokidarWatch.excludeArgs; + expect(excludeArgs.length).toBe(6); + expect(excludeArgs[0]).toBe('my-dir1'); + expect(excludeArgs[1]).toBe('**/my-dir2'); + }); + + describe('with file change events', () => { + let toolkit: CdkToolkit; + let cdkDeployMock: jest.Mock; + + beforeEach(async () => { + cloudExecutable.configuration.settings.set(['watch'], {}); + toolkit = defaultToolkitSetup(); + cdkDeployMock = jest.fn(); + toolkit.deploy = cdkDeployMock; + await toolkit.watch({ selector: { patterns: [] } }); + }); + + test("does not trigger a 'deploy' before the 'ready' event has fired", async () => { + await fakeChokidarWatcherOn.fileEventCallback('add', 'my-file'); + + expect(cdkDeployMock).not.toHaveBeenCalled(); + }); + + describe("when the 'ready' event has already fired", () => { + beforeEach(() => { + fakeChokidarWatcherOn.readyCallback(); + }); + + test("does trigger a 'deploy' for a file change", async () => { + await fakeChokidarWatcherOn.fileEventCallback('add', 'my-file'); + + expect(cdkDeployMock).toHaveBeenCalled(); + }); + + test("triggers a 'deploy' twice for two file changes", async () => { + await Promise.all([ + fakeChokidarWatcherOn.fileEventCallback('add', 'my-file1'), + fakeChokidarWatcherOn.fileEventCallback('change', 'my-file2'), + ]); + + expect(cdkDeployMock).toHaveBeenCalledTimes(2); + }); + + test("batches file changes that happen during 'deploy'", async () => { + await Promise.all([ + fakeChokidarWatcherOn.fileEventCallback('add', 'my-file1'), + fakeChokidarWatcherOn.fileEventCallback('change', 'my-file2'), + fakeChokidarWatcherOn.fileEventCallback('unlink', 'my-file3'), + ]); + + expect(cdkDeployMock).toHaveBeenCalledTimes(2); + }); + }); + }); +}); + describe('synth', () => { test('with no stdout option', async () => { // GIVE diff --git a/yarn.lock b/yarn.lock index 026281159396d..b98b3ecdb6050 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2287,7 +2287,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@^3.0.3: +anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -2674,6 +2674,11 @@ before-after-hook@^2.0.0, before-after-hook@^2.2.0: resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e" integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ== +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + bl@^4.0.3: version "4.1.0" resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" @@ -2712,7 +2717,7 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.1: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -2960,6 +2965,21 @@ charenc@0.0.2: resolved "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= +chokidar@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + chownr@^1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -4801,7 +4821,7 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^2.1.2, fsevents@^2.3.2: +fsevents@^2.1.2, fsevents@^2.3.2, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -4992,7 +5012,7 @@ github-api@^3.4.0: js-base64 "^2.1.9" utf8 "^2.1.1" -glob-parent@^5.1.1, glob-parent@^5.1.2: +glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -5421,6 +5441,13 @@ is-bigint@^1.0.1: dependencies: has-bigints "^1.0.1" +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-boolean-object@^1.1.0: version "1.1.2" resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" @@ -5524,7 +5551,7 @@ is-generator-fn@^2.0.0: resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1, is-glob@^4.0.3: version "4.0.3" resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -7824,7 +7851,7 @@ normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" -normalize-path@^3.0.0: +normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== @@ -8467,7 +8494,7 @@ picocolors@^1.0.0: resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.3: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: version "2.3.0" resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== @@ -8877,6 +8904,13 @@ readdir-scoped-modules@^1.0.0: graceful-fs "^4.1.2" once "^1.3.0" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + redent@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" From ea71b4ed7466d8799bde4fdd5adfed9fc8febb9c Mon Sep 17 00:00:00 2001 From: Ayush Goyal Date: Fri, 5 Nov 2021 14:35:44 +0530 Subject: [PATCH 141/148] feat(cfnspec): cloudformation spec v47.0.0 (#17350) Generated by running `scripts/bump-cfnspec.sh`. Wanted to speed up the additions required for #17290 . Feel free to close if this is supposed to be created by a bot like #17223 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/cfnspec/CHANGELOG.md | 273 +++ packages/@aws-cdk/cfnspec/cfn.version | 2 +- ...0_CloudFormationResourceSpecification.json | 1623 ++++++++++++++++- 3 files changed, 1821 insertions(+), 77 deletions(-) diff --git a/packages/@aws-cdk/cfnspec/CHANGELOG.md b/packages/@aws-cdk/cfnspec/CHANGELOG.md index 51d94432f3293..913546215a38d 100644 --- a/packages/@aws-cdk/cfnspec/CHANGELOG.md +++ b/packages/@aws-cdk/cfnspec/CHANGELOG.md @@ -1,3 +1,276 @@ +# CloudFormation Resource Specification v47.0.0 + +## New Resource Types + +* AWS::CloudFront::ResponseHeadersPolicy +* AWS::DataSync::LocationHDFS +* AWS::IoT::Logging +* AWS::IoT::ResourceSpecificLogging +* AWS::Pinpoint::InAppTemplate +* AWS::Redshift::EndpointAccess +* AWS::Redshift::EndpointAuthorization +* AWS::Redshift::EventSubscription +* AWS::Redshift::ScheduledAction + +## Attribute Changes + +* AWS::EC2::InternetGateway InternetGatewayId (__added__) +* AWS::EC2::NetworkInterface Id (__added__) +* AWS::EC2::NetworkInterface SecondaryPrivateIpAddresses.DuplicatesAllowed (__added__) +* AWS::EC2::NetworkInterface Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html +* AWS::IoTAnalytics::Channel Id (__added__) +* AWS::IoTAnalytics::Dataset Id (__added__) +* AWS::IoTAnalytics::Datastore Id (__added__) +* AWS::IoTAnalytics::Pipeline Id (__added__) + +## Property Changes + +* AWS::DMS::Endpoint RedisSettings (__added__) +* AWS::EC2::NetworkInterface Description.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-description + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-description +* AWS::EC2::NetworkInterface GroupSet.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-groupset + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-groupset +* AWS::EC2::NetworkInterface GroupSet.DuplicatesAllowed (__changed__) + * Old: false + * New: true +* AWS::EC2::NetworkInterface InterfaceType.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-interfacetype + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-interfacetype +* AWS::EC2::NetworkInterface Ipv6AddressCount.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-ipv6addresscount + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-ipv6addresscount +* AWS::EC2::NetworkInterface Ipv6Addresses.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-ipv6addresses + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-ipv6addresses +* AWS::EC2::NetworkInterface PrivateIpAddress.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-privateipaddress + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-privateipaddress +* AWS::EC2::NetworkInterface PrivateIpAddresses.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-privateipaddresses + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-privateipaddresses +* AWS::EC2::NetworkInterface PrivateIpAddresses.DuplicatesAllowed (__changed__) + * Old: false + * New: true +* AWS::EC2::NetworkInterface PrivateIpAddresses.UpdateType (__changed__) + * Old: Conditional + * New: Mutable +* AWS::EC2::NetworkInterface SecondaryPrivateIpAddressCount.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-secondaryprivateipcount + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-secondaryprivateipaddresscount +* AWS::EC2::NetworkInterface SourceDestCheck.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-sourcedestcheck + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-sourcedestcheck +* AWS::EC2::NetworkInterface SubnetId.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-subnetid + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-subnetid +* AWS::EC2::NetworkInterface Tags.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-tags + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-tags +* AWS::EC2::TransitGatewayPeeringAttachment Options (__added__) +* AWS::EC2::VPCEndpointService PayerResponsibility (__added__) +* AWS::EKS::Cluster Logging (__added__) +* AWS::EKS::Cluster Tags (__added__) +* AWS::EKS::Cluster ResourcesVpcConfig.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::IoTAnalytics::Channel ChannelName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Channel Tags.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset Actions.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset ContentDeliveryRules.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset DatasetName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Dataset LateDataRules.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset Tags.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset Triggers.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Datastore Tags.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Pipeline PipelineActivities.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Pipeline PipelineName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline Tags.DuplicatesAllowed (__added__) +* AWS::S3ObjectLambda::AccessPoint Name.Required (__changed__) + * Old: true + * New: false +* AWS::SageMaker::Endpoint RetainDeploymentConfig (__added__) + +## Property Type Changes + +* AWS::EKS::Cluster.Provider (__removed__) +* AWS::DMS::Endpoint.RedisSettings (__added__) +* AWS::EC2::EC2Fleet.CapacityRebalance (__added__) +* AWS::EC2::EC2Fleet.MaintenanceStrategies (__added__) +* AWS::EC2::TransitGatewayPeeringAttachment.TransitGatewayPeeringAttachmentOptions (__added__) +* AWS::EKS::Cluster.ClusterLogging (__added__) +* AWS::EKS::Cluster.Logging (__added__) +* AWS::EKS::Cluster.LoggingTypeConfig (__added__) +* AWS::NetworkFirewall::FirewallPolicy.StatefulEngineOptions (__added__) +* AWS::NetworkFirewall::RuleGroup.StatefulRuleOptions (__added__) +* AWS::DMS::Endpoint.KafkaSettings IncludeControlDetails (__added__) +* AWS::DMS::Endpoint.KafkaSettings IncludeNullAndEmpty (__added__) +* AWS::DMS::Endpoint.KafkaSettings IncludeTableAlterOperations (__added__) +* AWS::DMS::Endpoint.KafkaSettings IncludeTransactionDetails (__added__) +* AWS::DMS::Endpoint.KafkaSettings NoHexPrefix (__added__) +* AWS::DMS::Endpoint.KafkaSettings PartitionIncludeSchemaTable (__added__) +* AWS::DMS::Endpoint.KafkaSettings SaslPassword (__added__) +* AWS::DMS::Endpoint.KafkaSettings SaslUserName (__added__) +* AWS::DMS::Endpoint.KafkaSettings SecurityProtocol (__added__) +* AWS::DMS::Endpoint.KafkaSettings SslCaCertificateArn (__added__) +* AWS::DMS::Endpoint.KafkaSettings SslClientCertificateArn (__added__) +* AWS::DMS::Endpoint.KafkaSettings SslClientKeyArn (__added__) +* AWS::DMS::Endpoint.KafkaSettings SslClientKeyPassword (__added__) +* AWS::DMS::Endpoint.KinesisSettings IncludeControlDetails (__added__) +* AWS::DMS::Endpoint.KinesisSettings IncludeNullAndEmpty (__added__) +* AWS::DMS::Endpoint.KinesisSettings IncludeTableAlterOperations (__added__) +* AWS::DMS::Endpoint.KinesisSettings IncludeTransactionDetails (__added__) +* AWS::DMS::Endpoint.KinesisSettings NoHexPrefix (__added__) +* AWS::DMS::Endpoint.KinesisSettings PartitionIncludeSchemaTable (__added__) +* AWS::EC2::EC2Fleet.SpotOptionsRequest MaintenanceStrategies.PrimitiveType (__deleted__) +* AWS::EC2::EC2Fleet.SpotOptionsRequest MaintenanceStrategies.Type (__added__) +* AWS::EC2::NetworkInterface.PrivateIpAddressSpecification Primary.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html#cfn-ec2-networkinterface-privateipspecification-primary + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinterface-privateipaddressspecification.html#cfn-ec2-networkinterface-privateipaddressspecification-primary +* AWS::EC2::NetworkInterface.PrivateIpAddressSpecification PrivateIpAddress.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html#cfn-ec2-networkinterface-privateipspecification-privateipaddress + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinterface-privateipaddressspecification.html#cfn-ec2-networkinterface-privateipaddressspecification-privateipaddress +* AWS::EKS::Cluster.EncryptionConfig Provider.Type (__deleted__) +* AWS::EKS::Cluster.EncryptionConfig Provider.PrimitiveType (__added__) +* AWS::EKS::Cluster.EncryptionConfig Provider.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::EKS::Cluster.EncryptionConfig Resources.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::EKS::Cluster.KubernetesNetworkConfig ServiceIpv4Cidr.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::EKS::Cluster.ResourcesVpcConfig EndpointPrivateAccess (__added__) +* AWS::EKS::Cluster.ResourcesVpcConfig EndpointPublicAccess (__added__) +* AWS::EKS::Cluster.ResourcesVpcConfig PublicAccessCidrs (__added__) +* AWS::EKS::Cluster.ResourcesVpcConfig SecurityGroupIds.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::EKS::Cluster.ResourcesVpcConfig SubnetIds.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::IoTAnalytics::Dataset.ContainerAction Variables.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset.DatasetContentVersionValue DatasetName.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-variable-datasetcontentversionvalue.html#cfn-iotanalytics-dataset-variable-datasetcontentversionvalue-datasetname + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-datasetcontentversionvalue.html#cfn-iotanalytics-dataset-datasetcontentversionvalue-datasetname +* AWS::IoTAnalytics::Dataset.DatasetContentVersionValue DatasetName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Dataset.OutputFileUriValue FileName.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-variable-outputfileurivalue.html#cfn-iotanalytics-dataset-variable-outputfileurivalue-filename + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-outputfileurivalue.html#cfn-iotanalytics-dataset-outputfileurivalue-filename +* AWS::IoTAnalytics::Dataset.OutputFileUriValue FileName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Dataset.QueryAction Filters.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset.Schedule ScheduleExpression.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-trigger-schedule.html#cfn-iotanalytics-dataset-trigger-schedule-scheduleexpression + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-schedule.html#cfn-iotanalytics-dataset-schedule-scheduleexpression +* AWS::IoTAnalytics::Datastore.DatastorePartitions Partitions.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Datastore.IotSiteWiseMultiLayerStorage CustomerManagedS3Storage.Required (__changed__) + * Old: true + * New: false +* AWS::IoTAnalytics::Datastore.SchemaDefinition Columns.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Pipeline.AddAttributes Attributes.PrimitiveType (__deleted__) +* AWS::IoTAnalytics::Pipeline.AddAttributes Attributes.PrimitiveItemType (__added__) +* AWS::IoTAnalytics::Pipeline.AddAttributes Attributes.Type (__added__) +* AWS::IoTAnalytics::Pipeline.AddAttributes Attributes.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.AddAttributes Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Channel ChannelName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Channel Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Datastore DatastoreName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Datastore Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceRegistryEnrich Attribute.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceRegistryEnrich Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceRegistryEnrich RoleArn.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceRegistryEnrich ThingName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceShadowEnrich Attribute.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceShadowEnrich Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceShadowEnrich RoleArn.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceShadowEnrich ThingName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Filter Filter.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Filter Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Lambda BatchSize.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Lambda LambdaName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Lambda Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Math Attribute.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Math Math.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Math Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.RemoveAttributes Attributes.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Pipeline.RemoveAttributes Attributes.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.RemoveAttributes Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.SelectAttributes Attributes.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Pipeline.SelectAttributes Attributes.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.SelectAttributes Name.Required (__changed__) + * Old: false + * New: true +* AWS::NetworkFirewall::FirewallPolicy.FirewallPolicy StatefulDefaultActions (__added__) +* AWS::NetworkFirewall::FirewallPolicy.FirewallPolicy StatefulEngineOptions (__added__) +* AWS::NetworkFirewall::FirewallPolicy.StatefulRuleGroupReference Priority (__added__) +* AWS::NetworkFirewall::RuleGroup.RuleGroup StatefulRuleOptions (__added__) +* AWS::SageMaker::Endpoint.TrafficRoutingConfig LinearStepSize (__added__) + + # CloudFormation Resource Specification v46.0.0 ## New Resource Types diff --git a/packages/@aws-cdk/cfnspec/cfn.version b/packages/@aws-cdk/cfnspec/cfn.version index 783c5bb1ce5c2..645a41f3b46f7 100644 --- a/packages/@aws-cdk/cfnspec/cfn.version +++ b/packages/@aws-cdk/cfnspec/cfn.version @@ -1 +1 @@ -46.0.0 +47.0.0 diff --git a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json index 2db5051c26ccf..5d8a7aab62e63 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json +++ b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json @@ -12537,6 +12537,333 @@ } } }, + "AWS::CloudFront::ResponseHeadersPolicy.AccessControlAllowHeaders": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolallowheaders.html", + "Properties": { + "Items": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolallowheaders.html#cfn-cloudfront-responseheaderspolicy-accesscontrolallowheaders-items", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.AccessControlAllowMethods": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolallowmethods.html", + "Properties": { + "Items": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolallowmethods.html#cfn-cloudfront-responseheaderspolicy-accesscontrolallowmethods-items", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.AccessControlAllowOrigins": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolalloworigins.html", + "Properties": { + "Items": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolalloworigins.html#cfn-cloudfront-responseheaderspolicy-accesscontrolalloworigins-items", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.AccessControlExposeHeaders": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolexposeheaders.html", + "Properties": { + "Items": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolexposeheaders.html#cfn-cloudfront-responseheaderspolicy-accesscontrolexposeheaders-items", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.ContentSecurityPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-contentsecuritypolicy.html", + "Properties": { + "ContentSecurityPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-contentsecuritypolicy.html#cfn-cloudfront-responseheaderspolicy-contentsecuritypolicy-contentsecuritypolicy", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-contentsecuritypolicy.html#cfn-cloudfront-responseheaderspolicy-contentsecuritypolicy-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.ContentTypeOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-contenttypeoptions.html", + "Properties": { + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-contenttypeoptions.html#cfn-cloudfront-responseheaderspolicy-contenttypeoptions-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.CorsConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html", + "Properties": { + "AccessControlAllowCredentials": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-accesscontrolallowcredentials", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + }, + "AccessControlAllowHeaders": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-accesscontrolallowheaders", + "Required": true, + "Type": "AccessControlAllowHeaders", + "UpdateType": "Mutable" + }, + "AccessControlAllowMethods": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-accesscontrolallowmethods", + "Required": true, + "Type": "AccessControlAllowMethods", + "UpdateType": "Mutable" + }, + "AccessControlAllowOrigins": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-accesscontrolalloworigins", + "Required": true, + "Type": "AccessControlAllowOrigins", + "UpdateType": "Mutable" + }, + "AccessControlExposeHeaders": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-accesscontrolexposeheaders", + "Required": false, + "Type": "AccessControlExposeHeaders", + "UpdateType": "Mutable" + }, + "AccessControlMaxAgeSec": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-accesscontrolmaxagesec", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "OriginOverride": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-originoverride", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.CustomHeader": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-customheader.html", + "Properties": { + "Header": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-customheader.html#cfn-cloudfront-responseheaderspolicy-customheader-header", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-customheader.html#cfn-cloudfront-responseheaderspolicy-customheader-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + }, + "Value": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-customheader.html#cfn-cloudfront-responseheaderspolicy-customheader-value", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.CustomHeadersConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-customheadersconfig.html", + "Properties": { + "Items": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-customheadersconfig.html#cfn-cloudfront-responseheaderspolicy-customheadersconfig-items", + "DuplicatesAllowed": true, + "ItemType": "CustomHeader", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.FrameOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-frameoptions.html", + "Properties": { + "FrameOption": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-frameoptions.html#cfn-cloudfront-responseheaderspolicy-frameoptions-frameoption", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-frameoptions.html#cfn-cloudfront-responseheaderspolicy-frameoptions-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.ReferrerPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-referrerpolicy.html", + "Properties": { + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-referrerpolicy.html#cfn-cloudfront-responseheaderspolicy-referrerpolicy-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + }, + "ReferrerPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-referrerpolicy.html#cfn-cloudfront-responseheaderspolicy-referrerpolicy-referrerpolicy", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.ResponseHeadersPolicyConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-responseheaderspolicyconfig.html", + "Properties": { + "Comment": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-responseheaderspolicyconfig.html#cfn-cloudfront-responseheaderspolicy-responseheaderspolicyconfig-comment", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "CorsConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-responseheaderspolicyconfig.html#cfn-cloudfront-responseheaderspolicy-responseheaderspolicyconfig-corsconfig", + "Required": false, + "Type": "CorsConfig", + "UpdateType": "Mutable" + }, + "CustomHeadersConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-responseheaderspolicyconfig.html#cfn-cloudfront-responseheaderspolicy-responseheaderspolicyconfig-customheadersconfig", + "Required": false, + "Type": "CustomHeadersConfig", + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-responseheaderspolicyconfig.html#cfn-cloudfront-responseheaderspolicy-responseheaderspolicyconfig-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "SecurityHeadersConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-responseheaderspolicyconfig.html#cfn-cloudfront-responseheaderspolicy-responseheaderspolicyconfig-securityheadersconfig", + "Required": false, + "Type": "SecurityHeadersConfig", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.SecurityHeadersConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html", + "Properties": { + "ContentSecurityPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html#cfn-cloudfront-responseheaderspolicy-securityheadersconfig-contentsecuritypolicy", + "Required": false, + "Type": "ContentSecurityPolicy", + "UpdateType": "Mutable" + }, + "ContentTypeOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html#cfn-cloudfront-responseheaderspolicy-securityheadersconfig-contenttypeoptions", + "Required": false, + "Type": "ContentTypeOptions", + "UpdateType": "Mutable" + }, + "FrameOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html#cfn-cloudfront-responseheaderspolicy-securityheadersconfig-frameoptions", + "Required": false, + "Type": "FrameOptions", + "UpdateType": "Mutable" + }, + "ReferrerPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html#cfn-cloudfront-responseheaderspolicy-securityheadersconfig-referrerpolicy", + "Required": false, + "Type": "ReferrerPolicy", + "UpdateType": "Mutable" + }, + "StrictTransportSecurity": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html#cfn-cloudfront-responseheaderspolicy-securityheadersconfig-stricttransportsecurity", + "Required": false, + "Type": "StrictTransportSecurity", + "UpdateType": "Mutable" + }, + "XSSProtection": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html#cfn-cloudfront-responseheaderspolicy-securityheadersconfig-xssprotection", + "Required": false, + "Type": "XSSProtection", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.StrictTransportSecurity": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-stricttransportsecurity.html", + "Properties": { + "AccessControlMaxAgeSec": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-stricttransportsecurity.html#cfn-cloudfront-responseheaderspolicy-stricttransportsecurity-accesscontrolmaxagesec", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Mutable" + }, + "IncludeSubdomains": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-stricttransportsecurity.html#cfn-cloudfront-responseheaderspolicy-stricttransportsecurity-includesubdomains", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-stricttransportsecurity.html#cfn-cloudfront-responseheaderspolicy-stricttransportsecurity-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + }, + "Preload": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-stricttransportsecurity.html#cfn-cloudfront-responseheaderspolicy-stricttransportsecurity-preload", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.XSSProtection": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-xssprotection.html", + "Properties": { + "ModeBlock": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-xssprotection.html#cfn-cloudfront-responseheaderspolicy-xssprotection-modeblock", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-xssprotection.html#cfn-cloudfront-responseheaderspolicy-xssprotection-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + }, + "Protection": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-xssprotection.html#cfn-cloudfront-responseheaderspolicy-xssprotection-protection", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + }, + "ReportUri": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-xssprotection.html#cfn-cloudfront-responseheaderspolicy-xssprotection-reporturi", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::CloudFront::StreamingDistribution.Logging": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-logging.html", "Properties": { @@ -16883,6 +17210,84 @@ "Required": false, "UpdateType": "Mutable" }, + "IncludeControlDetails": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-includecontroldetails", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "IncludeNullAndEmpty": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-includenullandempty", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "IncludeTableAlterOperations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-includetablealteroperations", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "IncludeTransactionDetails": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-includetransactiondetails", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "NoHexPrefix": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-nohexprefix", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "PartitionIncludeSchemaTable": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-partitionincludeschematable", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "SaslPassword": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-saslpassword", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SaslUserName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-saslusername", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SecurityProtocol": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-securityprotocol", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SslCaCertificateArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-sslcacertificatearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SslClientCertificateArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-sslclientcertificatearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SslClientKeyArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-sslclientkeyarn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SslClientKeyPassword": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-sslclientkeypassword", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "Topic": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-topic", "PrimitiveType": "String", @@ -16894,12 +17299,48 @@ "AWS::DMS::Endpoint.KinesisSettings": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html", "Properties": { + "IncludeControlDetails": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-includecontroldetails", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "IncludeNullAndEmpty": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-includenullandempty", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "IncludeTableAlterOperations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-includetablealteroperations", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "IncludeTransactionDetails": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-includetransactiondetails", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, "MessageFormat": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-messageformat", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" }, + "NoHexPrefix": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-nohexprefix", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "PartitionIncludeSchemaTable": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-partitionincludeschematable", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, "ServiceAccessRoleArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-serviceaccessrolearn", "PrimitiveType": "String", @@ -17124,6 +17565,53 @@ } } }, + "AWS::DMS::Endpoint.RedisSettings": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html", + "Properties": { + "AuthPassword": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-authpassword", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "AuthType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-authtype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "AuthUserName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-authusername", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Port": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-port", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Mutable" + }, + "ServerName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-servername", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SslCaCertificateArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-sslcacertificatearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SslSecurityProtocol": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-sslsecurityprotocol", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::DMS::Endpoint.RedshiftSettings": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redshiftsettings.html", "Properties": { @@ -18746,6 +19234,40 @@ } } }, + "AWS::DataSync::LocationHDFS.NameNode": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationhdfs-namenode.html", + "Properties": { + "Hostname": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationhdfs-namenode.html#cfn-datasync-locationhdfs-namenode-hostname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Port": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationhdfs-namenode.html#cfn-datasync-locationhdfs-namenode-port", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::DataSync::LocationHDFS.QopConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationhdfs-qopconfiguration.html", + "Properties": { + "DataTransferProtection": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationhdfs-qopconfiguration.html#cfn-datasync-locationhdfs-qopconfiguration-datatransferprotection", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "RpcProtection": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationhdfs-qopconfiguration.html#cfn-datasync-locationhdfs-qopconfiguration-rpcprotection", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::DataSync::LocationNFS.MountOptions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationnfs-mountoptions.html", "Properties": { @@ -19815,6 +20337,23 @@ } } }, + "AWS::EC2::EC2Fleet.CapacityRebalance": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-capacityrebalance.html", + "Properties": { + "ReplacementStrategy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-capacityrebalance.html#cfn-ec2-ec2fleet-capacityrebalance-replacementstrategy", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "TerminationDelay": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-capacityrebalance.html#cfn-ec2-ec2fleet-capacityrebalance-terminationdelay", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::EC2::EC2Fleet.CapacityReservationOptionsRequest": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-capacityreservationoptionsrequest.html", "Properties": { @@ -20066,6 +20605,17 @@ } } }, + "AWS::EC2::EC2Fleet.MaintenanceStrategies": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-maintenancestrategies.html", + "Properties": { + "CapacityRebalance": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-maintenancestrategies.html#cfn-ec2-ec2fleet-maintenancestrategies-capacityrebalance", + "Required": false, + "Type": "CapacityRebalance", + "UpdateType": "Immutable" + } + } + }, "AWS::EC2::EC2Fleet.MemoryGiBPerVCpuRequest": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorygibpervcpurequest.html", "Properties": { @@ -20234,8 +20784,8 @@ }, "MaintenanceStrategies": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html#cfn-ec2-ec2fleet-spotoptionsrequest-maintenancestrategies", - "PrimitiveType": "Json", "Required": false, + "Type": "MaintenanceStrategies", "UpdateType": "Immutable" }, "MaxTotalPrice": { @@ -22232,16 +22782,16 @@ } }, "AWS::EC2::NetworkInterface.PrivateIpAddressSpecification": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinterface-privateipaddressspecification.html", "Properties": { "Primary": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html#cfn-ec2-networkinterface-privateipspecification-primary", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinterface-privateipaddressspecification.html#cfn-ec2-networkinterface-privateipaddressspecification-primary", "PrimitiveType": "Boolean", "Required": true, "UpdateType": "Mutable" }, "PrivateIpAddress": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html#cfn-ec2-networkinterface-privateipspecification-privateipaddress", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinterface-privateipaddressspecification.html#cfn-ec2-networkinterface-privateipaddressspecification-privateipaddress", "PrimitiveType": "String", "Required": true, "UpdateType": "Mutable" @@ -23380,6 +23930,17 @@ } } }, + "AWS::EC2::TransitGatewayPeeringAttachment.TransitGatewayPeeringAttachmentOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-transitgatewaypeeringattachment-transitgatewaypeeringattachmentoptions.html", + "Properties": { + "DynamicRouting": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-transitgatewaypeeringattachment-transitgatewaypeeringattachmentoptions.html#cfn-ec2-transitgatewaypeeringattachment-transitgatewaypeeringattachmentoptions-dynamicrouting", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::EC2::VPNConnection.VpnTunnelOptionsSpecification": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-vpnconnection-vpntunneloptionsspecification.html", "Properties": { @@ -25027,21 +25588,33 @@ } } }, + "AWS::EKS::Cluster.ClusterLogging": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-clusterlogging.html", + "Properties": { + "EnabledTypes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-clusterlogging.html#cfn-eks-cluster-clusterlogging-enabledtypes", + "ItemType": "LoggingTypeConfig", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::EKS::Cluster.EncryptionConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-encryptionconfig.html", "Properties": { "Provider": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-encryptionconfig.html#cfn-eks-cluster-encryptionconfig-provider", + "PrimitiveType": "Json", "Required": false, - "Type": "Provider", - "UpdateType": "Mutable" + "UpdateType": "Immutable" }, "Resources": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-encryptionconfig.html#cfn-eks-cluster-encryptionconfig-resources", "PrimitiveItemType": "String", "Required": false, "Type": "List", - "UpdateType": "Mutable" + "UpdateType": "Immutable" } } }, @@ -25052,15 +25625,26 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-kubernetesnetworkconfig.html#cfn-eks-cluster-kubernetesnetworkconfig-serviceipv4cidr", "PrimitiveType": "String", "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::EKS::Cluster.Logging": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-logging.html", + "Properties": { + "ClusterLogging": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-logging.html#cfn-eks-cluster-logging-clusterlogging", + "Required": false, + "Type": "ClusterLogging", "UpdateType": "Mutable" } } }, - "AWS::EKS::Cluster.Provider": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-provider.html", + "AWS::EKS::Cluster.LoggingTypeConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-loggingtypeconfig.html", "Properties": { - "KeyArn": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-provider.html#cfn-eks-cluster-provider-keyarn", + "Type": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-loggingtypeconfig.html#cfn-eks-cluster-loggingtypeconfig-type", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" @@ -25070,19 +25654,38 @@ "AWS::EKS::Cluster.ResourcesVpcConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-resourcesvpcconfig.html", "Properties": { + "EndpointPrivateAccess": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-resourcesvpcconfig.html#cfn-eks-cluster-resourcesvpcconfig-endpointprivateaccess", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "EndpointPublicAccess": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-resourcesvpcconfig.html#cfn-eks-cluster-resourcesvpcconfig-endpointpublicaccess", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "PublicAccessCidrs": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-resourcesvpcconfig.html#cfn-eks-cluster-resourcesvpcconfig-publicaccesscidrs", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "SecurityGroupIds": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-resourcesvpcconfig.html#cfn-eks-cluster-resourcesvpcconfig-securitygroupids", "PrimitiveItemType": "String", "Required": false, "Type": "List", - "UpdateType": "Mutable" + "UpdateType": "Immutable" }, "SubnetIds": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-resourcesvpcconfig.html#cfn-eks-cluster-resourcesvpcconfig-subnetids", "PrimitiveItemType": "String", "Required": true, "Type": "List", - "UpdateType": "Mutable" + "UpdateType": "Immutable" } } }, @@ -35964,8 +36567,7 @@ } }, "AWS::IoTAnalytics::Channel.ServiceManagedS3": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-channel-servicemanageds3.html", - "Properties": {} + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-channel-servicemanageds3.html" }, "AWS::IoTAnalytics::Dataset.Action": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-action.html", @@ -36013,6 +36615,7 @@ }, "Variables": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-containeraction.html#cfn-iotanalytics-dataset-containeraction-variables", + "DuplicatesAllowed": true, "ItemType": "Variable", "Required": false, "Type": "List", @@ -36055,12 +36658,12 @@ } }, "AWS::IoTAnalytics::Dataset.DatasetContentVersionValue": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-variable-datasetcontentversionvalue.html", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-datasetcontentversionvalue.html", "Properties": { "DatasetName": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-variable-datasetcontentversionvalue.html#cfn-iotanalytics-dataset-variable-datasetcontentversionvalue-datasetname", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-datasetcontentversionvalue.html#cfn-iotanalytics-dataset-datasetcontentversionvalue-datasetname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" } } @@ -36167,12 +36770,12 @@ } }, "AWS::IoTAnalytics::Dataset.OutputFileUriValue": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-variable-outputfileurivalue.html", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-outputfileurivalue.html", "Properties": { "FileName": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-variable-outputfileurivalue.html#cfn-iotanalytics-dataset-variable-outputfileurivalue-filename", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-outputfileurivalue.html#cfn-iotanalytics-dataset-outputfileurivalue-filename", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" } } @@ -36182,6 +36785,7 @@ "Properties": { "Filters": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-queryaction.html#cfn-iotanalytics-dataset-queryaction-filters", + "DuplicatesAllowed": true, "ItemType": "Filter", "Required": false, "Type": "List", @@ -36259,10 +36863,10 @@ } }, "AWS::IoTAnalytics::Dataset.Schedule": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-trigger-schedule.html", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-schedule.html", "Properties": { "ScheduleExpression": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-trigger-schedule.html#cfn-iotanalytics-dataset-trigger-schedule-scheduleexpression", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-schedule.html#cfn-iotanalytics-dataset-schedule-scheduleexpression", "PrimitiveType": "String", "Required": true, "UpdateType": "Mutable" @@ -36428,6 +37032,7 @@ "Properties": { "Partitions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-datastorepartitions.html#cfn-iotanalytics-datastore-datastorepartitions-partitions", + "DuplicatesAllowed": true, "ItemType": "DatastorePartition", "Required": false, "Type": "List", @@ -36480,15 +37085,14 @@ "Properties": { "CustomerManagedS3Storage": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-iotsitewisemultilayerstorage.html#cfn-iotanalytics-datastore-iotsitewisemultilayerstorage-customermanageds3storage", - "Required": true, + "Required": false, "Type": "CustomerManagedS3Storage", "UpdateType": "Mutable" } } }, "AWS::IoTAnalytics::Datastore.JsonConfiguration": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-jsonconfiguration.html", - "Properties": {} + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-jsonconfiguration.html" }, "AWS::IoTAnalytics::Datastore.ParquetConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-parquetconfiguration.html", @@ -36534,6 +37138,7 @@ "Properties": { "Columns": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-schemadefinition.html#cfn-iotanalytics-datastore-schemadefinition-columns", + "DuplicatesAllowed": true, "ItemType": "Column", "Required": false, "Type": "List", @@ -36542,8 +37147,7 @@ } }, "AWS::IoTAnalytics::Datastore.ServiceManagedS3": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-servicemanageds3.html", - "Properties": {} + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-servicemanageds3.html" }, "AWS::IoTAnalytics::Datastore.TimestampPartition": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-timestamppartition.html", @@ -36632,14 +37236,15 @@ "Properties": { "Attributes": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-addattributes.html#cfn-iotanalytics-pipeline-addattributes-attributes", - "PrimitiveType": "Json", - "Required": false, + "PrimitiveItemType": "String", + "Required": true, + "Type": "Map", "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-addattributes.html#cfn-iotanalytics-pipeline-addattributes-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36656,13 +37261,13 @@ "ChannelName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-channel.html#cfn-iotanalytics-pipeline-channel-channelname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-channel.html#cfn-iotanalytics-pipeline-channel-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36679,13 +37284,13 @@ "DatastoreName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-datastore.html#cfn-iotanalytics-pipeline-datastore-datastorename", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-datastore.html#cfn-iotanalytics-pipeline-datastore-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" } } @@ -36696,13 +37301,13 @@ "Attribute": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceregistryenrich.html#cfn-iotanalytics-pipeline-deviceregistryenrich-attribute", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceregistryenrich.html#cfn-iotanalytics-pipeline-deviceregistryenrich-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36714,13 +37319,13 @@ "RoleArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceregistryenrich.html#cfn-iotanalytics-pipeline-deviceregistryenrich-rolearn", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "ThingName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceregistryenrich.html#cfn-iotanalytics-pipeline-deviceregistryenrich-thingname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" } } @@ -36731,13 +37336,13 @@ "Attribute": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceshadowenrich.html#cfn-iotanalytics-pipeline-deviceshadowenrich-attribute", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceshadowenrich.html#cfn-iotanalytics-pipeline-deviceshadowenrich-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36749,13 +37354,13 @@ "RoleArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceshadowenrich.html#cfn-iotanalytics-pipeline-deviceshadowenrich-rolearn", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "ThingName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceshadowenrich.html#cfn-iotanalytics-pipeline-deviceshadowenrich-thingname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" } } @@ -36766,13 +37371,13 @@ "Filter": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-filter.html#cfn-iotanalytics-pipeline-filter-filter", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-filter.html#cfn-iotanalytics-pipeline-filter-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36789,19 +37394,19 @@ "BatchSize": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-lambda.html#cfn-iotanalytics-pipeline-lambda-batchsize", "PrimitiveType": "Integer", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "LambdaName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-lambda.html#cfn-iotanalytics-pipeline-lambda-lambdaname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-lambda.html#cfn-iotanalytics-pipeline-lambda-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36818,19 +37423,19 @@ "Attribute": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-math.html#cfn-iotanalytics-pipeline-math-attribute", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Math": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-math.html#cfn-iotanalytics-pipeline-math-math", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-math.html#cfn-iotanalytics-pipeline-math-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36846,15 +37451,16 @@ "Properties": { "Attributes": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-removeattributes.html#cfn-iotanalytics-pipeline-removeattributes-attributes", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", - "Required": false, + "Required": true, "Type": "List", "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-removeattributes.html#cfn-iotanalytics-pipeline-removeattributes-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36870,15 +37476,16 @@ "Properties": { "Attributes": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-selectattributes.html#cfn-iotanalytics-pipeline-selectattributes-attributes", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", - "Required": false, + "Required": true, "Type": "List", "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-selectattributes.html#cfn-iotanalytics-pipeline-selectattributes-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -50593,6 +51200,20 @@ "AWS::NetworkFirewall::FirewallPolicy.FirewallPolicy": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-firewallpolicy.html", "Properties": { + "StatefulDefaultActions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-firewallpolicy.html#cfn-networkfirewall-firewallpolicy-firewallpolicy-statefuldefaultactions", + "DuplicatesAllowed": false, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "StatefulEngineOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-firewallpolicy.html#cfn-networkfirewall-firewallpolicy-firewallpolicy-statefulengineoptions", + "Required": false, + "Type": "StatefulEngineOptions", + "UpdateType": "Mutable" + }, "StatefulRuleGroupReferences": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-firewallpolicy.html#cfn-networkfirewall-firewallpolicy-firewallpolicy-statefulrulegroupreferences", "DuplicatesAllowed": false, @@ -50648,9 +51269,26 @@ } } }, + "AWS::NetworkFirewall::FirewallPolicy.StatefulEngineOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-statefulengineoptions.html", + "Properties": { + "RuleOrder": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-statefulengineoptions.html#cfn-networkfirewall-firewallpolicy-statefulengineoptions-ruleorder", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::NetworkFirewall::FirewallPolicy.StatefulRuleGroupReference": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-statefulrulegroupreference.html", "Properties": { + "Priority": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-statefulrulegroupreference.html#cfn-networkfirewall-firewallpolicy-statefulrulegroupreference-priority", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, "ResourceArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-statefulrulegroupreference.html#cfn-networkfirewall-firewallpolicy-statefulrulegroupreference-resourcearn", "PrimitiveType": "String", @@ -50945,6 +51583,12 @@ "Required": true, "Type": "RulesSource", "UpdateType": "Mutable" + }, + "StatefulRuleOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-rulegroup.html#cfn-networkfirewall-rulegroup-rulegroup-statefulruleoptions", + "Required": false, + "Type": "StatefulRuleOptions", + "UpdateType": "Mutable" } } }, @@ -51069,6 +51713,17 @@ } } }, + "AWS::NetworkFirewall::RuleGroup.StatefulRuleOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-statefulruleoptions.html", + "Properties": { + "RuleOrder": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-statefulruleoptions.html#cfn-networkfirewall-rulegroup-statefulruleoptions-ruleorder", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::NetworkFirewall::RuleGroup.StatelessRule": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-statelessrule.html", "Properties": { @@ -53000,6 +53655,180 @@ } } }, + "AWS::Pinpoint::InAppTemplate.BodyConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-bodyconfig.html", + "Properties": { + "Alignment": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-bodyconfig.html#cfn-pinpoint-inapptemplate-bodyconfig-alignment", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Body": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-bodyconfig.html#cfn-pinpoint-inapptemplate-bodyconfig-body", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TextColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-bodyconfig.html#cfn-pinpoint-inapptemplate-bodyconfig-textcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Pinpoint::InAppTemplate.ButtonConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-buttonconfig.html", + "Properties": { + "Android": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-buttonconfig.html#cfn-pinpoint-inapptemplate-buttonconfig-android", + "Required": false, + "Type": "OverrideButtonConfiguration", + "UpdateType": "Mutable" + }, + "DefaultConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-buttonconfig.html#cfn-pinpoint-inapptemplate-buttonconfig-defaultconfig", + "Required": false, + "Type": "DefaultButtonConfiguration", + "UpdateType": "Mutable" + }, + "IOS": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-buttonconfig.html#cfn-pinpoint-inapptemplate-buttonconfig-ios", + "Required": false, + "Type": "OverrideButtonConfiguration", + "UpdateType": "Mutable" + }, + "Web": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-buttonconfig.html#cfn-pinpoint-inapptemplate-buttonconfig-web", + "Required": false, + "Type": "OverrideButtonConfiguration", + "UpdateType": "Mutable" + } + } + }, + "AWS::Pinpoint::InAppTemplate.DefaultButtonConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html", + "Properties": { + "BackgroundColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html#cfn-pinpoint-inapptemplate-defaultbuttonconfiguration-backgroundcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "BorderRadius": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html#cfn-pinpoint-inapptemplate-defaultbuttonconfiguration-borderradius", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "ButtonAction": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html#cfn-pinpoint-inapptemplate-defaultbuttonconfiguration-buttonaction", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Link": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html#cfn-pinpoint-inapptemplate-defaultbuttonconfiguration-link", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Text": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html#cfn-pinpoint-inapptemplate-defaultbuttonconfiguration-text", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TextColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html#cfn-pinpoint-inapptemplate-defaultbuttonconfiguration-textcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Pinpoint::InAppTemplate.HeaderConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-headerconfig.html", + "Properties": { + "Alignment": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-headerconfig.html#cfn-pinpoint-inapptemplate-headerconfig-alignment", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Header": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-headerconfig.html#cfn-pinpoint-inapptemplate-headerconfig-header", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TextColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-headerconfig.html#cfn-pinpoint-inapptemplate-headerconfig-textcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Pinpoint::InAppTemplate.InAppMessageContent": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html", + "Properties": { + "BackgroundColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html#cfn-pinpoint-inapptemplate-inappmessagecontent-backgroundcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "BodyConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html#cfn-pinpoint-inapptemplate-inappmessagecontent-bodyconfig", + "Required": false, + "Type": "BodyConfig", + "UpdateType": "Mutable" + }, + "HeaderConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html#cfn-pinpoint-inapptemplate-inappmessagecontent-headerconfig", + "Required": false, + "Type": "HeaderConfig", + "UpdateType": "Mutable" + }, + "ImageUrl": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html#cfn-pinpoint-inapptemplate-inappmessagecontent-imageurl", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "PrimaryBtn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html#cfn-pinpoint-inapptemplate-inappmessagecontent-primarybtn", + "Required": false, + "Type": "ButtonConfig", + "UpdateType": "Mutable" + }, + "SecondaryBtn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html#cfn-pinpoint-inapptemplate-inappmessagecontent-secondarybtn", + "Required": false, + "Type": "ButtonConfig", + "UpdateType": "Mutable" + } + } + }, + "AWS::Pinpoint::InAppTemplate.OverrideButtonConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-overridebuttonconfiguration.html", + "Properties": { + "ButtonAction": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-overridebuttonconfiguration.html#cfn-pinpoint-inapptemplate-overridebuttonconfiguration-buttonaction", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Link": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-overridebuttonconfiguration.html#cfn-pinpoint-inapptemplate-overridebuttonconfiguration-link", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::Pinpoint::PushTemplate.APNSPushNotificationTemplate": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-pushtemplate-apnspushnotificationtemplate.html", "Properties": { @@ -55910,6 +56739,103 @@ } } }, + "AWS::Redshift::EndpointAccess.VpcSecurityGroup": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-endpointaccess-vpcsecuritygroup.html", + "Properties": { + "Status": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-endpointaccess-vpcsecuritygroup.html#cfn-redshift-endpointaccess-vpcsecuritygroup-status", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "VpcSecurityGroupId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-endpointaccess-vpcsecuritygroup.html#cfn-redshift-endpointaccess-vpcsecuritygroup-vpcsecuritygroupid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::ScheduledAction.PauseClusterMessage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-pauseclustermessage.html", + "Properties": { + "ClusterIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-pauseclustermessage.html#cfn-redshift-scheduledaction-pauseclustermessage-clusteridentifier", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::ScheduledAction.ResizeClusterMessage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html", + "Properties": { + "Classic": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-classic", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "ClusterIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-clusteridentifier", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "ClusterType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-clustertype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "NodeType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-nodetype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "NumberOfNodes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-numberofnodes", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::ScheduledAction.ResumeClusterMessage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resumeclustermessage.html", + "Properties": { + "ClusterIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resumeclustermessage.html#cfn-redshift-scheduledaction-resumeclustermessage-clusteridentifier", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::ScheduledAction.ScheduledActionType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-scheduledactiontype.html", + "Properties": { + "PauseCluster": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-scheduledactiontype.html#cfn-redshift-scheduledaction-scheduledactiontype-pausecluster", + "Required": false, + "Type": "PauseClusterMessage", + "UpdateType": "Mutable" + }, + "ResizeCluster": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-scheduledactiontype.html#cfn-redshift-scheduledaction-scheduledactiontype-resizecluster", + "Required": false, + "Type": "ResizeClusterMessage", + "UpdateType": "Mutable" + }, + "ResumeCluster": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-scheduledactiontype.html#cfn-redshift-scheduledaction-scheduledactiontype-resumecluster", + "Required": false, + "Type": "ResumeClusterMessage", + "UpdateType": "Mutable" + } + } + }, "AWS::ResourceGroups::Group.ConfigurationItem": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-resourcegroups-group-configurationitem.html", "Properties": { @@ -60138,6 +61064,12 @@ "Type": "CapacitySize", "UpdateType": "Mutable" }, + "LinearStepSize": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-endpoint-trafficroutingconfig.html#cfn-sagemaker-endpoint-trafficroutingconfig-linearstepsize", + "Required": false, + "Type": "CapacitySize", + "UpdateType": "Mutable" + }, "Type": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-endpoint-trafficroutingconfig.html#cfn-sagemaker-endpoint-trafficroutingconfig-type", "PrimitiveType": "String", @@ -65160,7 +66092,7 @@ } } }, - "ResourceSpecificationVersion": "46.0.0", + "ResourceSpecificationVersion": "47.0.0", "ResourceTypes": { "AWS::ACMPCA::Certificate": { "Attributes": { @@ -71860,6 +72792,25 @@ } } }, + "AWS::CloudFront::ResponseHeadersPolicy": { + "Attributes": { + "Id": { + "PrimitiveType": "String" + }, + "LastModifiedTime": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-responseheaderspolicy.html", + "Properties": { + "ResponseHeadersPolicyConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-responseheaderspolicy.html#cfn-cloudfront-responseheaderspolicy-responseheaderspolicyconfig", + "Required": true, + "Type": "ResponseHeadersPolicyConfig", + "UpdateType": "Mutable" + } + } + }, "AWS::CloudFront::StreamingDistribution": { "Attributes": { "DomainName": { @@ -75133,6 +76084,12 @@ "Type": "PostgreSqlSettings", "UpdateType": "Mutable" }, + "RedisSettings": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dms-endpoint.html#cfn-dms-endpoint-redissettings", + "Required": false, + "Type": "RedisSettings", + "UpdateType": "Mutable" + }, "RedshiftSettings": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dms-endpoint.html#cfn-dms-endpoint-redshiftsettings", "Required": false, @@ -75937,6 +76894,101 @@ } } }, + "AWS::DataSync::LocationHDFS": { + "Attributes": { + "LocationArn": { + "PrimitiveType": "String" + }, + "LocationUri": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html", + "Properties": { + "AgentArns": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-agentarns", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "AuthenticationType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-authenticationtype", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "BlockSize": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-blocksize", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "KerberosKeytab": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-kerberoskeytab", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "KerberosKrb5Conf": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-kerberoskrb5conf", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "KerberosPrincipal": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-kerberosprincipal", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "KmsKeyProviderUri": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-kmskeyprovideruri", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "NameNodes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-namenodes", + "ItemType": "NameNode", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "QopConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-qopconfiguration", + "Required": false, + "Type": "QopConfiguration", + "UpdateType": "Mutable" + }, + "ReplicationFactor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-replicationfactor", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "SimpleUser": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-simpleuser", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Subdirectory": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-subdirectory", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-tags", + "DuplicatesAllowed": false, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::DataSync::LocationNFS": { "Attributes": { "LocationArn": { @@ -77944,6 +78996,11 @@ } }, "AWS::EC2::InternetGateway": { + "Attributes": { + "InternetGatewayId": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internetgateway.html", "Properties": { "Tags": { @@ -78296,44 +79353,48 @@ }, "AWS::EC2::NetworkInterface": { "Attributes": { + "Id": { + "PrimitiveType": "String" + }, "PrimaryPrivateIpAddress": { "PrimitiveType": "String" }, "SecondaryPrivateIpAddresses": { + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Type": "List" } }, - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html", "Properties": { "Description": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-description", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-description", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" }, "GroupSet": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-groupset", - "DuplicatesAllowed": false, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-groupset", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", "UpdateType": "Mutable" }, "InterfaceType": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-interfacetype", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-interfacetype", "PrimitiveType": "String", "Required": false, "UpdateType": "Immutable" }, "Ipv6AddressCount": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-ipv6addresscount", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-ipv6addresscount", "PrimitiveType": "Integer", "Required": false, "UpdateType": "Mutable" }, "Ipv6Addresses": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-ipv6addresses", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-ipv6addresses", "DuplicatesAllowed": false, "ItemType": "InstanceIpv6Address", "Required": false, @@ -78341,39 +79402,39 @@ "UpdateType": "Mutable" }, "PrivateIpAddress": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-privateipaddress", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-privateipaddress", "PrimitiveType": "String", "Required": false, "UpdateType": "Immutable" }, "PrivateIpAddresses": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-privateipaddresses", - "DuplicatesAllowed": false, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-privateipaddresses", + "DuplicatesAllowed": true, "ItemType": "PrivateIpAddressSpecification", "Required": false, "Type": "List", - "UpdateType": "Conditional" + "UpdateType": "Mutable" }, "SecondaryPrivateIpAddressCount": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-secondaryprivateipcount", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-secondaryprivateipaddresscount", "PrimitiveType": "Integer", "Required": false, "UpdateType": "Mutable" }, "SourceDestCheck": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-sourcedestcheck", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-sourcedestcheck", "PrimitiveType": "Boolean", "Required": false, "UpdateType": "Mutable" }, "SubnetId": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-subnetid", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-subnetid", "PrimitiveType": "String", "Required": true, "UpdateType": "Immutable" }, "Tags": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-tags", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-tags", "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, @@ -79451,6 +80512,12 @@ }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaypeeringattachment.html", "Properties": { + "Options": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaypeeringattachment.html#cfn-ec2-transitgatewaypeeringattachment-options", + "Required": false, + "Type": "TransitGatewayPeeringAttachmentOptions", + "UpdateType": "Mutable" + }, "PeerAccountId": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaypeeringattachment.html#cfn-ec2-transitgatewaypeeringattachment-peeraccountid", "PrimitiveType": "String", @@ -79857,6 +80924,12 @@ "Required": false, "Type": "List", "UpdateType": "Mutable" + }, + "PayerResponsibility": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservice.html#cfn-ec2-vpcendpointservice-payerresponsibility", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" } } }, @@ -80997,6 +82070,12 @@ "Type": "KubernetesNetworkConfig", "UpdateType": "Immutable" }, + "Logging": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-logging", + "Required": false, + "Type": "Logging", + "UpdateType": "Mutable" + }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-name", "PrimitiveType": "String", @@ -81007,7 +82086,7 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-resourcesvpcconfig", "Required": true, "Type": "ResourcesVpcConfig", - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "RoleArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-rolearn", @@ -81015,6 +82094,14 @@ "Required": true, "UpdateType": "Immutable" }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-tags", + "DuplicatesAllowed": false, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "Version": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-version", "PrimitiveType": "String", @@ -88225,6 +89312,29 @@ } } }, + "AWS::IoT::Logging": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-logging.html", + "Properties": { + "AccountId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-logging.html#cfn-iot-logging-accountid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "DefaultLogLevel": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-logging.html#cfn-iot-logging-defaultloglevel", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "RoleArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-logging.html#cfn-iot-logging-rolearn", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::IoT::MitigationAction": { "Attributes": { "MitigationActionArn": { @@ -88356,6 +89466,34 @@ } } }, + "AWS::IoT::ResourceSpecificLogging": { + "Attributes": { + "TargetId": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-resourcespecificlogging.html", + "Properties": { + "LogLevel": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-resourcespecificlogging.html#cfn-iot-resourcespecificlogging-loglevel", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "TargetName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-resourcespecificlogging.html#cfn-iot-resourcespecificlogging-targetname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "TargetType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-resourcespecificlogging.html#cfn-iot-resourcespecificlogging-targettype", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, "AWS::IoT::ScheduledAudit": { "Attributes": { "ScheduledAuditArn": { @@ -88562,12 +89700,17 @@ } }, "AWS::IoTAnalytics::Channel": { + "Attributes": { + "Id": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-channel.html", "Properties": { "ChannelName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-channel.html#cfn-iotanalytics-channel-channelname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Immutable" }, "ChannelStorage": { @@ -88584,6 +89727,7 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-channel.html#cfn-iotanalytics-channel-tags", + "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, "Type": "List", @@ -88592,10 +89736,16 @@ } }, "AWS::IoTAnalytics::Dataset": { + "Attributes": { + "Id": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html", "Properties": { "Actions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html#cfn-iotanalytics-dataset-actions", + "DuplicatesAllowed": true, "ItemType": "Action", "Required": true, "Type": "List", @@ -88603,6 +89753,7 @@ }, "ContentDeliveryRules": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html#cfn-iotanalytics-dataset-contentdeliveryrules", + "DuplicatesAllowed": true, "ItemType": "DatasetContentDeliveryRule", "Required": false, "Type": "List", @@ -88611,11 +89762,12 @@ "DatasetName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html#cfn-iotanalytics-dataset-datasetname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Immutable" }, "LateDataRules": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html#cfn-iotanalytics-dataset-latedatarules", + "DuplicatesAllowed": true, "ItemType": "LateDataRule", "Required": false, "Type": "List", @@ -88629,6 +89781,7 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html#cfn-iotanalytics-dataset-tags", + "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, "Type": "List", @@ -88636,6 +89789,7 @@ }, "Triggers": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html#cfn-iotanalytics-dataset-triggers", + "DuplicatesAllowed": true, "ItemType": "Trigger", "Required": false, "Type": "List", @@ -88650,6 +89804,11 @@ } }, "AWS::IoTAnalytics::Datastore": { + "Attributes": { + "Id": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-datastore.html", "Properties": { "DatastoreName": { @@ -88684,6 +89843,7 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-datastore.html#cfn-iotanalytics-datastore-tags", + "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, "Type": "List", @@ -88692,10 +89852,16 @@ } }, "AWS::IoTAnalytics::Pipeline": { + "Attributes": { + "Id": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-pipeline.html", "Properties": { "PipelineActivities": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-pipeline.html#cfn-iotanalytics-pipeline-pipelineactivities", + "DuplicatesAllowed": true, "ItemType": "Activity", "Required": true, "Type": "List", @@ -88704,11 +89870,12 @@ "PipelineName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-pipeline.html#cfn-iotanalytics-pipeline-pipelinename", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Immutable" }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-pipeline.html#cfn-iotanalytics-pipeline-tags", + "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, "Type": "List", @@ -96373,6 +97540,53 @@ } } }, + "AWS::Pinpoint::InAppTemplate": { + "Attributes": { + "Arn": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html", + "Properties": { + "Content": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html#cfn-pinpoint-inapptemplate-content", + "ItemType": "InAppMessageContent", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "CustomConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html#cfn-pinpoint-inapptemplate-customconfig", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Mutable" + }, + "Layout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html#cfn-pinpoint-inapptemplate-layout", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html#cfn-pinpoint-inapptemplate-tags", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Mutable" + }, + "TemplateDescription": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html#cfn-pinpoint-inapptemplate-templatedescription", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TemplateName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html#cfn-pinpoint-inapptemplate-templatename", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, "AWS::Pinpoint::PushTemplate": { "Attributes": { "Arn": { @@ -98792,6 +100006,257 @@ } } }, + "AWS::Redshift::EndpointAccess": { + "Attributes": { + "Address": { + "PrimitiveType": "String" + }, + "EndpointCreateTime": { + "PrimitiveType": "String" + }, + "EndpointStatus": { + "PrimitiveType": "String" + }, + "Port": { + "PrimitiveType": "Integer" + }, + "VpcSecurityGroups": { + "ItemType": "VpcSecurityGroup", + "Type": "List" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html", + "Properties": { + "ClusterIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-clusteridentifier", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "EndpointName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-endpointname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "ResourceOwner": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-resourceowner", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "SubnetGroupName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-subnetgroupname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "VpcSecurityGroupIds": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-vpcsecuritygroupids", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::EndpointAuthorization": { + "Attributes": { + "AllowedAllVPCs": { + "PrimitiveType": "Boolean" + }, + "AllowedVPCs": { + "PrimitiveItemType": "String", + "Type": "List" + }, + "AuthorizeTime": { + "PrimitiveType": "String" + }, + "ClusterStatus": { + "PrimitiveType": "String" + }, + "EndpointCount": { + "PrimitiveType": "Integer" + }, + "Grantee": { + "PrimitiveType": "String" + }, + "Grantor": { + "PrimitiveType": "String" + }, + "Status": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html", + "Properties": { + "Account": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-account", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "ClusterIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-clusteridentifier", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Force": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-force", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "VpcIds": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-vpcids", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::EventSubscription": { + "Attributes": { + "CustSubscriptionId": { + "PrimitiveType": "String" + }, + "CustomerAwsId": { + "PrimitiveType": "String" + }, + "EventCategoriesList": { + "PrimitiveItemType": "String", + "Type": "List" + }, + "SourceIdsList": { + "PrimitiveItemType": "String", + "Type": "List" + }, + "Status": { + "PrimitiveType": "String" + }, + "SubscriptionCreationTime": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html", + "Properties": { + "Enabled": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-enabled", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "EventCategories": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-eventcategories", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "Severity": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-severity", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SnsTopicArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-snstopicarn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SourceIds": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-sourceids", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "SourceType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-sourcetype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SubscriptionName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-subscriptionname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::ScheduledAction": { + "Attributes": { + "NextInvocations": { + "PrimitiveItemType": "String", + "Type": "List" + }, + "State": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html", + "Properties": { + "Enable": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-enable", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "EndTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-endtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "IamRole": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-iamrole", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Schedule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-schedule", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ScheduledActionDescription": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-scheduledactiondescription", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ScheduledActionName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-scheduledactionname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "StartTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-starttime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TargetAction": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-targetaction", + "Required": false, + "Type": "ScheduledActionType", + "UpdateType": "Mutable" + } + } + }, "AWS::Rekognition::Project": { "Attributes": { "Arn": { @@ -100388,7 +101853,7 @@ "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3objectlambda-accesspoint.html#cfn-s3objectlambda-accesspoint-name", "PrimitiveType": "String", - "Required": true, + "Required": false, "UpdateType": "Immutable" }, "ObjectLambdaConfiguration": { @@ -102174,6 +103639,12 @@ "Required": false, "UpdateType": "Mutable" }, + "RetainDeploymentConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-endpoint.html#cfn-sagemaker-endpoint-retaindeploymentconfig", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-endpoint.html#cfn-sagemaker-endpoint-tags", "ItemType": "Tag", From 7886607528b0cb005fa1176803b2a45d3e948f48 Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Fri, 5 Nov 2021 16:31:22 +0530 Subject: [PATCH 142/148] feat(cfnspec): cloudformation spec v47.0.0 (#17353) Co-authored-by: AWS CDK Team Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> From 332ce4d9ae995bd1336fef13e2c7f9fc0c12f34d Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 5 Nov 2021 12:58:12 +0100 Subject: [PATCH 143/148] fix(cli): `wmic not found` on modern Windows systems (#17070) Apparently Microsoft stopped shipping `wmic.exe` in certain situations (modern systems?). We rely on this to detect whether we are on an EC2 instance, so that we do or do not configure the IMDS credential provider (we try to avoid the IMDS credential provider if unnecessary, because in certain network setups it may hang for a long time failing to connect to `169.254.169.254`). If calling `wmic` fails, just assume we're not on an EC2 instance and proceed. Fixes #16419. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/api/aws-auth/awscli-compatible.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/aws-cdk/lib/api/aws-auth/awscli-compatible.ts b/packages/aws-cdk/lib/api/aws-auth/awscli-compatible.ts index b409274efa59c..eb141768b9644 100644 --- a/packages/aws-cdk/lib/api/aws-auth/awscli-compatible.ts +++ b/packages/aws-cdk/lib/api/aws-auth/awscli-compatible.ts @@ -177,12 +177,18 @@ async function isEc2Instance() { let instance = false; if (process.platform === 'win32') { // https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/identify_ec2_instances.html - const result = await util.promisify(child_process.exec)('wmic path win32_computersystemproduct get uuid', { encoding: 'utf-8' }); - // output looks like - // UUID - // EC2AE145-D1DC-13B2-94ED-01234ABCDEF - const lines = result.stdout.toString().split('\n'); - instance = lines.some(x => matchesRegex(/^ec2/i, x)); + try { + const result = await util.promisify(child_process.exec)('wmic path win32_computersystemproduct get uuid', { encoding: 'utf-8' }); + // output looks like + // UUID + // EC2AE145-D1DC-13B2-94ED-01234ABCDEF + const lines = result.stdout.toString().split('\n'); + instance = lines.some(x => matchesRegex(/^ec2/i, x)); + } catch (e) { + // Modern machines may not have wmic.exe installed. No reason to fail, just assume it's not an EC2 instance. + debug(`Checking using WMIC failed, assuming NOT an EC2 instance: ${e.message} (pass --ec2creds to force)`); + instance = false; + } } else { // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html const files: Array<[string, RegExp]> = [ From 9e81dc731993a55fbc05c642ce96151f12ed69da Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 5 Nov 2021 13:54:00 +0100 Subject: [PATCH 144/148] fix(pipelines): `additionalInputs` not working (#17279) The rendering of `additionalInputs` was using a bashism that is not supported by CodeBuild by default. Turn ``` [[ ! -d "directory" ]] ``` into ``` [ ! -d "directory" ] ``` Fixes #17224 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts | 2 +- .../pipelines/test/codepipeline/codebuild-step.test.ts | 2 +- packages/@aws-cdk/pipelines/test/compliance/synths.test.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts b/packages/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts index fb523cf7d6818..7534aba9cb840 100644 --- a/packages/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts +++ b/packages/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts @@ -333,7 +333,7 @@ function generateInputArtifactLinkCommands(artifacts: ArtifactMap, inputs: FileS return inputs.map(input => { const fragments = []; - fragments.push(`[[ ! -d "${input.directory}" ]] || { echo 'additionalInputs: "${input.directory}" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.'; exit 1; }`); + fragments.push(`[ ! -d "${input.directory}" ] || { echo 'additionalInputs: "${input.directory}" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.'; exit 1; }`); const parentDirectory = path.dirname(input.directory); if (!['.', '..'].includes(parentDirectory)) { diff --git a/packages/@aws-cdk/pipelines/test/codepipeline/codebuild-step.test.ts b/packages/@aws-cdk/pipelines/test/codepipeline/codebuild-step.test.ts index 78f1e0f471655..166e6c9336dd1 100644 --- a/packages/@aws-cdk/pipelines/test/codepipeline/codebuild-step.test.ts +++ b/packages/@aws-cdk/pipelines/test/codepipeline/codebuild-step.test.ts @@ -34,7 +34,7 @@ test('additionalinputs creates the right commands', () => { phases: { install: { commands: [ - '[[ ! -d "some/deep/directory" ]] || { echo \'additionalInputs: "some/deep/directory" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.\'; exit 1; } && mkdir -p -- "some/deep" && ln -s -- "$CODEBUILD_SRC_DIR_test2_test2_Source" "some/deep/directory"', + '[ ! -d "some/deep/directory" ] || { echo \'additionalInputs: "some/deep/directory" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.\'; exit 1; } && mkdir -p -- "some/deep" && ln -s -- "$CODEBUILD_SRC_DIR_test2_test2_Source" "some/deep/directory"', ], }, }, diff --git a/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts b/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts index acbce1d765f36..03ee0686f1807 100644 --- a/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts +++ b/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts @@ -947,8 +947,8 @@ behavior('Multiple input sources in side-by-side directories', (suite) => { phases: { install: { commands: [ - '[[ ! -d "../sibling" ]] || { echo \'additionalInputs: "../sibling" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.\'; exit 1; } && ln -s -- "$CODEBUILD_SRC_DIR_foo_bar_Source" "../sibling"', - '[[ ! -d "sub" ]] || { echo \'additionalInputs: "sub" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.\'; exit 1; } && ln -s -- "$CODEBUILD_SRC_DIR_Prebuild_Output" "sub"', + '[ ! -d "../sibling" ] || { echo \'additionalInputs: "../sibling" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.\'; exit 1; } && ln -s -- "$CODEBUILD_SRC_DIR_foo_bar_Source" "../sibling"', + '[ ! -d "sub" ] || { echo \'additionalInputs: "sub" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.\'; exit 1; } && ln -s -- "$CODEBUILD_SRC_DIR_Prebuild_Output" "sub"', ], }, build: { From 1aa1588640b34be1dc027f79e3b9dd90e9b8b26f Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Fri, 5 Nov 2021 16:06:15 +0200 Subject: [PATCH 145/148] chore: remove invalid test from regression suite (#17345) Follow up on https://github.com/aws/aws-cdk/pull/17337 to fix regression suites. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../cli-regression-patches/v1.130.0/NOTES.md | 10 +- .../v1.130.0/bootstrapping.integtest.js | 220 ++++++++++++++++++ 2 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/bootstrapping.integtest.js diff --git a/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md index 9a9338f4d04fb..5e17983dd23b4 100644 --- a/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md +++ b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md @@ -1,4 +1,12 @@ +--------------------------------------- + On november 2nd 2021, lambda started deprecating the nodejs10.x runtime. This meant we can no longer create functions with this runtime. Our integration tests use this runtime for one of its stacks. -This patch brings https://github.com/aws/aws-cdk/pull/17282 into the regression suite. \ No newline at end of file +This patch brings https://github.com/aws/aws-cdk/pull/17282 into the regression suite. + +---------------------------------------- + +Needs to disable an existing test due to change in bootstrap of integration tests. + +This patch brings https://github.com/aws/aws-cdk/pull/17337 into the regression suite. \ No newline at end of file diff --git a/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/bootstrapping.integtest.js b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/bootstrapping.integtest.js new file mode 100644 index 0000000000000..5895d49ff1ad9 --- /dev/null +++ b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/bootstrapping.integtest.js @@ -0,0 +1,220 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = require("fs"); +const path = require("path"); +const cdk_1 = require("../helpers/cdk"); +const test_helpers_1 = require("../helpers/test-helpers"); +const timeout = process.env.CODEBUILD_BUILD_ID ? // if the process is running in CodeBuild + 3600000 : // 1 hour + 600000; // 10 minutes +jest.setTimeout(timeout); +process.stdout.write(`bootstrapping.integtest.ts: Setting jest time out to ${timeout} ms`); +test_helpers_1.integTest('can bootstrap without execution', cdk_1.withDefaultFixture(async (fixture) => { + var _a; + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapLegacy({ + toolkitStackName: bootstrapStackName, + noExecute: true, + }); + const resp = await fixture.aws.cloudFormation('describeStacks', { + StackName: bootstrapStackName, + }); + expect((_a = resp.Stacks) === null || _a === void 0 ? void 0 : _a[0].StackStatus).toEqual('REVIEW_IN_PROGRESS'); +})); +test_helpers_1.integTest('upgrade legacy bootstrap stack to new bootstrap stack while in use', cdk_1.withDefaultFixture(async (fixture) => { + const bootstrapStackName = fixture.bootstrapStackName; + const legacyBootstrapBucketName = `aws-cdk-bootstrap-integ-test-legacy-bckt-${cdk_1.randomString()}`; + const newBootstrapBucketName = `aws-cdk-bootstrap-integ-test-v2-bckt-${cdk_1.randomString()}`; + fixture.rememberToDeleteBucket(legacyBootstrapBucketName); // This one will leak + fixture.rememberToDeleteBucket(newBootstrapBucketName); // This one shouldn't leak if the test succeeds, but let's be safe in case it doesn't + // Legacy bootstrap + await fixture.cdkBootstrapLegacy({ + toolkitStackName: bootstrapStackName, + bootstrapBucketName: legacyBootstrapBucketName, + }); + // Deploy stack that uses file assets + await fixture.cdkDeploy('lambda', { + options: ['--toolkit-stack-name', bootstrapStackName], + }); + // Upgrade bootstrap stack to "new" style + await fixture.cdkBootstrapModern({ + toolkitStackName: bootstrapStackName, + bootstrapBucketName: newBootstrapBucketName, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + // (Force) deploy stack again + // --force to bypass the check which says that the template hasn't changed. + await fixture.cdkDeploy('lambda', { + options: [ + '--toolkit-stack-name', bootstrapStackName, + '--force', + ], + }); +})); +test_helpers_1.integTest('can and deploy if omitting execution policies', cdk_1.withDefaultFixture(async (fixture) => { + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + toolkitStackName: bootstrapStackName, + }); + // Deploy stack that uses file assets + await fixture.cdkDeploy('lambda', { + options: [ + '--toolkit-stack-name', bootstrapStackName, + '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`, + '--context', '@aws-cdk/core:newStyleStackSynthesis=1', + ], + }); +})); +test_helpers_1.integTest('deploy new style synthesis to new style bootstrap', cdk_1.withDefaultFixture(async (fixture) => { + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + toolkitStackName: bootstrapStackName, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + // Deploy stack that uses file assets + await fixture.cdkDeploy('lambda', { + options: [ + '--toolkit-stack-name', bootstrapStackName, + '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`, + '--context', '@aws-cdk/core:newStyleStackSynthesis=1', + ], + }); +})); +test_helpers_1.integTest('deploy new style synthesis to new style bootstrap (with docker image)', cdk_1.withDefaultFixture(async (fixture) => { + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + toolkitStackName: bootstrapStackName, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + // Deploy stack that uses file assets + await fixture.cdkDeploy('docker', { + options: [ + '--toolkit-stack-name', bootstrapStackName, + '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`, + '--context', '@aws-cdk/core:newStyleStackSynthesis=1', + ], + }); +})); +test_helpers_1.integTest('deploy old style synthesis to new style bootstrap', cdk_1.withDefaultFixture(async (fixture) => { + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + toolkitStackName: bootstrapStackName, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + // Deploy stack that uses file assets + await fixture.cdkDeploy('lambda', { + options: [ + '--toolkit-stack-name', bootstrapStackName, + ], + }); +})); +test_helpers_1.integTest('can create a legacy bootstrap stack with --public-access-block-configuration=false', cdk_1.withDefaultFixture(async (fixture) => { + var _a; + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapLegacy({ + verbose: true, + toolkitStackName: bootstrapStackName, + publicAccessBlockConfiguration: false, + tags: 'Foo=Bar', + }); + const response = await fixture.aws.cloudFormation('describeStacks', { StackName: bootstrapStackName }); + expect((_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].Tags).toEqual([ + { Key: 'Foo', Value: 'Bar' }, + ]); +})); +test_helpers_1.integTest('can create multiple legacy bootstrap stacks', cdk_1.withDefaultFixture(async (fixture) => { + var _a; + const bootstrapStackName1 = `${fixture.bootstrapStackName}-1`; + const bootstrapStackName2 = `${fixture.bootstrapStackName}-2`; + // deploy two toolkit stacks into the same environment (see #1416) + // one with tags + await fixture.cdkBootstrapLegacy({ + verbose: true, + toolkitStackName: bootstrapStackName1, + tags: 'Foo=Bar', + }); + await fixture.cdkBootstrapLegacy({ + verbose: true, + toolkitStackName: bootstrapStackName2, + }); + const response = await fixture.aws.cloudFormation('describeStacks', { StackName: bootstrapStackName1 }); + expect((_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].Tags).toEqual([ + { Key: 'Foo', Value: 'Bar' }, + ]); +})); +test_helpers_1.integTest('can dump the template, modify and use it to deploy a custom bootstrap stack', cdk_1.withDefaultFixture(async (fixture) => { + let template = await fixture.cdkBootstrapModern({ + // toolkitStackName doesn't matter for this particular invocation + toolkitStackName: fixture.bootstrapStackName, + showTemplate: true, + cliOptions: { + captureStderr: false, + }, + }); + expect(template).toContain('BootstrapVersion:'); + template += '\n' + [ + ' TwiddleDee:', + ' Value: Template got twiddled', + ].join('\n'); + const filename = path.join(fixture.integTestDir, `${fixture.qualifier}-template.yaml`); + fs.writeFileSync(filename, template, { encoding: 'utf-8' }); + await fixture.cdkBootstrapModern({ + toolkitStackName: fixture.bootstrapStackName, + template: filename, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); +})); +test_helpers_1.integTest('switch on termination protection, switch is left alone on re-bootstrap', cdk_1.withDefaultFixture(async (fixture) => { + var _a; + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + verbose: true, + toolkitStackName: bootstrapStackName, + terminationProtection: true, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + await fixture.cdkBootstrapModern({ + verbose: true, + toolkitStackName: bootstrapStackName, + force: true, + }); + const response = await fixture.aws.cloudFormation('describeStacks', { StackName: bootstrapStackName }); + expect((_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].EnableTerminationProtection).toEqual(true); +})); +test_helpers_1.integTest('add tags, left alone on re-bootstrap', cdk_1.withDefaultFixture(async (fixture) => { + var _a; + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + verbose: true, + toolkitStackName: bootstrapStackName, + tags: 'Foo=Bar', + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + await fixture.cdkBootstrapModern({ + verbose: true, + toolkitStackName: bootstrapStackName, + force: true, + }); + const response = await fixture.aws.cloudFormation('describeStacks', { StackName: bootstrapStackName }); + expect((_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].Tags).toEqual([ + { Key: 'Foo', Value: 'Bar' }, + ]); +})); +test_helpers_1.integTest('can deploy modern-synthesized stack even if bootstrap stack name is unknown', cdk_1.withDefaultFixture(async (fixture) => { + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + toolkitStackName: bootstrapStackName, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + // Deploy stack that uses file assets + await fixture.cdkDeploy('lambda', { + options: [ + // Explicity pass a name that's sure to not exist, otherwise the CLI might accidentally find a + // default bootstracp stack if that happens to be in the account already. + '--toolkit-stack-name', 'DefinitelyDoesNotExist', + '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`, + '--context', '@aws-cdk/core:newStyleStackSynthesis=1', + ], + }); +})); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9vdHN0cmFwcGluZy5pbnRlZ3Rlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJib290c3RyYXBwaW5nLmludGVndGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFDN0Isd0NBQWtFO0FBQ2xFLDBEQUFvRDtBQUVwRCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyx5Q0FBeUM7SUFDeEYsT0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTO0lBQ3JCLE1BQU8sQ0FBQyxDQUFDLGFBQWE7QUFDeEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUN6QixPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx3REFBd0QsT0FBTyxLQUFLLENBQUMsQ0FBQztBQUUzRix3QkFBUyxDQUFDLGlDQUFpQyxFQUFFLHdCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTs7SUFDaEYsTUFBTSxrQkFBa0IsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUM7SUFFdEQsTUFBTSxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDL0IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLFNBQVMsRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQztJQUVILE1BQU0sSUFBSSxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLEVBQUU7UUFDOUQsU0FBUyxFQUFFLGtCQUFrQjtLQUM5QixDQUFDLENBQUM7SUFFSCxNQUFNLE9BQUMsSUFBSSxDQUFDLE1BQU0sMENBQUcsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQ3JFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFSix3QkFBUyxDQUFDLG9FQUFvRSxFQUFFLHdCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUNuSCxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztJQUV0RCxNQUFNLHlCQUF5QixHQUFHLDRDQUE0QyxrQkFBWSxFQUFFLEVBQUUsQ0FBQztJQUMvRixNQUFNLHNCQUFzQixHQUFHLHdDQUF3QyxrQkFBWSxFQUFFLEVBQUUsQ0FBQztJQUN4RixPQUFPLENBQUMsc0JBQXNCLENBQUMseUJBQXlCLENBQUMsQ0FBQyxDQUFDLHFCQUFxQjtJQUNoRixPQUFPLENBQUMsc0JBQXNCLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLHFGQUFxRjtJQUU3SSxtQkFBbUI7SUFDbkIsTUFBTSxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDL0IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLG1CQUFtQixFQUFFLHlCQUF5QjtLQUMvQyxDQUFDLENBQUM7SUFFSCxxQ0FBcUM7SUFDckMsTUFBTSxPQUFPLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRTtRQUNoQyxPQUFPLEVBQUUsQ0FBQyxzQkFBc0IsRUFBRSxrQkFBa0IsQ0FBQztLQUN0RCxDQUFDLENBQUM7SUFFSCx5Q0FBeUM7SUFDekMsTUFBTSxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDL0IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLG1CQUFtQixFQUFFLHNCQUFzQjtRQUMzQyxrQkFBa0IsRUFBRSw2Q0FBNkM7S0FDbEUsQ0FBQyxDQUFDO0lBRUgsNkJBQTZCO0lBQzdCLDJFQUEyRTtJQUMzRSxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFO1FBQ2hDLE9BQU8sRUFBRTtZQUNQLHNCQUFzQixFQUFFLGtCQUFrQjtZQUMxQyxTQUFTO1NBQ1Y7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRUosd0JBQVMsQ0FBQywrQ0FBK0MsRUFBRSx3QkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7SUFDOUYsTUFBTSxrQkFBa0IsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUM7SUFFdEQsTUFBTSxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDL0IsZ0JBQWdCLEVBQUUsa0JBQWtCO0tBQ3JDLENBQUMsQ0FBQztJQUVILHFDQUFxQztJQUNyQyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFO1FBQ2hDLE9BQU8sRUFBRTtZQUNQLHNCQUFzQixFQUFFLGtCQUFrQjtZQUMxQyxXQUFXLEVBQUUsb0NBQW9DLE9BQU8sQ0FBQyxTQUFTLEVBQUU7WUFDcEUsV0FBVyxFQUFFLHdDQUF3QztTQUN0RDtLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFSix3QkFBUyxDQUFDLG1EQUFtRCxFQUFFLHdCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUNsRyxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztJQUV0RCxNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixnQkFBZ0IsRUFBRSxrQkFBa0I7UUFDcEMsa0JBQWtCLEVBQUUsNkNBQTZDO0tBQ2xFLENBQUMsQ0FBQztJQUVILHFDQUFxQztJQUNyQyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFO1FBQ2hDLE9BQU8sRUFBRTtZQUNQLHNCQUFzQixFQUFFLGtCQUFrQjtZQUMxQyxXQUFXLEVBQUUsb0NBQW9DLE9BQU8sQ0FBQyxTQUFTLEVBQUU7WUFDcEUsV0FBVyxFQUFFLHdDQUF3QztTQUN0RDtLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFSix3QkFBUyxDQUFDLHVFQUF1RSxFQUFFLHdCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUN0SCxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztJQUV0RCxNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixnQkFBZ0IsRUFBRSxrQkFBa0I7UUFDcEMsa0JBQWtCLEVBQUUsNkNBQTZDO0tBQ2xFLENBQUMsQ0FBQztJQUVILHFDQUFxQztJQUNyQyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFO1FBQ2hDLE9BQU8sRUFBRTtZQUNQLHNCQUFzQixFQUFFLGtCQUFrQjtZQUMxQyxXQUFXLEVBQUUsb0NBQW9DLE9BQU8sQ0FBQyxTQUFTLEVBQUU7WUFDcEUsV0FBVyxFQUFFLHdDQUF3QztTQUN0RDtLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFSix3QkFBUyxDQUFDLG1EQUFtRCxFQUFFLHdCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUNsRyxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztJQUV0RCxNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixnQkFBZ0IsRUFBRSxrQkFBa0I7UUFDcEMsa0JBQWtCLEVBQUUsNkNBQTZDO0tBQ2xFLENBQUMsQ0FBQztJQUVILHFDQUFxQztJQUNyQyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFO1FBQ2hDLE9BQU8sRUFBRTtZQUNQLHNCQUFzQixFQUFFLGtCQUFrQjtTQUMzQztLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFSix3QkFBUyxDQUFDLG9GQUFvRixFQUFFLHdCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTs7SUFDbkksTUFBTSxrQkFBa0IsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUM7SUFFdEQsTUFBTSxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDL0IsT0FBTyxFQUFFLElBQUk7UUFDYixnQkFBZ0IsRUFBRSxrQkFBa0I7UUFDcEMsOEJBQThCLEVBQUUsS0FBSztRQUNyQyxJQUFJLEVBQUUsU0FBUztLQUNoQixDQUFDLENBQUM7SUFFSCxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLGdCQUFnQixFQUFFLEVBQUUsU0FBUyxFQUFFLGtCQUFrQixFQUFFLENBQUMsQ0FBQztJQUN2RyxNQUFNLE9BQUMsUUFBUSxDQUFDLE1BQU0sMENBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4QyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRTtLQUM3QixDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRUosd0JBQVMsQ0FBQyw2Q0FBNkMsRUFBRSx3QkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7O0lBQzVGLE1BQU0sbUJBQW1CLEdBQUcsR0FBRyxPQUFPLENBQUMsa0JBQWtCLElBQUksQ0FBQztJQUM5RCxNQUFNLG1CQUFtQixHQUFHLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixJQUFJLENBQUM7SUFFOUQsa0VBQWtFO0lBQ2xFLGdCQUFnQjtJQUNoQixNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixPQUFPLEVBQUUsSUFBSTtRQUNiLGdCQUFnQixFQUFFLG1CQUFtQjtRQUNyQyxJQUFJLEVBQUUsU0FBUztLQUNoQixDQUFDLENBQUM7SUFDSCxNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixPQUFPLEVBQUUsSUFBSTtRQUNiLGdCQUFnQixFQUFFLG1CQUFtQjtLQUN0QyxDQUFDLENBQUM7SUFFSCxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLGdCQUFnQixFQUFFLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFFLENBQUMsQ0FBQztJQUN4RyxNQUFNLE9BQUMsUUFBUSxDQUFDLE1BQU0sMENBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4QyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRTtLQUM3QixDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRUosd0JBQVMsQ0FBQyw2RUFBNkUsRUFBRSx3QkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7SUFDNUgsSUFBSSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDOUMsaUVBQWlFO1FBQ2pFLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxrQkFBa0I7UUFDNUMsWUFBWSxFQUFFLElBQUk7UUFDbEIsVUFBVSxFQUFFO1lBQ1YsYUFBYSxFQUFFLEtBQUs7U0FDckI7S0FDRixDQUFDLENBQUM7SUFFSCxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFFaEQsUUFBUSxJQUFJLElBQUksR0FBRztRQUNqQixlQUFlO1FBQ2Ysa0NBQWtDO0tBQ25DLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRWIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEdBQUcsT0FBTyxDQUFDLFNBQVMsZ0JBQWdCLENBQUMsQ0FBQztJQUN2RixFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUM1RCxNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixnQkFBZ0IsRUFBRSxPQUFPLENBQUMsa0JBQWtCO1FBQzVDLFFBQVEsRUFBRSxRQUFRO1FBQ2xCLGtCQUFrQixFQUFFLDZDQUE2QztLQUNsRSxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRUosd0JBQVMsQ0FBQyx3RUFBd0UsRUFBRSx3QkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7O0lBQ3ZILE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDO0lBRXRELE1BQU0sT0FBTyxDQUFDLGtCQUFrQixDQUFDO1FBQy9CLE9BQU8sRUFBRSxJQUFJO1FBQ2IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLHFCQUFxQixFQUFFLElBQUk7UUFDM0Isa0JBQWtCLEVBQUUsNkNBQTZDO0tBQ2xFLENBQUMsQ0FBQztJQUNILE1BQU0sT0FBTyxDQUFDLGtCQUFrQixDQUFDO1FBQy9CLE9BQU8sRUFBRSxJQUFJO1FBQ2IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLEtBQUssRUFBRSxJQUFJO0tBQ1osQ0FBQyxDQUFDO0lBRUgsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLFNBQVMsRUFBRSxrQkFBa0IsRUFBRSxDQUFDLENBQUM7SUFDdkcsTUFBTSxPQUFDLFFBQVEsQ0FBQyxNQUFNLDBDQUFHLENBQUMsRUFBRSwyQkFBMkIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN6RSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRUosd0JBQVMsQ0FBQyxzQ0FBc0MsRUFBRSx3QkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7O0lBQ3JGLE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDO0lBRXRELE1BQU0sT0FBTyxDQUFDLGtCQUFrQixDQUFDO1FBQy9CLE9BQU8sRUFBRSxJQUFJO1FBQ2IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLElBQUksRUFBRSxTQUFTO1FBQ2Ysa0JBQWtCLEVBQUUsNkNBQTZDO0tBQ2xFLENBQUMsQ0FBQztJQUNILE1BQU0sT0FBTyxDQUFDLGtCQUFrQixDQUFDO1FBQy9CLE9BQU8sRUFBRSxJQUFJO1FBQ2IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLEtBQUssRUFBRSxJQUFJO0tBQ1osQ0FBQyxDQUFDO0lBRUgsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLFNBQVMsRUFBRSxrQkFBa0IsRUFBRSxDQUFDLENBQUM7SUFDdkcsTUFBTSxPQUFDLFFBQVEsQ0FBQyxNQUFNLDBDQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDeEMsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUU7S0FDN0IsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUVKLHdCQUFTLENBQUMsNkVBQTZFLEVBQUUsd0JBQWtCLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO0lBQzVILE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDO0lBRXRELE1BQU0sT0FBTyxDQUFDLGtCQUFrQixDQUFDO1FBQy9CLGdCQUFnQixFQUFFLGtCQUFrQjtRQUNwQyxrQkFBa0IsRUFBRSw2Q0FBNkM7S0FDbEUsQ0FBQyxDQUFDO0lBRUgscUNBQXFDO0lBQ3JDLE1BQU0sT0FBTyxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUU7UUFDaEMsT0FBTyxFQUFFO1lBQ1AsOEZBQThGO1lBQzlGLHlFQUF5RTtZQUN6RSxzQkFBc0IsRUFBRSx3QkFBd0I7WUFDaEQsV0FBVyxFQUFFLG9DQUFvQyxPQUFPLENBQUMsU0FBUyxFQUFFO1lBQ3BFLFdBQVcsRUFBRSx3Q0FBd0M7U0FDdEQ7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IHJhbmRvbVN0cmluZywgd2l0aERlZmF1bHRGaXh0dXJlIH0gZnJvbSAnLi4vaGVscGVycy9jZGsnO1xuaW1wb3J0IHsgaW50ZWdUZXN0IH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LWhlbHBlcnMnO1xuXG5jb25zdCB0aW1lb3V0ID0gcHJvY2Vzcy5lbnYuQ09ERUJVSUxEX0JVSUxEX0lEID8gLy8gaWYgdGhlIHByb2Nlc3MgaXMgcnVubmluZyBpbiBDb2RlQnVpbGRcbiAgM182MDBfMDAwIDogLy8gMSBob3VyXG4gIDYwMF8wMDA7IC8vIDEwIG1pbnV0ZXNcbmplc3Quc2V0VGltZW91dCh0aW1lb3V0KTtcbnByb2Nlc3Muc3Rkb3V0LndyaXRlKGBib290c3RyYXBwaW5nLmludGVndGVzdC50czogU2V0dGluZyBqZXN0IHRpbWUgb3V0IHRvICR7dGltZW91dH0gbXNgKTtcblxuaW50ZWdUZXN0KCdjYW4gYm9vdHN0cmFwIHdpdGhvdXQgZXhlY3V0aW9uJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZSA9IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lO1xuXG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTGVnYWN5KHtcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gICAgbm9FeGVjdXRlOiB0cnVlLFxuICB9KTtcblxuICBjb25zdCByZXNwID0gYXdhaXQgZml4dHVyZS5hd3MuY2xvdWRGb3JtYXRpb24oJ2Rlc2NyaWJlU3RhY2tzJywge1xuICAgIFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICB9KTtcblxuICBleHBlY3QocmVzcC5TdGFja3M/LlswXS5TdGFja1N0YXR1cykudG9FcXVhbCgnUkVWSUVXX0lOX1BST0dSRVNTJyk7XG59KSk7XG5cbmludGVnVGVzdCgndXBncmFkZSBsZWdhY3kgYm9vdHN0cmFwIHN0YWNrIHRvIG5ldyBib290c3RyYXAgc3RhY2sgd2hpbGUgaW4gdXNlJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZSA9IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lO1xuXG4gIGNvbnN0IGxlZ2FjeUJvb3RzdHJhcEJ1Y2tldE5hbWUgPSBgYXdzLWNkay1ib290c3RyYXAtaW50ZWctdGVzdC1sZWdhY3ktYmNrdC0ke3JhbmRvbVN0cmluZygpfWA7XG4gIGNvbnN0IG5ld0Jvb3RzdHJhcEJ1Y2tldE5hbWUgPSBgYXdzLWNkay1ib290c3RyYXAtaW50ZWctdGVzdC12Mi1iY2t0LSR7cmFuZG9tU3RyaW5nKCl9YDtcbiAgZml4dHVyZS5yZW1lbWJlclRvRGVsZXRlQnVja2V0KGxlZ2FjeUJvb3RzdHJhcEJ1Y2tldE5hbWUpOyAvLyBUaGlzIG9uZSB3aWxsIGxlYWtcbiAgZml4dHVyZS5yZW1lbWJlclRvRGVsZXRlQnVja2V0KG5ld0Jvb3RzdHJhcEJ1Y2tldE5hbWUpOyAvLyBUaGlzIG9uZSBzaG91bGRuJ3QgbGVhayBpZiB0aGUgdGVzdCBzdWNjZWVkcywgYnV0IGxldCdzIGJlIHNhZmUgaW4gY2FzZSBpdCBkb2Vzbid0XG5cbiAgLy8gTGVnYWN5IGJvb3RzdHJhcFxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcExlZ2FjeSh7XG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIGJvb3RzdHJhcEJ1Y2tldE5hbWU6IGxlZ2FjeUJvb3RzdHJhcEJ1Y2tldE5hbWUsXG4gIH0pO1xuXG4gIC8vIERlcGxveSBzdGFjayB0aGF0IHVzZXMgZmlsZSBhc3NldHNcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2xhbWJkYScsIHtcbiAgICBvcHRpb25zOiBbJy0tdG9vbGtpdC1zdGFjay1uYW1lJywgYm9vdHN0cmFwU3RhY2tOYW1lXSxcbiAgfSk7XG5cbiAgLy8gVXBncmFkZSBib290c3RyYXAgc3RhY2sgdG8gXCJuZXdcIiBzdHlsZVxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcE1vZGVybih7XG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIGJvb3RzdHJhcEJ1Y2tldE5hbWU6IG5ld0Jvb3RzdHJhcEJ1Y2tldE5hbWUsXG4gICAgY2ZuRXhlY3V0aW9uUG9saWN5OiAnYXJuOmF3czppYW06OmF3czpwb2xpY3kvQWRtaW5pc3RyYXRvckFjY2VzcycsXG4gIH0pO1xuXG4gIC8vIChGb3JjZSkgZGVwbG95IHN0YWNrIGFnYWluXG4gIC8vIC0tZm9yY2UgdG8gYnlwYXNzIHRoZSBjaGVjayB3aGljaCBzYXlzIHRoYXQgdGhlIHRlbXBsYXRlIGhhc24ndCBjaGFuZ2VkLlxuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnbGFtYmRhJywge1xuICAgIG9wdGlvbnM6IFtcbiAgICAgICctLXRvb2xraXQtc3RhY2stbmFtZScsIGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICAgICctLWZvcmNlJyxcbiAgICBdLFxuICB9KTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjYW4gYW5kIGRlcGxveSBpZiBvbWl0dGluZyBleGVjdXRpb24gcG9saWNpZXMnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHRvb2xraXRTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgfSk7XG5cbiAgLy8gRGVwbG95IHN0YWNrIHRoYXQgdXNlcyBmaWxlIGFzc2V0c1xuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnbGFtYmRhJywge1xuICAgIG9wdGlvbnM6IFtcbiAgICAgICctLXRvb2xraXQtc3RhY2stbmFtZScsIGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICAgICctLWNvbnRleHQnLCBgQGF3cy1jZGsvY29yZTpib290c3RyYXBRdWFsaWZpZXI9JHtmaXh0dXJlLnF1YWxpZmllcn1gLFxuICAgICAgJy0tY29udGV4dCcsICdAYXdzLWNkay9jb3JlOm5ld1N0eWxlU3RhY2tTeW50aGVzaXM9MScsXG4gICAgXSxcbiAgfSk7XG59KSk7XG5cbmludGVnVGVzdCgnZGVwbG95IG5ldyBzdHlsZSBzeW50aGVzaXMgdG8gbmV3IHN0eWxlIGJvb3RzdHJhcCcsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBib290c3RyYXBTdGFja05hbWUgPSBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZTtcblxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcE1vZGVybih7XG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIGNmbkV4ZWN1dGlvblBvbGljeTogJ2Fybjphd3M6aWFtOjphd3M6cG9saWN5L0FkbWluaXN0cmF0b3JBY2Nlc3MnLFxuICB9KTtcblxuICAvLyBEZXBsb3kgc3RhY2sgdGhhdCB1c2VzIGZpbGUgYXNzZXRzXG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdsYW1iZGEnLCB7XG4gICAgb3B0aW9uczogW1xuICAgICAgJy0tdG9vbGtpdC1zdGFjay1uYW1lJywgYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgICAgJy0tY29udGV4dCcsIGBAYXdzLWNkay9jb3JlOmJvb3RzdHJhcFF1YWxpZmllcj0ke2ZpeHR1cmUucXVhbGlmaWVyfWAsXG4gICAgICAnLS1jb250ZXh0JywgJ0Bhd3MtY2RrL2NvcmU6bmV3U3R5bGVTdGFja1N5bnRoZXNpcz0xJyxcbiAgICBdLFxuICB9KTtcbn0pKTtcblxuaW50ZWdUZXN0KCdkZXBsb3kgbmV3IHN0eWxlIHN5bnRoZXNpcyB0byBuZXcgc3R5bGUgYm9vdHN0cmFwICh3aXRoIGRvY2tlciBpbWFnZSknLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHRvb2xraXRTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICBjZm5FeGVjdXRpb25Qb2xpY3k6ICdhcm46YXdzOmlhbTo6YXdzOnBvbGljeS9BZG1pbmlzdHJhdG9yQWNjZXNzJyxcbiAgfSk7XG5cbiAgLy8gRGVwbG95IHN0YWNrIHRoYXQgdXNlcyBmaWxlIGFzc2V0c1xuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnZG9ja2VyJywge1xuICAgIG9wdGlvbnM6IFtcbiAgICAgICctLXRvb2xraXQtc3RhY2stbmFtZScsIGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICAgICctLWNvbnRleHQnLCBgQGF3cy1jZGsvY29yZTpib290c3RyYXBRdWFsaWZpZXI9JHtmaXh0dXJlLnF1YWxpZmllcn1gLFxuICAgICAgJy0tY29udGV4dCcsICdAYXdzLWNkay9jb3JlOm5ld1N0eWxlU3RhY2tTeW50aGVzaXM9MScsXG4gICAgXSxcbiAgfSk7XG59KSk7XG5cbmludGVnVGVzdCgnZGVwbG95IG9sZCBzdHlsZSBzeW50aGVzaXMgdG8gbmV3IHN0eWxlIGJvb3RzdHJhcCcsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBib290c3RyYXBTdGFja05hbWUgPSBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZTtcblxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcE1vZGVybih7XG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIGNmbkV4ZWN1dGlvblBvbGljeTogJ2Fybjphd3M6aWFtOjphd3M6cG9saWN5L0FkbWluaXN0cmF0b3JBY2Nlc3MnLFxuICB9KTtcblxuICAvLyBEZXBsb3kgc3RhY2sgdGhhdCB1c2VzIGZpbGUgYXNzZXRzXG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdsYW1iZGEnLCB7XG4gICAgb3B0aW9uczogW1xuICAgICAgJy0tdG9vbGtpdC1zdGFjay1uYW1lJywgYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIF0sXG4gIH0pO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2NhbiBjcmVhdGUgYSBsZWdhY3kgYm9vdHN0cmFwIHN0YWNrIHdpdGggLS1wdWJsaWMtYWNjZXNzLWJsb2NrLWNvbmZpZ3VyYXRpb249ZmFsc2UnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBMZWdhY3koe1xuICAgIHZlcmJvc2U6IHRydWUsXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIHB1YmxpY0FjY2Vzc0Jsb2NrQ29uZmlndXJhdGlvbjogZmFsc2UsXG4gICAgdGFnczogJ0Zvbz1CYXInLFxuICB9KTtcblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmNsb3VkRm9ybWF0aW9uKCdkZXNjcmliZVN0YWNrcycsIHsgU3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUgfSk7XG4gIGV4cGVjdChyZXNwb25zZS5TdGFja3M/LlswXS5UYWdzKS50b0VxdWFsKFtcbiAgICB7IEtleTogJ0ZvbycsIFZhbHVlOiAnQmFyJyB9LFxuICBdKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjYW4gY3JlYXRlIG11bHRpcGxlIGxlZ2FjeSBib290c3RyYXAgc3RhY2tzJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZTEgPSBgJHtmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZX0tMWA7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZTIgPSBgJHtmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZX0tMmA7XG5cbiAgLy8gZGVwbG95IHR3byB0b29sa2l0IHN0YWNrcyBpbnRvIHRoZSBzYW1lIGVudmlyb25tZW50IChzZWUgIzE0MTYpXG4gIC8vIG9uZSB3aXRoIHRhZ3NcbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBMZWdhY3koe1xuICAgIHZlcmJvc2U6IHRydWUsXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lMSxcbiAgICB0YWdzOiAnRm9vPUJhcicsXG4gIH0pO1xuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcExlZ2FjeSh7XG4gICAgdmVyYm9zZTogdHJ1ZSxcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUyLFxuICB9KTtcblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmNsb3VkRm9ybWF0aW9uKCdkZXNjcmliZVN0YWNrcycsIHsgU3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUxIH0pO1xuICBleHBlY3QocmVzcG9uc2UuU3RhY2tzPy5bMF0uVGFncykudG9FcXVhbChbXG4gICAgeyBLZXk6ICdGb28nLCBWYWx1ZTogJ0JhcicgfSxcbiAgXSk7XG59KSk7XG5cbmludGVnVGVzdCgnY2FuIGR1bXAgdGhlIHRlbXBsYXRlLCBtb2RpZnkgYW5kIHVzZSBpdCB0byBkZXBsb3kgYSBjdXN0b20gYm9vdHN0cmFwIHN0YWNrJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGxldCB0ZW1wbGF0ZSA9IGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICAvLyB0b29sa2l0U3RhY2tOYW1lIGRvZXNuJ3QgbWF0dGVyIGZvciB0aGlzIHBhcnRpY3VsYXIgaW52b2NhdGlvblxuICAgIHRvb2xraXRTdGFja05hbWU6IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIHNob3dUZW1wbGF0ZTogdHJ1ZSxcbiAgICBjbGlPcHRpb25zOiB7XG4gICAgICBjYXB0dXJlU3RkZXJyOiBmYWxzZSxcbiAgICB9LFxuICB9KTtcblxuICBleHBlY3QodGVtcGxhdGUpLnRvQ29udGFpbignQm9vdHN0cmFwVmVyc2lvbjonKTtcblxuICB0ZW1wbGF0ZSArPSAnXFxuJyArIFtcbiAgICAnICBUd2lkZGxlRGVlOicsXG4gICAgJyAgICBWYWx1ZTogVGVtcGxhdGUgZ290IHR3aWRkbGVkJyxcbiAgXS5qb2luKCdcXG4nKTtcblxuICBjb25zdCBmaWxlbmFtZSA9IHBhdGguam9pbihmaXh0dXJlLmludGVnVGVzdERpciwgYCR7Zml4dHVyZS5xdWFsaWZpZXJ9LXRlbXBsYXRlLnlhbWxgKTtcbiAgZnMud3JpdGVGaWxlU3luYyhmaWxlbmFtZSwgdGVtcGxhdGUsIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSk7XG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICB0ZW1wbGF0ZTogZmlsZW5hbWUsXG4gICAgY2ZuRXhlY3V0aW9uUG9saWN5OiAnYXJuOmF3czppYW06OmF3czpwb2xpY3kvQWRtaW5pc3RyYXRvckFjY2VzcycsXG4gIH0pO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ3N3aXRjaCBvbiB0ZXJtaW5hdGlvbiBwcm90ZWN0aW9uLCBzd2l0Y2ggaXMgbGVmdCBhbG9uZSBvbiByZS1ib290c3RyYXAnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHZlcmJvc2U6IHRydWUsXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIHRlcm1pbmF0aW9uUHJvdGVjdGlvbjogdHJ1ZSxcbiAgICBjZm5FeGVjdXRpb25Qb2xpY3k6ICdhcm46YXdzOmlhbTo6YXdzOnBvbGljeS9BZG1pbmlzdHJhdG9yQWNjZXNzJyxcbiAgfSk7XG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICB2ZXJib3NlOiB0cnVlLFxuICAgIHRvb2xraXRTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICBmb3JjZTogdHJ1ZSxcbiAgfSk7XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmaXh0dXJlLmF3cy5jbG91ZEZvcm1hdGlvbignZGVzY3JpYmVTdGFja3MnLCB7IFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lIH0pO1xuICBleHBlY3QocmVzcG9uc2UuU3RhY2tzPy5bMF0uRW5hYmxlVGVybWluYXRpb25Qcm90ZWN0aW9uKS50b0VxdWFsKHRydWUpO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2FkZCB0YWdzLCBsZWZ0IGFsb25lIG9uIHJlLWJvb3RzdHJhcCcsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBib290c3RyYXBTdGFja05hbWUgPSBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZTtcblxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcE1vZGVybih7XG4gICAgdmVyYm9zZTogdHJ1ZSxcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gICAgdGFnczogJ0Zvbz1CYXInLFxuICAgIGNmbkV4ZWN1dGlvblBvbGljeTogJ2Fybjphd3M6aWFtOjphd3M6cG9saWN5L0FkbWluaXN0cmF0b3JBY2Nlc3MnLFxuICB9KTtcbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHZlcmJvc2U6IHRydWUsXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIGZvcmNlOiB0cnVlLFxuICB9KTtcblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmNsb3VkRm9ybWF0aW9uKCdkZXNjcmliZVN0YWNrcycsIHsgU3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUgfSk7XG4gIGV4cGVjdChyZXNwb25zZS5TdGFja3M/LlswXS5UYWdzKS50b0VxdWFsKFtcbiAgICB7IEtleTogJ0ZvbycsIFZhbHVlOiAnQmFyJyB9LFxuICBdKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjYW4gZGVwbG95IG1vZGVybi1zeW50aGVzaXplZCBzdGFjayBldmVuIGlmIGJvb3RzdHJhcCBzdGFjayBuYW1lIGlzIHVua25vd24nLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHRvb2xraXRTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICBjZm5FeGVjdXRpb25Qb2xpY3k6ICdhcm46YXdzOmlhbTo6YXdzOnBvbGljeS9BZG1pbmlzdHJhdG9yQWNjZXNzJyxcbiAgfSk7XG5cbiAgLy8gRGVwbG95IHN0YWNrIHRoYXQgdXNlcyBmaWxlIGFzc2V0c1xuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnbGFtYmRhJywge1xuICAgIG9wdGlvbnM6IFtcbiAgICAgIC8vIEV4cGxpY2l0eSBwYXNzIGEgbmFtZSB0aGF0J3Mgc3VyZSB0byBub3QgZXhpc3QsIG90aGVyd2lzZSB0aGUgQ0xJIG1pZ2h0IGFjY2lkZW50YWxseSBmaW5kIGFcbiAgICAgIC8vIGRlZmF1bHQgYm9vdHN0cmFjcCBzdGFjayBpZiB0aGF0IGhhcHBlbnMgdG8gYmUgaW4gdGhlIGFjY291bnQgYWxyZWFkeS5cbiAgICAgICctLXRvb2xraXQtc3RhY2stbmFtZScsICdEZWZpbml0ZWx5RG9lc05vdEV4aXN0JyxcbiAgICAgICctLWNvbnRleHQnLCBgQGF3cy1jZGsvY29yZTpib290c3RyYXBRdWFsaWZpZXI9JHtmaXh0dXJlLnF1YWxpZmllcn1gLFxuICAgICAgJy0tY29udGV4dCcsICdAYXdzLWNkay9jb3JlOm5ld1N0eWxlU3RhY2tTeW50aGVzaXM9MScsXG4gICAgXSxcbiAgfSk7XG59KSk7XG4iXX0= \ No newline at end of file From 4ae78b07af20ea3ef049079ac5b892f9ee8476e5 Mon Sep 17 00:00:00 2001 From: nom3ad <19239479+nom3ad@users.noreply.github.com> Date: Fri, 5 Nov 2021 22:55:16 +0530 Subject: [PATCH 146/148] fix(cognito): ambiguous error message when same trigger is added twice (#16917) when the same trigger is added twice to the Cognito userpool, ```ts const fn = lambda.Function.fromFunctionArn(stack, 'Trigger', 'arn:aws:lambda:us-east-1:123456789012:function:CognitoFunction') const userpool = new cognito.UserPool(stack, 'Userpool', { lambdaTriggers: { customMessage: fn } }) userpool.addTrigger(cognito.UserPoolOperation.CUSTOM_MESSAGE, fn) ``` throws error message: `Error: A trigger for the operation [object Object] already exists.` This PR fixes it as: ` Error: A trigger for the operation customMessage already exists.` ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-cognito/lib/user-pool.ts | 2 +- packages/@aws-cdk/aws-cognito/test/user-pool.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-cognito/lib/user-pool.ts b/packages/@aws-cdk/aws-cognito/lib/user-pool.ts index 6277ee0f467ee..adc3f51bf37a2 100644 --- a/packages/@aws-cdk/aws-cognito/lib/user-pool.ts +++ b/packages/@aws-cdk/aws-cognito/lib/user-pool.ts @@ -830,7 +830,7 @@ export class UserPool extends UserPoolBase { */ public addTrigger(operation: UserPoolOperation, fn: lambda.IFunction): void { if (operation.operationName in this.triggers) { - throw new Error(`A trigger for the operation ${operation} already exists.`); + throw new Error(`A trigger for the operation ${operation.operationName} already exists.`); } this.addLambdaPermission(fn, operation.operationName); diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts index 7b132803da2d6..5aa6c48ee99fc 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts @@ -403,7 +403,7 @@ describe('User Pool', () => { // WHEN userpool.addTrigger(UserPoolOperation.CREATE_AUTH_CHALLENGE, fn1); - expect(() => userpool.addTrigger(UserPoolOperation.CREATE_AUTH_CHALLENGE, fn2)).toThrow(/already exists/); + expect(() => userpool.addTrigger(UserPoolOperation.CREATE_AUTH_CHALLENGE, fn2)).toThrow(/createAuthChallenge already exists/); }); test('no username aliases specified', () => { From 8c7eab5ca99de85bdff5b861bf596e4811ef92d2 Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Fri, 5 Nov 2021 12:21:45 -0600 Subject: [PATCH 147/148] chore(lambda-nodejs): improve spawnSync error message (#16986) This PR improves the error message when a lambda-nodejs function fails to bundle. I'm working on moving a client's repository from a "makeshift monorepo" to a real `yarn`/`lerna` driven monorepo. They make heavy use of `NodejsFunction`, so I'm moving them to the newer [reference project architecture](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-lambda-nodejs-readme.html#reference-project-architecture) with a single lockfile at the root of the repository. While working through this issue, I kept running into this error message: ``` > yarn cdk diff Bundling asset SomeLambdaHandler/SomeSubLambda/Lambda/Code/Stage... Usage Error: Couldn't find a script named "esbuild". $ yarn run [--inspect] [--inspect-brk] ... Failed to bundle asset SomeLambdaHandler/SomeSubLambda/Lambda/Code/Stage, bundle output is located at /Users/blimmer/code/client/project/packages/some-workspace/cdk.out/bundling-temp-2f3ffba54d828547eb851ebe672a601943e153ec31fdc5e45f8e80ed976da6d3-error: Error: bash exited with status 1 Subprocess exited with error 1 ``` This was confusing to me because I have `esbuild` installed in both sub-packages that require it. The error message just tells me that `bash` failed to run, which isn't very helpful. However, when I set an interactive breakpoint, I got a lot more information about the failure. By digging into these arguments https://github.com/aws/aws-cdk/blob/507769aa034ba3d8daa497953be629408072baed/packages/%40aws-cdk/aws-lambda-nodejs/lib/util.ts#L56-L57 I can actually see what's being run and which directory it's run in. | argument | contents | comments | | -------- | -------- | -------- | | `cmd` | `bash` | this doesn't really tell me anything about what's happening | | `args` | [ `-c`, `"yarn run esbuild --bundle \"/Users/blimmer/code/client/project/packages/some-workspace/lib/some-sub-lambda/lambda/index.ts\" --target=node14 --platform=node --outfile=\"/Users/blimmer/code/client/project/packages/some-workspace/cdk.out/bundling-temp-2f3ffba54d828547eb851ebe672a601943e153ec31fdc5e45f8e80ed976da6d3/index.js\" --external:aws-sdk"` ] | the second argument of this array actually represents the command being run - this is way more useful than just `bash` | | `options` | `{ ...lotsOfOtherStuff, cwd: '/Users/blimmer/code/client/project' }` | `cwd` was actually crucial for me to fix this problem. because I see this is running in the root of the monorepo, it shows that I need to install `esbuild` there, instead of in the workspaces. | ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts index 5ead91793e93b..af24d3b4ae371 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts @@ -64,7 +64,7 @@ export function exec(cmd: string, args: string[], options?: SpawnSyncOptions) { if (proc.stdout || proc.stderr) { throw new Error(`[Status ${proc.status}] stdout: ${proc.stdout?.toString().trim()}\n\n\nstderr: ${proc.stderr?.toString().trim()}`); } - throw new Error(`${cmd} exited with status ${proc.status}`); + throw new Error(`${cmd} ${args.join(' ')} ${options?.cwd ? `run in directory ${options.cwd}` : ''} exited with status ${proc.status}`); } return proc; From 37f8a9f0620b41a3ce9e6e1ca42611ad35ad586a Mon Sep 17 00:00:00 2001 From: Madeline Kusters <80541297+madeline-k@users.noreply.github.com> Date: Fri, 5 Nov 2021 12:16:30 -0700 Subject: [PATCH 148/148] docs(ecs): update docs to accurately reflect that a new security group is created if one is not provided. (#17364) Closes #15365 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/fargate/application-load-balanced-fargate-service.ts | 2 +- .../lib/fargate/queue-processing-fargate-service.ts | 2 +- packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts | 4 ++-- packages/@aws-cdk/aws-ecs/lib/external/external-service.ts | 2 +- packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-load-balanced-fargate-service.ts b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-load-balanced-fargate-service.ts index 19a2501355223..81f243f4a6fa6 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-load-balanced-fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-load-balanced-fargate-service.ts @@ -86,7 +86,7 @@ export interface ApplicationLoadBalancedFargateServiceProps extends ApplicationL readonly platformVersion?: FargatePlatformVersion; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * @default - A new security group is created. */ diff --git a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/queue-processing-fargate-service.ts b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/queue-processing-fargate-service.ts index e6f8b89c736b3..033d19dc39612 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/queue-processing-fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/queue-processing-fargate-service.ts @@ -77,7 +77,7 @@ export interface QueueProcessingFargateServiceProps extends QueueProcessingServi readonly taskSubnets?: ec2.SubnetSelection; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * @default - A new security group is created. */ diff --git a/packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts b/packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts index df2ad7819543c..0a98809dff403 100644 --- a/packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts +++ b/packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts @@ -39,7 +39,7 @@ export interface Ec2ServiceProps extends BaseServiceOptions { readonly vpcSubnets?: ec2.SubnetSelection; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * This property is only used for tasks that use the awsvpc network mode. * @@ -49,7 +49,7 @@ export interface Ec2ServiceProps extends BaseServiceOptions { readonly securityGroup?: ec2.ISecurityGroup; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * This property is only used for tasks that use the awsvpc network mode. * diff --git a/packages/@aws-cdk/aws-ecs/lib/external/external-service.ts b/packages/@aws-cdk/aws-ecs/lib/external/external-service.ts index 741ba0a7b2b29..2c1c6c9f59534 100644 --- a/packages/@aws-cdk/aws-ecs/lib/external/external-service.ts +++ b/packages/@aws-cdk/aws-ecs/lib/external/external-service.ts @@ -21,7 +21,7 @@ export interface ExternalServiceProps extends BaseServiceOptions { readonly taskDefinition: TaskDefinition; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * * @default - A new security group is created. diff --git a/packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts b/packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts index 7979b98f0b0fa..a996aca37cc23 100644 --- a/packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts @@ -34,7 +34,7 @@ export interface FargateServiceProps extends BaseServiceOptions { readonly vpcSubnets?: ec2.SubnetSelection; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * @default - A new security group is created. * @deprecated use securityGroups instead. @@ -42,7 +42,7 @@ export interface FargateServiceProps extends BaseServiceOptions { readonly securityGroup?: ec2.ISecurityGroup; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * @default - A new security group is created. */