From b75980ddba6b5055f5685153f313a8eb3f5c2957 Mon Sep 17 00:00:00 2001 From: AWS CDK Team Date: Fri, 6 Dec 2024 13:07:25 +0000 Subject: [PATCH 1/7] chore(release): 2.172.0 --- CHANGELOG.v2.alpha.md | 19 ++++++++++ CHANGELOG.v2.md | 38 ++++++++++++++++++++ packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md | 25 +++++++++++-- packages/aws-cdk-lib/cx-api/lib/features.ts | 4 +-- version.v2.json | 4 +-- 5 files changed, 83 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.v2.alpha.md b/CHANGELOG.v2.alpha.md index 9682da4675bda..bd8f4face7249 100644 --- a/CHANGELOG.v2.alpha.md +++ b/CHANGELOG.v2.alpha.md @@ -2,6 +2,25 @@ 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. +## [2.172.0-alpha.0](https://github.com/aws/aws-cdk/compare/v2.171.1-alpha.0...v2.172.0-alpha.0) (2024-12-06) + + +### Features + +* **ec2:** default BastionHostLinux to use Amazon Linux 2023 (under feature flag) ([#31996](https://github.com/aws/aws-cdk/issues/31996)) ([bf77e51](https://github.com/aws/aws-cdk/commit/bf77e51c90e3da972c464430d579695163160a13)), closes [#29493](https://github.com/aws/aws-cdk/issues/29493) [#29493](https://github.com/aws/aws-cdk/issues/29493) +* **ec2:** instance support passing IAM instance profile ([#32073](https://github.com/aws/aws-cdk/issues/32073)) ([cf89d0f](https://github.com/aws/aws-cdk/commit/cf89d0f67f6d03bdeec38a4ffb48d3cda59db7cc)), closes [#8348](https://github.com/aws/aws-cdk/issues/8348) +* **eks-v2-alpha:** create the alpha package for the EKS L2 rewrite and setup test ([#32366](https://github.com/aws/aws-cdk/issues/32366)) ([b30c823](https://github.com/aws/aws-cdk/commit/b30c8234def40509899c7e7a7bd796d93470445d)) +* **eks-v2-alpha:** use native L1 instead of custom resource for Fargate Profile ([#32386](https://github.com/aws/aws-cdk/issues/32386)) ([8189c82](https://github.com/aws/aws-cdk/commit/8189c828be3eadeb82cbb4d7a9591f8327a2d18d)) +* **neptune:** auto minor version upgrade for an instance ([#31988](https://github.com/aws/aws-cdk/issues/31988)) ([d95db49](https://github.com/aws/aws-cdk/commit/d95db491f7c1fd11dd42299f99d40fd94b0d642f)) +* **pipes:** add LogDestination implementation ([#31672](https://github.com/aws/aws-cdk/issues/31672)) ([af5345e](https://github.com/aws/aws-cdk/commit/af5345e9ed2528bde2af6cd4b2428654b096eb93)), closes [#31671](https://github.com/aws/aws-cdk/issues/31671) +* **pipes-targets:** add API Gateway ([#31954](https://github.com/aws/aws-cdk/issues/31954)) ([c77536f](https://github.com/aws/aws-cdk/commit/c77536f8999e221c8d6dae5742f484a04b05bac5)) +* **redshift:** execute resource action ([#31995](https://github.com/aws/aws-cdk/issues/31995)) ([40835a0](https://github.com/aws/aws-cdk/commit/40835a01536509daefa44e5e4cad5d8829d8dd1c)) + + +### Bug Fixes + +* **scheduler-targets-alpha:** incorrect validation of maximumEventAge ([#32284](https://github.com/aws/aws-cdk/issues/32284)) ([2eebc59](https://github.com/aws/aws-cdk/commit/2eebc5913966f0266efbad65c3f137c07c75270b)) + ## [2.171.1-alpha.0](https://github.com/aws/aws-cdk/compare/v2.171.0-alpha.0...v2.171.1-alpha.0) (2024-11-27) ## [2.171.0-alpha.0](https://github.com/aws/aws-cdk/compare/v2.170.0-alpha.0...v2.171.0-alpha.0) (2024-11-25) diff --git a/CHANGELOG.v2.md b/CHANGELOG.v2.md index 42cf512a04cd9..71b5f4db75fa5 100644 --- a/CHANGELOG.v2.md +++ b/CHANGELOG.v2.md @@ -2,6 +2,44 @@ 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. +## [2.172.0](https://github.com/aws/aws-cdk/compare/v2.171.1...v2.172.0) (2024-12-06) + + +### ⚠ BREAKING CHANGES TO EXPERIMENTAL FEATURES + +* **apigateway:** We will be removing deprecated `APIGatewayV2` constructs from `aws-apigateway` module. + +*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* + +### Features + +* **aspects:** priority-ordered aspect invocation ([#32097](https://github.com/aws/aws-cdk/issues/32097)) ([8ccdff4](https://github.com/aws/aws-cdk/commit/8ccdff4ee083d66f73259223ba75ba0b8a0752a0)), closes [#21341](https://github.com/aws/aws-cdk/issues/21341) [/github.com/aws/aws-cdk/blob/8b495f9ec157c0b00674715f62b1bbcabf2096ac/packages/aws-cdk-lib/core/lib/private/synthesis.ts#L217](https://github.com/aws//github.com/aws/aws-cdk/blob/8b495f9ec157c0b00674715f62b1bbcabf2096ac/packages/aws-cdk-lib/core/lib/private/synthesis.ts/issues/L217) +* **cognito:** new `cloudFrontEndpoint` method for user pool domain without custom resource ([#31402](https://github.com/aws/aws-cdk/issues/31402)) ([deeb2ad](https://github.com/aws/aws-cdk/commit/deeb2ad0bc38101a9f1fa8162ad5d6008900a98d)), closes [#31342](https://github.com/aws/aws-cdk/issues/31342) [/github.com/go-to-k/aws-cdk/blob/fcbdc769e681f1f915cdc8cd7aa3a565d807884d/packages/aws-cdk-lib/aws-route53-targets/lib/userpool-domain.ts#L14](https://github.com/aws//github.com/go-to-k/aws-cdk/blob/fcbdc769e681f1f915cdc8cd7aa3a565d807884d/packages/aws-cdk-lib/aws-route53-targets/lib/userpool-domain.ts/issues/L14) +* **cognito:** support for ALLOW_USER_AUTH explicit auth flow ([#32273](https://github.com/aws/aws-cdk/issues/32273)) ([c5bcfdc](https://github.com/aws/aws-cdk/commit/c5bcfdc57aa763539b31f4e7f6f115f707c401a4)) +* **elasticloadbalancingv2:** ip address type for both network and application target group ([#32189](https://github.com/aws/aws-cdk/issues/32189)) ([7cc5f30](https://github.com/aws/aws-cdk/commit/7cc5f305c839048454240f8d6db1614e2dfa4c53)) +* **events:** add filter rules for prefixEqualsIgnoreCase, suffixEqualsIgnoreCase, wildcard, and anythingBut* matches ([#32063](https://github.com/aws/aws-cdk/issues/32063)) ([0ce71fc](https://github.com/aws/aws-cdk/commit/0ce71fc50cffffc04d9d1bc9c98c9c04e77bfe1f)), closes [#28462](https://github.com/aws/aws-cdk/issues/28462) +* **lambda-nodejs:** add bun support ([#31770](https://github.com/aws/aws-cdk/issues/31770)) ([aed8ad1](https://github.com/aws/aws-cdk/commit/aed8ad10c3d86497be34b2889466f770910d36ef)), closes [#31753](https://github.com/aws/aws-cdk/issues/31753) [#31753](https://github.com/aws/aws-cdk/issues/31753) +* **rds:** limitless database cluster ([#32151](https://github.com/aws/aws-cdk/issues/32151)) ([f4c19c7](https://github.com/aws/aws-cdk/commit/f4c19c71ca8a34188f1d26f756ef5b3ec218b5c2)) +* **ses:** add support to disable account-level suppression list ([#32168](https://github.com/aws/aws-cdk/issues/32168)) ([bb50c1a](https://github.com/aws/aws-cdk/commit/bb50c1abc8c507e2b877a952377adc607b936eab)), closes [#32149](https://github.com/aws/aws-cdk/issues/32149) +* update L1 CloudFormation resource definitions ([#32272](https://github.com/aws/aws-cdk/issues/32272)) ([421d327](https://github.com/aws/aws-cdk/commit/421d32708f5018353b2c5db1751cb3415412b985)) +* update L1 CloudFormation resource definitions ([#32356](https://github.com/aws/aws-cdk/issues/32356)) ([9e6bb24](https://github.com/aws/aws-cdk/commit/9e6bb24f533c11bbb74a30a729566f91f5d6a13f)) +* **route53-targets:** add `AppSync` route53 target ([#31976](https://github.com/aws/aws-cdk/issues/31976)) ([dc7574a](https://github.com/aws/aws-cdk/commit/dc7574a3c048fdb58ca1ac996dbe46fd54b59993)), closes [#26109](https://github.com/aws/aws-cdk/issues/26109) + + +### Bug Fixes + +* **apigateway:** remove deprecated apigatewayv2 from aws-apigateway module ([#32297](https://github.com/aws/aws-cdk/issues/32297)) ([4db9565](https://github.com/aws/aws-cdk/commit/4db956597b41bb9d7dd8e1d65b39643772065353)) +* **appsync:** `appsync.HttpDataSourceProps` erroneously extends `BaseDataSourceProps` ([#32065](https://github.com/aws/aws-cdk/issues/32065)) ([4e7f5c4](https://github.com/aws/aws-cdk/commit/4e7f5c4469509ed4e1d586a9c5263f19b540a7bd)), closes [#29689](https://github.com/aws/aws-cdk/issues/29689) +* **cli:** assume role calls are skipping the proxy ([#32291](https://github.com/aws/aws-cdk/issues/32291)) ([6c0f74e](https://github.com/aws/aws-cdk/commit/6c0f74e4b37b8ef81c927adca1112680d0bf2ad0)) +* **cli:** lambda hotswap fails if `lambda:GetFunctionConfiguration` action is not allowed ([#32301](https://github.com/aws/aws-cdk/issues/32301)) ([be000a2](https://github.com/aws/aws-cdk/commit/be000a251b781b0b0870930992793df5a2fc4b01)), closes [/github.com/aws/aws-sdk-js-v3/blob/main/clients/client-lambda/src/waiters/waitForFunctionUpdatedV2.ts#L10](https://github.com/aws//github.com/aws/aws-sdk-js-v3/blob/main/clients/client-lambda/src/waiters/waitForFunctionUpdatedV2.ts/issues/L10) [/github.com/aws/aws-sdk-js-v3/blob/main/clients/client-lambda/src/waiters/waitForFunctionUpdated.ts#L13](https://github.com/aws//github.com/aws/aws-sdk-js-v3/blob/main/clients/client-lambda/src/waiters/waitForFunctionUpdated.ts/issues/L13) +* **cli:** mfa code is not requested when `$AWS_PROFILE` is used ([#32313](https://github.com/aws/aws-cdk/issues/32313)) ([6458439](https://github.com/aws/aws-cdk/commit/6458439b08f9ce1f49c1137dd85bb582550a5f52)), closes [#32312](https://github.com/aws/aws-cdk/issues/32312) +* **cli:** remove source maps ([#32317](https://github.com/aws/aws-cdk/issues/32317)) ([512cf95](https://github.com/aws/aws-cdk/commit/512cf952f3971cd302fb1cca7c24149b43832280)), closes [#19930](https://github.com/aws/aws-cdk/issues/19930) [#19930](https://github.com/aws/aws-cdk/issues/19930) +* **cli:** short-lived credentials are not refreshed ([#32354](https://github.com/aws/aws-cdk/issues/32354)) ([058a0bf](https://github.com/aws/aws-cdk/commit/058a0bfc22036230252fcbc026576260723f6d28)) +* **cli:** warns about missing `--no-rollback` flag that is present ([#32309](https://github.com/aws/aws-cdk/issues/32309)) ([559d676](https://github.com/aws/aws-cdk/commit/559d676e2989739b38491b1f767face839d39f69)), closes [#32295](https://github.com/aws/aws-cdk/issues/32295) +* **cloudformation-include:** drops unknown policy attributes ([#32321](https://github.com/aws/aws-cdk/issues/32321)) ([20edc7f](https://github.com/aws/aws-cdk/commit/20edc7fe5e891461a8188d306dcc0f776041cf8f)) +* **cloudfront:** propagate `originAccessControlId` CloudFront Origin property to CloudFormation templates ([#32020](https://github.com/aws/aws-cdk/issues/32020)) ([f9708a6](https://github.com/aws/aws-cdk/commit/f9708a634ceaef7f62e8193443ea30fe9e2fbad6)), closes [#32018](https://github.com/aws/aws-cdk/issues/32018) +* **iam:** `Role.addManagedPolicy()` does not work for imported roles `IRole` [#8307](https://github.com/aws/aws-cdk/issues/8307) ([#31212](https://github.com/aws/aws-cdk/issues/31212)) ([c78ef1b](https://github.com/aws/aws-cdk/commit/c78ef1b43a18e1ffc93fcbdee9dd2e91fa750a36)), closes [/github.com/aws/aws-cdk/blob/823ff6e03899f790a4cb1c43f92a02cc906ac356/packages/aws-cdk-lib/aws-iam/lib/identity-base.ts#L17-L21](https://github.com/aws//github.com/aws/aws-cdk/blob/823ff6e03899f790a4cb1c43f92a02cc906ac356/packages/aws-cdk-lib/aws-iam/lib/identity-base.ts/issues/L17-L21) + ## [2.171.1](https://github.com/aws/aws-cdk/compare/v2.171.0...v2.171.1) (2024-11-27) diff --git a/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md b/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md index 005491dbe78b6..ed9e96757c561 100644 --- a/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +++ b/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md @@ -81,7 +81,8 @@ Flags come in three types: | [@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics](#aws-cdkcorecfnincluderejectcomplexresourceupdatecreatepolicyintrinsics) | When enabled, CFN templates added with `cfn-include` will error if the template contains Resource Update or Create policies with CFN Intrinsics that include non-primitive values. | 2.161.0 | (fix) | | [@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy](#aws-cdkaws-stepfunctions-tasksfixrunecstaskpolicy) | When enabled, the resource of IAM Run Ecs policy generated by SFN EcsRunTask will reference the definition, instead of constructing ARN. | 2.163.0 | (fix) | | [@aws-cdk/aws-dynamodb:resourcePolicyPerReplica](#aws-cdkaws-dynamodbresourcepolicyperreplica) | When enabled will allow you to specify a resource policy per replica, and not copy the source table policy to all replicas | 2.164.0 | (fix) | -| [@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault](#aws-cdkaws-ec2bastionhostuseamazonlinux2023bydefault) | When enabled, the BastionHost construct will use the latest Amazon Linux 2023 AMI, instead of Amazon Linux 2. | V2NEXT | (default) | +| [@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault](#aws-cdkaws-ec2bastionhostuseamazonlinux2023bydefault) | When enabled, the BastionHost construct will use the latest Amazon Linux 2023 AMI, instead of Amazon Linux 2. | 2.172.0 | (default) | +| [@aws-cdk/core:aspectStabilization](#aws-cdkcoreaspectstabilization) | When enabled, a stabilization loop will be run when invoking Aspects during synthesis. | 2.172.0 | (config) | @@ -197,6 +198,7 @@ are migrating a v1 CDK project to v2, explicitly set any of these flags which do | [@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2\_2021](#aws-cdkaws-cloudfrontdefaultsecuritypolicytlsv12_2021) | Enable this feature flag to have cloudfront distributions use the security policy TLSv1.2_2021 by default. | (fix) | 1.117.0 | `false` | `true` | | [@aws-cdk/pipelines:reduceAssetRoleTrustScope](#aws-cdkpipelinesreduceassetroletrustscope) | Remove the root account principal from PipelineAssetsFileRole trust policy | (default) | | `false` | `true` | | [@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask](#aws-cdkaws-stepfunctions-tasksusenews3uriparametersforbedrockinvokemodeltask) | When enabled, use new props for S3 URI field in task definition of state machine for bedrock invoke model. | (fix) | | `false` | `true` | +| [@aws-cdk/core:aspectStabilization](#aws-cdkcoreaspectstabilization) | When enabled, a stabilization loop will be run when invoking Aspects during synthesis. | (config) | | `false` | `true` | @@ -213,7 +215,8 @@ Here is an example of a `cdk.json` file that restores v1 behavior for these flag "@aws-cdk/aws-lambda:recognizeVersionProps": false, "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": false, "@aws-cdk/pipelines:reduceAssetRoleTrustScope": false, - "@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask": false + "@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask": false, + "@aws-cdk/core:aspectStabilization": false } } ``` @@ -1546,9 +1549,25 @@ the latest Amazon Linux 2023 version will be used instead of Amazon Linux 2. | Since | Default | Recommended | | ----- | ----- | ----- | | (not in v1) | | | -| V2NEXT | `false` | `true` | +| 2.172.0 | `false` | `true` | **Compatibility with old behavior:** Disable the feature flag or explicitly pass an Amazon Linux 2 machine image to the BastionHost construct. +### @aws-cdk/core:aspectStabilization + +*When enabled, a stabilization loop will be run when invoking Aspects during synthesis.* (config) + +Currently, when Aspects are invoked in one single pass of the construct tree. +This means that the Aspects that create other Aspects are not run and Aspects that create new nodes of the tree sometimes do not inherit their parent Aspects. + +When this feature flag is enabled, a stabilization loop is run to recurse the construct tree multiple times when invoking Aspects. + + +| Since | Default | Recommended | +| ----- | ----- | ----- | +| (not in v1) | | | +| 2.172.0 | `true` | `true` | + + diff --git a/packages/aws-cdk-lib/cx-api/lib/features.ts b/packages/aws-cdk-lib/cx-api/lib/features.ts index 339898ba7a518..120e4a4a6b4d8 100644 --- a/packages/aws-cdk-lib/cx-api/lib/features.ts +++ b/packages/aws-cdk-lib/cx-api/lib/features.ts @@ -1265,7 +1265,7 @@ export const FLAGS: Record = { When this feature flag is enabled, if you do not pass the machineImage property to the BastionHost construct, the latest Amazon Linux 2023 version will be used instead of Amazon Linux 2. `, - introducedIn: { v2: 'V2NEXT' }, + introducedIn: { v2: '2.172.0' }, recommendedValue: true, compatibilityWithOldBehaviorMd: 'Disable the feature flag or explicitly pass an Amazon Linux 2 machine image to the BastionHost construct.', }, @@ -1281,7 +1281,7 @@ export const FLAGS: Record = { When this feature flag is enabled, a stabilization loop is run to recurse the construct tree multiple times when invoking Aspects. `, defaults: { v2: true }, - introducedIn: { v2: 'V2NEXT' }, + introducedIn: { v2: '2.172.0' }, recommendedValue: true, }, }; diff --git a/version.v2.json b/version.v2.json index 841a865f4d1b3..6508e95648e0d 100644 --- a/version.v2.json +++ b/version.v2.json @@ -1,4 +1,4 @@ { - "version": "2.171.1", - "alphaVersion": "2.171.1-alpha.0" + "version": "2.172.0", + "alphaVersion": "2.172.0-alpha.0" } \ No newline at end of file From f692fac1eb694a6b87372ee7e7d7ef665c32d1f8 Mon Sep 17 00:00:00 2001 From: Otavio Macedo <288203+otaviomacedo@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:11:20 +0000 Subject: [PATCH 2/7] Remove eks-v2-alpha changes --- CHANGELOG.v2.alpha.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.v2.alpha.md b/CHANGELOG.v2.alpha.md index bd8f4face7249..f7580ebb38ef8 100644 --- a/CHANGELOG.v2.alpha.md +++ b/CHANGELOG.v2.alpha.md @@ -9,8 +9,6 @@ All notable changes to this project will be documented in this file. See [standa * **ec2:** default BastionHostLinux to use Amazon Linux 2023 (under feature flag) ([#31996](https://github.com/aws/aws-cdk/issues/31996)) ([bf77e51](https://github.com/aws/aws-cdk/commit/bf77e51c90e3da972c464430d579695163160a13)), closes [#29493](https://github.com/aws/aws-cdk/issues/29493) [#29493](https://github.com/aws/aws-cdk/issues/29493) * **ec2:** instance support passing IAM instance profile ([#32073](https://github.com/aws/aws-cdk/issues/32073)) ([cf89d0f](https://github.com/aws/aws-cdk/commit/cf89d0f67f6d03bdeec38a4ffb48d3cda59db7cc)), closes [#8348](https://github.com/aws/aws-cdk/issues/8348) -* **eks-v2-alpha:** create the alpha package for the EKS L2 rewrite and setup test ([#32366](https://github.com/aws/aws-cdk/issues/32366)) ([b30c823](https://github.com/aws/aws-cdk/commit/b30c8234def40509899c7e7a7bd796d93470445d)) -* **eks-v2-alpha:** use native L1 instead of custom resource for Fargate Profile ([#32386](https://github.com/aws/aws-cdk/issues/32386)) ([8189c82](https://github.com/aws/aws-cdk/commit/8189c828be3eadeb82cbb4d7a9591f8327a2d18d)) * **neptune:** auto minor version upgrade for an instance ([#31988](https://github.com/aws/aws-cdk/issues/31988)) ([d95db49](https://github.com/aws/aws-cdk/commit/d95db491f7c1fd11dd42299f99d40fd94b0d642f)) * **pipes:** add LogDestination implementation ([#31672](https://github.com/aws/aws-cdk/issues/31672)) ([af5345e](https://github.com/aws/aws-cdk/commit/af5345e9ed2528bde2af6cd4b2428654b096eb93)), closes [#31671](https://github.com/aws/aws-cdk/issues/31671) * **pipes-targets:** add API Gateway ([#31954](https://github.com/aws/aws-cdk/issues/31954)) ([c77536f](https://github.com/aws/aws-cdk/commit/c77536f8999e221c8d6dae5742f484a04b05bac5)) From 3fe229d0eb48fe405e00bf3717face3c4cfc2cc1 Mon Sep 17 00:00:00 2001 From: Matsuda Date: Sat, 7 Dec 2024 10:13:35 +0900 Subject: [PATCH 3/7] fix(rds): serverlessV2MaxCapacity can be set to 0.5, which is invalid (#32232) ### Issue # (if applicable) N/A ### Reason for this change In [CFn docs](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-rds-dbcluster-serverlessv2scalingconfiguration.html#cfn-rds-dbcluster-serverlessv2scalingconfiguration-maxcapacity), MaximumCapacity value must be higher than 0.5 ACUs. ``` The maximum capacity must be higher than 0.5 ACUs. ``` This means MaximumCapacity cannot be set to 0.5 ACUs. However, in the CDK, `serverlessV2MaxCapacity` can be set to 0.5, which is invalid. When I attempted to deploy with `serverlessV2MaxCapacity` set to 0.5, I encountered the following error: > CREATE_FAILED | AWS::RDS::DBCluster | Integ-Cluster (IntegCluster4261F36F) Resource handler returned message: "Serverless v2 maximum capacity 0.5 isn't valid. The maximum capacity must be at least 1.0. In the Management Console, Maximum Capacity cannot be set to 0.5. image ### Description of changes Fix a validation. ### Description of how you validated changes Fix unit tests. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *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/aws-rds/lib/cluster.ts | 7 ++----- packages/aws-cdk-lib/aws-rds/test/cluster.test.ts | 5 ++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/aws-cdk-lib/aws-rds/lib/cluster.ts b/packages/aws-cdk-lib/aws-rds/lib/cluster.ts index 3f09f240df96d..48521aedd2a1b 100644 --- a/packages/aws-cdk-lib/aws-rds/lib/cluster.ts +++ b/packages/aws-cdk-lib/aws-rds/lib/cluster.ts @@ -1074,8 +1074,8 @@ abstract class DatabaseClusterNew extends DatabaseClusterBase { } private validateServerlessScalingConfig(): void { - if (this.serverlessV2MaxCapacity > 256 || this.serverlessV2MaxCapacity < 0.5) { - throw new Error('serverlessV2MaxCapacity must be >= 0.5 & <= 256'); + if (this.serverlessV2MaxCapacity > 256 || this.serverlessV2MaxCapacity < 1) { + throw new Error('serverlessV2MaxCapacity must be >= 1 & <= 256'); } if (this.serverlessV2MinCapacity > 256 || this.serverlessV2MinCapacity < 0) { @@ -1086,9 +1086,6 @@ abstract class DatabaseClusterNew extends DatabaseClusterBase { throw new Error('serverlessV2MaxCapacity must be greater than serverlessV2MinCapacity'); } - if (this.serverlessV2MaxCapacity === 0.5 && this.serverlessV2MinCapacity === 0.5) { - throw new Error('If serverlessV2MinCapacity === 0.5 then serverlessV2MaxCapacity must be >=1'); - } const regexp = new RegExp(/^[0-9]+\.?5?$/); if (!regexp.test(this.serverlessV2MaxCapacity.toString()) || !regexp.test(this.serverlessV2MinCapacity.toString())) { throw new Error('serverlessV2MinCapacity & serverlessV2MaxCapacity must be in 0.5 step increments, received '+ diff --git a/packages/aws-cdk-lib/aws-rds/test/cluster.test.ts b/packages/aws-cdk-lib/aws-rds/test/cluster.test.ts index 8091945676ea8..56a426d9cc9ec 100644 --- a/packages/aws-cdk-lib/aws-rds/test/cluster.test.ts +++ b/packages/aws-cdk-lib/aws-rds/test/cluster.test.ts @@ -116,11 +116,10 @@ describe('cluster new api', () => { }); test.each([ - [0.5, 300, /serverlessV2MaxCapacity must be >= 0.5 & <= 256/], - [0.5, 0, /serverlessV2MaxCapacity must be >= 0.5 & <= 256/], + [0.5, 300, /serverlessV2MaxCapacity must be >= 1 & <= 256/], + [0.5, 0, /serverlessV2MaxCapacity must be >= 1 & <= 256/], [-1, 1, /serverlessV2MinCapacity must be >= 0 & <= 256/], [300, 1, /serverlessV2MinCapacity must be >= 0 & <= 256/], - [0.5, 0.5, /If serverlessV2MinCapacity === 0.5 then serverlessV2MaxCapacity must be >=1/], [10.1, 12, /serverlessV2MinCapacity & serverlessV2MaxCapacity must be in 0.5 step increments/], [12, 12.1, /serverlessV2MinCapacity & serverlessV2MaxCapacity must be in 0.5 step increments/], [5, 1, /serverlessV2MaxCapacity must be greater than serverlessV2MinCapacity/], From 609faba4d8a454fa6b320631180507f0001eecb3 Mon Sep 17 00:00:00 2001 From: Hogan Bobertz Date: Fri, 6 Dec 2024 20:44:50 -0500 Subject: [PATCH 4/7] chore: chalk breaking logging tests (#32393) ### Reason for this change logging tests would break when running `npx jest` but not when running `yarn test` as npx jest was not pulling out the ansi codes which were failing the string comparisons. ### Description of changes Removed all the ansi codes from stdout in logging and log-monitor tests ### Description of how you validated changes ran `npx jest` and `yarn test` as well as rebuilt the package ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../logs/cli-logging.test.ts} | 52 +++++++++++-------- .../test/api/logs/logs-monitor.test.ts | 23 +++++--- 2 files changed, 45 insertions(+), 30 deletions(-) rename packages/aws-cdk/test/{logging.test.ts => api/logs/cli-logging.test.ts} (65%) diff --git a/packages/aws-cdk/test/logging.test.ts b/packages/aws-cdk/test/api/logs/cli-logging.test.ts similarity index 65% rename from packages/aws-cdk/test/logging.test.ts rename to packages/aws-cdk/test/api/logs/cli-logging.test.ts index 4a7ae5d254b77..08300a7e64890 100644 --- a/packages/aws-cdk/test/logging.test.ts +++ b/packages/aws-cdk/test/api/logs/cli-logging.test.ts @@ -1,10 +1,16 @@ -import { LogLevel, log, setLogLevel, setCI, data, print, error, warning, success, debug, trace, prefix, withCorkedLogging } from '../lib/logging'; +import { LogLevel, log, setLogLevel, setCI, data, print, error, warning, success, debug, trace, prefix, withCorkedLogging } from '../../../lib/logging'; describe('logging', () => { // Mock streams to capture output let mockStdout: jest.Mock; let mockStderr: jest.Mock; + // Helper function to strip ANSI codes + const stripAnsi = (str: string): string => { + const ansiRegex = /\u001b\[[0-9;]*[a-zA-Z]/g; + return str.replace(ansiRegex, ''); + }; + beforeEach(() => { // Reset log level before each test setLogLevel(LogLevel.INFO); @@ -14,14 +20,14 @@ describe('logging', () => { mockStdout = jest.fn(); mockStderr = jest.fn(); - // Mock the write methods directly + // Mock the write methods directly and strip ANSI codes jest.spyOn(process.stdout, 'write').mockImplementation((chunk: any) => { - mockStdout(chunk.toString()); + mockStdout(stripAnsi(chunk.toString())); return true; }); jest.spyOn(process.stderr, 'write').mockImplementation((chunk: any) => { - mockStderr(chunk.toString()); + mockStderr(stripAnsi(chunk.toString())); return true; }); }); @@ -29,29 +35,30 @@ describe('logging', () => { afterEach(() => { jest.restoreAllMocks(); }); + describe('stream selection', () => { test('data() always writes to stdout', () => { data('test message'); - expect(mockStdout).toHaveBeenCalledWith(expect.stringContaining('test message\n')); + expect(mockStdout).toHaveBeenCalledWith('test message\n'); expect(mockStderr).not.toHaveBeenCalled(); }); test('error() always writes to stderr', () => { error('test error'); - expect(mockStderr).toHaveBeenCalledWith(expect.stringContaining('test error\n')); + expect(mockStderr).toHaveBeenCalledWith('test error\n'); expect(mockStdout).not.toHaveBeenCalled(); }); test('print() writes to stderr by default', () => { print('test print'); - expect(mockStderr).toHaveBeenCalledWith(expect.stringContaining('test print\n')); + expect(mockStderr).toHaveBeenCalledWith('test print\n'); expect(mockStdout).not.toHaveBeenCalled(); }); test('print() writes to stdout in CI mode', () => { setCI(true); print('test print'); - expect(mockStdout).toHaveBeenCalledWith(expect.stringContaining('test print\n')); + expect(mockStdout).toHaveBeenCalledWith('test print\n'); expect(mockStderr).not.toHaveBeenCalled(); }); }); @@ -62,9 +69,9 @@ describe('logging', () => { error('error message'); warning('warning message'); print('print message'); - expect(mockStderr).toHaveBeenCalledWith(expect.stringContaining('error message\n')); - expect(mockStderr).not.toHaveBeenCalledWith(expect.stringContaining('warning message\n')); - expect(mockStderr).not.toHaveBeenCalledWith(expect.stringContaining('print message\n')); + expect(mockStderr).toHaveBeenCalledWith('error message\n'); + expect(mockStderr).not.toHaveBeenCalledWith('warning message\n'); + expect(mockStderr).not.toHaveBeenCalledWith('print message\n'); }); test('debug messages only show at debug level', () => { @@ -74,7 +81,7 @@ describe('logging', () => { setLogLevel(LogLevel.DEBUG); debug('debug message'); - expect(mockStderr).toHaveBeenCalledWith(expect.stringContaining('debug message\n')); + expect(mockStderr).toHaveBeenCalledWith('debug message\n'); }); test('trace messages only show at trace level', () => { @@ -84,26 +91,25 @@ describe('logging', () => { setLogLevel(LogLevel.TRACE); trace('trace message'); - expect(mockStderr).toHaveBeenCalledWith(expect.stringContaining('trace message\n')); + expect(mockStderr).toHaveBeenCalledWith('trace message\n'); }); }); describe('message formatting', () => { test('formats messages with multiple arguments', () => { print('Value: %d, String: %s', 42, 'test'); - expect(mockStderr).toHaveBeenCalledWith(expect.stringContaining('Value: 42, String: test\n')); + expect(mockStderr).toHaveBeenCalledWith('Value: 42, String: test\n'); }); test('handles prefix correctly', () => { const prefixedLog = prefix('PREFIX'); prefixedLog('test message'); - expect(mockStderr).toHaveBeenCalledWith(expect.stringContaining('PREFIX test message\n')); + expect(mockStderr).toHaveBeenCalledWith('PREFIX test message\n'); }); test('handles custom styles', () => { success('success message'); - // Note: actual styling will depend on chalk, but we can verify the message is there - expect(mockStderr).toHaveBeenCalledWith(expect.stringContaining('success message\n')); + expect(mockStderr).toHaveBeenCalledWith('success message\n'); }); }); @@ -115,8 +121,8 @@ describe('logging', () => { expect(mockStderr).not.toHaveBeenCalled(); }); - expect(mockStderr).toHaveBeenCalledWith(expect.stringContaining('message 1\n')); - expect(mockStderr).toHaveBeenCalledWith(expect.stringContaining('message 2\n')); + expect(mockStderr).toHaveBeenCalledWith('message 1\n'); + expect(mockStderr).toHaveBeenCalledWith('message 2\n'); }); test('handles nested corking correctly', async () => { @@ -130,9 +136,9 @@ describe('logging', () => { }); expect(mockStderr).toHaveBeenCalledTimes(3); - expect(mockStderr).toHaveBeenCalledWith(expect.stringContaining('outer 1\n')); - expect(mockStderr).toHaveBeenCalledWith(expect.stringContaining('inner\n')); - expect(mockStderr).toHaveBeenCalledWith(expect.stringContaining('outer 2\n')); + expect(mockStderr).toHaveBeenCalledWith('outer 1\n'); + expect(mockStderr).toHaveBeenCalledWith('inner\n'); + expect(mockStderr).toHaveBeenCalledWith('outer 2\n'); }); }); @@ -145,7 +151,7 @@ describe('logging', () => { prefix: 'PREFIX', }); expect(mockStderr).toHaveBeenCalledWith( - expect.stringMatching(/PREFIX \[\d{2}:\d{2}:\d{2}\] test message\n/), + expect.stringMatching(/^PREFIX \[\d{2}:\d{2}:\d{2}\] test message\n$/), ); }); }); diff --git a/packages/aws-cdk/test/api/logs/logs-monitor.test.ts b/packages/aws-cdk/test/api/logs/logs-monitor.test.ts index 85f903e7681a8..4bdb7f96bd0a4 100644 --- a/packages/aws-cdk/test/api/logs/logs-monitor.test.ts +++ b/packages/aws-cdk/test/api/logs/logs-monitor.test.ts @@ -1,16 +1,25 @@ import { FilterLogEventsCommand, type FilteredLogEvent } from '@aws-sdk/client-cloudwatch-logs'; -import { blue, yellow } from 'chalk'; import { CloudWatchLogEventMonitor } from '../../../lib/api/logs/logs-monitor'; import { sleep } from '../../util'; import { MockSdk, mockCloudWatchClient } from '../../util/mock-sdk'; +// Helper function to strip ANSI codes +const stripAnsi = (str: string): string => { + const ansiRegex = /\u001b\[[0-9;]*[a-zA-Z]/g; + return str.replace(ansiRegex, ''); +}; + let sdk: MockSdk; let stderrMock: jest.SpyInstance; let monitor: CloudWatchLogEventMonitor; beforeEach(() => { monitor = new CloudWatchLogEventMonitor(new Date(T100)); - stderrMock = jest.spyOn(process.stderr, 'write').mockImplementation(() => { - return true; + stderrMock = jest.spyOn(process.stderr, 'write').mockImplementation((chunk: any) => { + // Strip ANSI codes when capturing output + if (typeof chunk === 'string') { + return stripAnsi(chunk) as unknown as boolean; + } + return stripAnsi(chunk.toString()) as unknown as boolean; }); sdk = new MockSdk(); }); @@ -44,7 +53,7 @@ test('process events', async () => { // THEN const expectedLocaleTimeString = eventDate.toLocaleTimeString(); expect(stderrMock).toHaveBeenCalledTimes(1); - expect(stderrMock.mock.calls[0][0]).toContain(`[${blue('loggroup')}] ${yellow(expectedLocaleTimeString)} message`); + expect(stripAnsi(stderrMock.mock.calls[0][0])).toContain(`[loggroup] ${expectedLocaleTimeString} message`); }); test('process truncated events', async () => { @@ -76,9 +85,9 @@ test('process truncated events', async () => { // THEN const expectedLocaleTimeString = eventDate.toLocaleTimeString(); expect(stderrMock).toHaveBeenCalledTimes(101); - expect(stderrMock.mock.calls[0][0]).toContain(`[${blue('loggroup')}] ${yellow(expectedLocaleTimeString)} message`); - expect(stderrMock.mock.calls[100][0]).toContain( - `[${blue('loggroup')}] ${yellow(expectedLocaleTimeString)} >>> \`watch\` shows only the first 100 log messages - the rest have been truncated...`, + expect(stripAnsi(stderrMock.mock.calls[0][0])).toContain(`[loggroup] ${expectedLocaleTimeString} message0`); + expect(stripAnsi(stderrMock.mock.calls[100][0])).toContain( + `[loggroup] ${expectedLocaleTimeString} >>> \`watch\` shows only the first 100 log messages - the rest have been truncated...`, ); }); From 2607eb3a905f735b96713dda4f32d28d10d686fd Mon Sep 17 00:00:00 2001 From: Momo Kornher Date: Fri, 6 Dec 2024 18:16:14 -0800 Subject: [PATCH 5/7] fix(lambda): improve validation errors for lambda functions (#32323) ### Issue # (if applicable) Relates to #32324 ### Reason for this change Currently all errors are untyped. This makes it difficult users to programmatically distinguish between different classes of errors, e.g. what is a validation error vs what is a syntax error? With this change, users can catch errors and check their type before proceeding accordingly. ### Description of changes Addition of a new Error type `ValidationError`. For now this error is used only in a single file. The intention is to extend this to all error cases. `ValidationError` extends an abstract `ConstructError` which also handles any improvements to error display. `ConstructError` manipulates the stack trace to improve display. It's changing two things, both of which are based on a construct that is passed in on error creation. If not construct is passed, the error behaves as before. 1. Construct information is inserted as the first line of the stack trace. 2. The strack trace is captured from the point of _creation of the construct_. That is the class constructor call. This is achieved by passing the error's constructs into [Error.captureStackTrace](https://nodejs.org/docs/latest-v22.x/api/errors.html#errorcapturestacktracetargetobject-constructoropt). As a side effect, in many cases the "line of error" is not minified code anymore and thus doesn't ruin the error experience for users. See comments for current vs future errors. ### Description of how you validated changes Existing test. Manual testing of error cases. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-cdk-lib/aws-lambda/lib/function.ts | 87 +++++------ packages/aws-cdk-lib/core/lib/errors.ts | 145 ++++++++++++++++++ packages/aws-cdk-lib/core/lib/index.ts | 1 + packages/aws-cdk-lib/core/test/errors.test.ts | 34 ++++ 4 files changed, 224 insertions(+), 43 deletions(-) create mode 100644 packages/aws-cdk-lib/core/lib/errors.ts create mode 100644 packages/aws-cdk-lib/core/test/errors.test.ts diff --git a/packages/aws-cdk-lib/aws-lambda/lib/function.ts b/packages/aws-cdk-lib/aws-lambda/lib/function.ts index 38481f883b92e..ad239483b50ef 100644 --- a/packages/aws-cdk-lib/aws-lambda/lib/function.ts +++ b/packages/aws-cdk-lib/aws-lambda/lib/function.ts @@ -30,6 +30,7 @@ import * as logs from '../../aws-logs'; import * as sns from '../../aws-sns'; import * as sqs from '../../aws-sqs'; import { Annotations, ArnFormat, CfnResource, Duration, FeatureFlags, Fn, IAspect, Lazy, Names, Size, Stack, Token } from '../../core'; +import { ValidationError } from '../../core/lib/errors'; import { LAMBDA_RECOGNIZE_LAYER_VERSION } from '../../cx-api'; /** @@ -917,16 +918,16 @@ export class Function extends FunctionBase { if (props.functionName && !Token.isUnresolved(props.functionName)) { if (props.functionName.length > 64) { - throw new Error(`Function name can not be longer than 64 characters but has ${props.functionName.length} characters.`); + throw new ValidationError(`Function name can not be longer than 64 characters but has ${props.functionName.length} characters.`, this); } if (!/^[a-zA-Z0-9-_]+$/.test(props.functionName)) { - throw new Error(`Function name ${props.functionName} can contain only letters, numbers, hyphens, or underscores with no spaces.`); + throw new ValidationError(`Function name ${props.functionName} can contain only letters, numbers, hyphens, or underscores with no spaces.`, this); } } if (props.description && !Token.isUnresolved(props.description)) { if (props.description.length > 256) { - throw new Error(`Function description can not be longer than 256 characters but has ${props.description.length} characters.`); + throw new ValidationError(`Function description can not be longer than 256 characters but has ${props.description.length} characters.`, this); } } @@ -951,10 +952,10 @@ export class Function extends FunctionBase { const config = props.filesystem.config; if (!Token.isUnresolved(config.localMountPath)) { if (!/^\/mnt\/[a-zA-Z0-9-_.]+$/.test(config.localMountPath)) { - throw new Error(`Local mount path should match with ^/mnt/[a-zA-Z0-9-_.]+$ but given ${config.localMountPath}.`); + throw new ValidationError(`Local mount path should match with ^/mnt/[a-zA-Z0-9-_.]+$ but given ${config.localMountPath}.`, this); } if (config.localMountPath.length > 160) { - throw new Error(`Local mount path can not be longer than 160 characters but has ${config.localMountPath.length} characters.`); + throw new ValidationError(`Local mount path can not be longer than 160 characters but has ${config.localMountPath.length} characters.`, this); } } if (config.policies) { @@ -1019,16 +1020,16 @@ export class Function extends FunctionBase { } if (props.architecture && props.architectures !== undefined) { - throw new Error('Either architecture or architectures must be specified but not both.'); + throw new ValidationError('Either architecture or architectures must be specified but not both.', this); } if (props.architectures && props.architectures.length > 1) { - throw new Error('Only one architecture must be specified.'); + throw new ValidationError('Only one architecture must be specified.', this); } this._architecture = props.architecture ?? (props.architectures && props.architectures[0]); if (props.ephemeralStorageSize && !props.ephemeralStorageSize.isUnresolved() && (props.ephemeralStorageSize.toMebibytes() < 512 || props.ephemeralStorageSize.toMebibytes() > 10240)) { - throw new Error(`Ephemeral storage size must be between 512 and 10240 MB, received ${props.ephemeralStorageSize}.`); + throw new ValidationError(`Ephemeral storage size must be between 512 and 10240 MB, received ${props.ephemeralStorageSize}.`, this); } const resource: CfnFunction = new CfnFunction(this, 'Resource', { @@ -1096,7 +1097,7 @@ export class Function extends FunctionBase { if (props.layers) { if (props.runtime === Runtime.FROM_IMAGE) { - throw new Error('Layers are not supported for container image functions'); + throw new ValidationError('Layers are not supported for container image functions', this); } this.addLayers(...props.layers); @@ -1109,7 +1110,7 @@ export class Function extends FunctionBase { // Log retention if (props.logRetention) { if (props.logGroup) { - throw new Error('CDK does not support setting logRetention and logGroup'); + throw new ValidationError('CDK does not support setting logRetention and logGroup', this); } const logRetention = new logs.LogRetention(this, 'LogRetention', { logGroupName: `/aws/lambda/${this.functionName}`, @@ -1137,7 +1138,7 @@ export class Function extends FunctionBase { if (props.filesystem) { if (!props.vpc) { - throw new Error('Cannot configure \'filesystem\' without configuring a VPC.'); + throw new ValidationError('Cannot configure \'filesystem\' without configuring a VPC.', this); } const config = props.filesystem.config; if (config.dependency) { @@ -1201,7 +1202,7 @@ export class Function extends FunctionBase { 'LAMBDA_RUNTIME_DIR', ]; if (reservedEnvironmentVariables.includes(key)) { - throw new Error(`${key} environment variable is reserved by the lambda runtime and can not be set manually. See https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html`); + throw new ValidationError(`${key} environment variable is reserved by the lambda runtime and can not be set manually. See https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html`, this); } this.environment[key] = { value, ...options }; return this; @@ -1214,24 +1215,24 @@ export class Function extends FunctionBase { */ private getLoggingConfig(props: FunctionProps): CfnFunction.LoggingConfigProperty | undefined { if (props.logFormat && props.loggingFormat) { - throw new Error('Only define LogFormat or LoggingFormat, not both.'); + throw new ValidationError('Only define LogFormat or LoggingFormat, not both.', this); } if (props.applicationLogLevel && props.applicationLogLevelV2) { - throw new Error('Only define applicationLogLevel or applicationLogLevelV2, not both.'); + throw new ValidationError('Only define applicationLogLevel or applicationLogLevelV2, not both.', this); } if (props.systemLogLevel && props.systemLogLevelV2) { - throw new Error('Only define systemLogLevel or systemLogLevelV2, not both.'); + throw new ValidationError('Only define systemLogLevel or systemLogLevelV2, not both.', this); } if (props.applicationLogLevel || props.applicationLogLevelV2 || props.systemLogLevel || props.systemLogLevelV2) { if (props.logFormat !== LogFormat.JSON && props.loggingFormat === undefined) { - throw new Error(`To use ApplicationLogLevel and/or SystemLogLevel you must set LogFormat to '${LogFormat.JSON}', got '${props.logFormat}'.`); + throw new ValidationError(`To use ApplicationLogLevel and/or SystemLogLevel you must set LogFormat to '${LogFormat.JSON}', got '${props.logFormat}'.`, this); } if (props.loggingFormat !== LoggingFormat.JSON && props.logFormat === undefined) { - throw new Error(`To use ApplicationLogLevel and/or SystemLogLevel you must set LoggingFormat to '${LoggingFormat.JSON}', got '${props.loggingFormat}'.`); + throw new ValidationError(`To use ApplicationLogLevel and/or SystemLogLevel you must set LoggingFormat to '${LoggingFormat.JSON}', got '${props.loggingFormat}'.`, this); } } @@ -1268,7 +1269,7 @@ export class Function extends FunctionBase { */ public invalidateVersionBasedOn(x: string) { if (Token.isUnresolved(x)) { - throw new Error('invalidateVersionOn: input may not contain unresolved tokens'); + throw new ValidationError('invalidateVersionOn: input may not contain unresolved tokens', this); } this.hashMixins.push(x); } @@ -1283,11 +1284,11 @@ export class Function extends FunctionBase { public addLayers(...layers: ILayerVersion[]): void { for (const layer of layers) { if (this._layers.length === 5) { - throw new Error('Unable to add layer: this lambda function already uses 5 layers.'); + throw new ValidationError('Unable to add layer: this lambda function already uses 5 layers.', this); } if (layer.compatibleRuntimes && !layer.compatibleRuntimes.find(runtime => runtime.runtimeEquals(this.runtime))) { const runtimes = layer.compatibleRuntimes.map(runtime => runtime.name).join(', '); - throw new Error(`This lambda function uses a runtime that is incompatible with this layer (${this.runtime.name} is not in [${runtimes}])`); + throw new ValidationError(`This lambda function uses a runtime that is incompatible with this layer (${this.runtime.name} is not in [${runtimes}])`, this); } // Currently no validations for compatible architectures since Lambda service @@ -1398,8 +1399,8 @@ export class Function extends FunctionBase { } const envKeys = Object.keys(this.environment); if (envKeys.length !== 0) { - throw new Error(`The function ${this.node.path} contains environment variables [${envKeys}] and is not compatible with Lambda@Edge. \ -Environment variables can be marked for removal when used in Lambda@Edge by setting the \'removeInEdge\' property in the \'addEnvironment()\' API.`); + throw new ValidationError(`The function ${this.node.path} contains environment variables [${envKeys}] and is not compatible with Lambda@Edge. \ +Environment variables can be marked for removal when used in Lambda@Edge by setting the \'removeInEdge\' property in the \'addEnvironment()\' API.`, this); } return; @@ -1435,19 +1436,19 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett } if (props.runtime === Runtime.FROM_IMAGE) { - throw new Error("ADOT Lambda layer can't be configured with container image package type"); + throw new ValidationError("ADOT Lambda layer can't be configured with container image package type", this); } // This is not the complete list of incompatible runtimes and layer types. We are only // checking for common mistakes on a best-effort basis. if (this.runtime === Runtime.GO_1_X) { - throw new Error('Runtime go1.x is not supported by the ADOT Lambda Go SDK'); + throw new ValidationError('Runtime go1.x is not supported by the ADOT Lambda Go SDK', this); } // The Runtime is Python and Adot is set it requires a different EXEC_WRAPPER than the other code bases. if (this.runtime.family === RuntimeFamily.PYTHON && props.adotInstrumentation.execWrapper.valueOf() !== AdotLambdaExecWrapper.INSTRUMENT_HANDLER) { - throw new Error('Python Adot Lambda layer requires AdotLambdaExecWrapper.INSTRUMENT_HANDLER'); + throw new ValidationError('Python Adot Lambda layer requires AdotLambdaExecWrapper.INSTRUMENT_HANDLER', this); } this.addLayers(LayerVersion.fromLayerVersionArn(this, 'AdotLayer', props.adotInstrumentation.layerVersion._bind(this).arn)); @@ -1510,47 +1511,47 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett */ private configureVpc(props: FunctionProps): CfnFunction.VpcConfigProperty | undefined { if (props.securityGroup && props.securityGroups) { - throw new Error('Only one of the function props, securityGroup or securityGroups, is allowed'); + throw new ValidationError('Only one of the function props, securityGroup or securityGroups, is allowed', this); } const hasSecurityGroups = props.securityGroups && props.securityGroups.length > 0; if (!props.vpc) { if (props.allowAllOutbound !== undefined) { - throw new Error('Cannot configure \'allowAllOutbound\' without configuring a VPC'); + throw new ValidationError('Cannot configure \'allowAllOutbound\' without configuring a VPC', this); } if (props.securityGroup) { - throw new Error('Cannot configure \'securityGroup\' without configuring a VPC'); + throw new ValidationError('Cannot configure \'securityGroup\' without configuring a VPC', this); } if (hasSecurityGroups) { - throw new Error('Cannot configure \'securityGroups\' without configuring a VPC'); + throw new ValidationError('Cannot configure \'securityGroups\' without configuring a VPC', this); } if (props.vpcSubnets) { - throw new Error('Cannot configure \'vpcSubnets\' without configuring a VPC'); + throw new ValidationError('Cannot configure \'vpcSubnets\' without configuring a VPC', this); } if (props.ipv6AllowedForDualStack) { - throw new Error('Cannot configure \'ipv6AllowedForDualStack\' without configuring a VPC'); + throw new ValidationError('Cannot configure \'ipv6AllowedForDualStack\' without configuring a VPC', this); } if (props.allowAllIpv6Outbound !== undefined) { - throw new Error('Cannot configure \'allowAllIpv6Outbound\' without configuring a VPC'); + throw new ValidationError('Cannot configure \'allowAllIpv6Outbound\' without configuring a VPC', this); } return undefined; } if (props.allowAllOutbound !== undefined) { if (props.securityGroup) { - throw new Error('Configure \'allowAllOutbound\' directly on the supplied SecurityGroup.'); + throw new ValidationError('Configure \'allowAllOutbound\' directly on the supplied SecurityGroup.', this); } if (hasSecurityGroups) { - throw new Error('Configure \'allowAllOutbound\' directly on the supplied SecurityGroups.'); + throw new ValidationError('Configure \'allowAllOutbound\' directly on the supplied SecurityGroups.', this); } } if (props.allowAllIpv6Outbound !== undefined) { if (props.securityGroup) { - throw new Error('Configure \'allowAllIpv6Outbound\' directly on the supplied SecurityGroup.'); + throw new ValidationError('Configure \'allowAllIpv6Outbound\' directly on the supplied SecurityGroup.', this); } if (hasSecurityGroups) { - throw new Error('Configure \'allowAllIpv6Outbound\' directly on the supplied SecurityGroups.'); + throw new ValidationError('Configure \'allowAllIpv6Outbound\' directly on the supplied SecurityGroups.', this); } } @@ -1585,8 +1586,8 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett const publicSubnetIds = new Set(props.vpc.publicSubnets.map(s => s.subnetId)); for (const subnetId of selectedSubnets.subnetIds) { if (publicSubnetIds.has(subnetId) && !allowPublicSubnet) { - throw new Error('Lambda Functions in a public subnet can NOT access the internet. ' + - 'If you are aware of this limitation and would still like to place the function in a public subnet, set `allowPublicSubnet` to true'); + throw new ValidationError('Lambda Functions in a public subnet can NOT access the internet. ' + + 'If you are aware of this limitation and would still like to place the function in a public subnet, set `allowPublicSubnet` to true', this); } } this.node.addDependency(selectedSubnets.internetConnectivityEstablished); @@ -1622,15 +1623,15 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett Annotations.of(this).addWarningV2('@aws-cdk/aws-lambda:snapStartRequirePublish', 'SnapStart only support published Lambda versions. Ignore if function already have published versions'); if (!props.runtime.supportsSnapStart) { - throw new Error(`SnapStart currently not supported by runtime ${props.runtime.name}`); + throw new ValidationError(`SnapStart currently not supported by runtime ${props.runtime.name}`, this); } if (props.filesystem) { - throw new Error('SnapStart is currently not supported using EFS'); + throw new ValidationError('SnapStart is currently not supported using EFS', this); } if (props.ephemeralStorageSize && props.ephemeralStorageSize?.toMebibytes() > 512) { - throw new Error('SnapStart is currently not supported using more than 512 MiB Ephemeral Storage'); + throw new ValidationError('SnapStart is currently not supported using more than 512 MiB Ephemeral Storage', this); } return props.snapStart._render(); @@ -1648,7 +1649,7 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett throw Error('deadLetterQueue defined but deadLetterQueueEnabled explicitly set to false'); } if (props.deadLetterTopic && (props.deadLetterQueue || props.deadLetterQueueEnabled !== undefined)) { - throw new Error('deadLetterQueue and deadLetterTopic cannot be specified together at the same time'); + throw new ValidationError('deadLetterQueue and deadLetterTopic cannot be specified together at the same time', this); } let deadLetterQueue: sqs.IQueue | sns.ITopic; @@ -1698,7 +1699,7 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett private validateProfiling(props: FunctionProps) { if (!props.runtime.supportsCodeGuruProfiling) { - throw new Error(`CodeGuru profiling is not supported by runtime ${props.runtime.name}`); + throw new ValidationError(`CodeGuru profiling is not supported by runtime ${props.runtime.name}`, this); } if (props.environment && (props.environment.AWS_CODEGURU_PROFILER_GROUP_NAME || props.environment.AWS_CODEGURU_PROFILER_GROUP_ARN diff --git a/packages/aws-cdk-lib/core/lib/errors.ts b/packages/aws-cdk-lib/core/lib/errors.ts new file mode 100644 index 0000000000000..727cf0228c396 --- /dev/null +++ b/packages/aws-cdk-lib/core/lib/errors.ts @@ -0,0 +1,145 @@ +import { IConstruct } from 'constructs'; +import { constructInfoFromConstruct } from './helpers-internal'; + +const CONSTRUCT_ERROR_SYMBOL = Symbol.for('@aws-cdk/core.SynthesisError'); +const VALIDATION_ERROR_SYMBOL = Symbol.for('@aws-cdk/core.ValidationError'); + +/** + * Helper to check if an error is a SynthesisErrors + */ +export class Errors { + /** + * Test whether the given errors is a ConstructionError + */ + public static isConstructError(x: any): x is ConstructError { + return x !== null && typeof(x) === 'object' && CONSTRUCT_ERROR_SYMBOL in x; + } + + /** + * Test whether the given error is a ValidationError + */ + public static isValidationError(x: any): x is ValidationError { + return Errors.isConstructError(x) && VALIDATION_ERROR_SYMBOL in x; + } +} + +interface ConstructInfo { + readonly fqn: string; + readonly version: string; +} + +/** + * Generic, abstract error that is thrown from the users app during app construction or synth. + */ +abstract class ConstructError extends Error { + #time: string; + #constructPath?: string; + #constructInfo?: ConstructInfo; + + /** + * The time the error was thrown. + */ + public get time(): string { + return this.#time; + } + + /** + * The level. Always `'error'`. + */ + public get level(): 'error' { + return 'error'; + } + + /** + * The type of the error. + */ + public abstract get type(): string; + + /** + * The path of the construct this error is thrown from, if available. + */ + public get constructPath(): string | undefined { + return this.#constructPath; + } + + /** + * Information on the construct this error is thrown from, if available. + */ + public get constructInfo(): ConstructInfo | undefined { + return this.#constructInfo; + } + + constructor(msg: string, scope?: IConstruct) { + super(msg); + Object.setPrototypeOf(this, ConstructError.prototype); + Object.defineProperty(this, CONSTRUCT_ERROR_SYMBOL, { value: true }); + + this.name = new.target.name; + this.#time = new Date().toISOString(); + this.#constructPath = scope?.node.path; + + if (scope) { + Error.captureStackTrace(this, scope.constructor); + try { + this.#constructInfo = scope ? constructInfoFromConstruct(scope) : undefined; + } catch (_) { + // we don't want to fail if construct info is not available + } + } + + const stack = [ + `${this.name}: ${this.message}`, + ]; + + if (this.constructInfo) { + stack.push(`in ${this.constructInfo?.fqn} at [${this.constructPath}]`); + } else { + stack.push(`in [${this.constructPath}]`); + } + + if (this.stack) { + stack.push(this.stack); + } + + this.stack = this.constructStack(this.stack); + } + + /** + * Helper message to clean-up the stack and amend with construct information. + */ + private constructStack(prev?: string) { + const indent = ' '.repeat(4); + + const stack = [ + `${this.name}: ${this.message}`, + ]; + + if (this.constructInfo) { + stack.push(`${indent}at path [${this.constructPath}] in ${this.constructInfo?.fqn}`); + } else { + stack.push(`${indent}at path [${this.constructPath}]`); + } + + if (prev) { + stack.push(''); + stack.push(...prev.split('\n').slice(1)); + } + + return stack.join('\n'); + } +} + +/** + * An Error that is thrown when a construct has validation errors. + */ +export class ValidationError extends ConstructError { + public get type(): 'validation' { + return 'validation'; + } + + constructor(msg: string, scope: IConstruct) { + super(msg, scope); + Object.setPrototypeOf(this, ValidationError.prototype); + Object.defineProperty(this, VALIDATION_ERROR_SYMBOL, { value: true }); + } +} diff --git a/packages/aws-cdk-lib/core/lib/index.ts b/packages/aws-cdk-lib/core/lib/index.ts index b35e89c0e59e4..9fb4041a136a0 100644 --- a/packages/aws-cdk-lib/core/lib/index.ts +++ b/packages/aws-cdk-lib/core/lib/index.ts @@ -35,6 +35,7 @@ export * from './expiration'; export * from './size'; export * from './stack-trace'; export { Element } from './deps'; +export { Errors } from './errors'; export * from './app'; export * from './context-provider'; diff --git a/packages/aws-cdk-lib/core/test/errors.test.ts b/packages/aws-cdk-lib/core/test/errors.test.ts new file mode 100644 index 0000000000000..a1a7f34de051e --- /dev/null +++ b/packages/aws-cdk-lib/core/test/errors.test.ts @@ -0,0 +1,34 @@ +import { App, Stack } from '../lib'; +import { Errors, ValidationError } from '../lib/errors'; + +jest + .useFakeTimers() + .setSystemTime(new Date('2020-01-01')); + +describe('ValidationError', () => { + test('ValidationError is ValidationError and ConstructError', () => { + const error = new ValidationError('this is an error', new App()); + + expect(Errors.isConstructError(error)).toBe(true); + expect(Errors.isValidationError(error)).toBe(true); + }); + + test('ValidationError data', () => { + const app = new App(); + const stack = new Stack(app, 'MyStack'); + const error = new ValidationError('this is an error', stack); + + expect(error.time).toBe('2020-01-01T00:00:00.000Z'); + expect(error.type).toBe('validation'); + expect(error.level).toBe('error'); + expect(error.constructPath).toBe('MyStack'); + expect(error.constructInfo).toMatchObject({ + // fqns are different when run from compiled JS (first) and dynamically from TS (second) + fqn: expect.stringMatching(/aws-cdk-lib\.Stack|constructs\.Construct/), + version: expect.stringMatching(/^\d+\.\d+\.\d+$/), + }); + expect(error.message).toBe('this is an error'); + expect(error.stack).toContain('ValidationError: this is an error'); + expect(error.stack).toContain('at path [MyStack] in'); + }); +}); From e9c6e23ec49405c2f24b7a78ffb427dff6b72822 Mon Sep 17 00:00:00 2001 From: Kazuho Cryer-Shinozuka Date: Mon, 9 Dec 2024 23:06:17 +0900 Subject: [PATCH 6/7] fix(elasticloadbalancingv2): cannot create UDP listener for dual-stack NLB (#32184) ### Issue # (if applicable) None ### Reason for this change NetworkListener has the validation that it does not create UDP listeners for dual-stack NLB. However, dual-stack NLB now supports the creation of UDP listeners, and this validation is no longer required. ### Description of changes - Remove this validation from NetworkListener class. ```ts if ( props.loadBalancer.ipAddressType === IpAddressType.DUAL_STACK && (props.protocol === Protocol.UDP || props.protocol === Protocol.TCP_UDP) ) { throw new Error('UDP or TCP_UDP listeners cannot be added to a dualstack network load balancer.'); } ``` - Add `enablePrefixIpv6SourceNat` to the `NetworkLoadbalancerProps` - It is essential to enable this parameter for UDP listener with dual-stack NLB. - ref: https://github.com/aws/aws-cdk/pull/32184#issuecomment-2510536270 ### Description of how you validated changes Add both unit and integ tests. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...NlbEnablePrefixForIpv6NatStack.assets.json | 19 + ...bEnablePrefixForIpv6NatStack.template.json | 707 ++++++++++ ...efaultTestDeployAssert4C17D694.assets.json | 19 + ...aultTestDeployAssert4C17D694.template.json | 36 + .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 311 +++++ .../tree.json | 1134 +++++++++++++++++ .../integ.nlb-enable-prefix-for-ipv6-nat.ts | 73 ++ .../aws-elasticloadbalancingv2/README.md | 19 +- .../lib/nlb/network-listener.ts | 9 +- .../lib/nlb/network-load-balancer.ts | 22 +- .../test/nlb/load-balancer.test.ts | 47 +- 13 files changed, 2380 insertions(+), 29 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStack.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStack.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStack.assets.json new file mode 100644 index 0000000000000..34d0c4649041f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStack.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "fa46958bcb246c27c21906c9bf41a44bce7f9613a3d90335588eedc4daeb49dd": { + "source": { + "path": "NlbEnablePrefixForIpv6NatStack.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "fa46958bcb246c27c21906c9bf41a44bce7f9613a3d90335588eedc4daeb49dd.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStack.template.json new file mode 100644 index 0000000000000..a5031e0a2dafc --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStack.template.json @@ -0,0 +1,707 @@ +{ + "Resources": { + "Vpc8378EB38": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "NlbEnablePrefixForIpv6NatStack/Vpc" + } + ] + } + }, + "Vpcipv6cidr40D3CB78": { + "Type": "AWS::EC2::VPCCidrBlock", + "Properties": { + "AmazonProvidedIpv6CidrBlock": true, + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "VpcPublicSubnet1Subnet5C2D37C4": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AssignIpv6AddressOnCreation": true, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.0.0/18", + "Ipv6CidrBlock": { + "Fn::Select": [ + 0, + { + "Fn::Cidr": [ + { + "Fn::Select": [ + 0, + { + "Fn::GetAtt": [ + "Vpc8378EB38", + "Ipv6CidrBlocks" + ] + } + ] + }, + 4, + "64" + ] + } + ] + }, + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcPublicSubnet1RouteTable6C95E38E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcPublicSubnet1RouteTableAssociation97140677": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcPublicSubnet1DefaultRoute3DA9E72A": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + }, + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78", + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet1DefaultRoute6A21265FB": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationIpv6CidrBlock": "::/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + }, + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcPublicSubnet2Subnet691E08A3": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AssignIpv6AddressOnCreation": true, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.64.0/18", + "Ipv6CidrBlock": { + "Fn::Select": [ + 1, + { + "Fn::Cidr": [ + { + "Fn::Select": [ + 0, + { + "Fn::GetAtt": [ + "Vpc8378EB38", + "Ipv6CidrBlocks" + ] + } + ] + }, + 4, + "64" + ] + } + ] + }, + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcPublicSubnet2RouteTable94F7E489": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcPublicSubnet2RouteTableAssociationDD5762D8": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcPublicSubnet2DefaultRoute97F91067": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + }, + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78", + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet2DefaultRoute63E63096C": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationIpv6CidrBlock": "::/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + }, + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcIsolatedSubnet1SubnetE48C5737": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AssignIpv6AddressOnCreation": true, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.128.0/18", + "Ipv6CidrBlock": { + "Fn::Select": [ + 2, + { + "Fn::Cidr": [ + { + "Fn::Select": [ + 0, + { + "Fn::GetAtt": [ + "Vpc8378EB38", + "Ipv6CidrBlocks" + ] + } + ] + }, + 4, + "64" + ] + } + ] + }, + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Isolated" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Isolated" + }, + { + "Key": "Name", + "Value": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcIsolatedSubnet1RouteTable4771E3E5": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcIsolatedSubnet1RouteTableAssociationD300FCBB": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcIsolatedSubnet1RouteTable4771E3E5" + }, + "SubnetId": { + "Ref": "VpcIsolatedSubnet1SubnetE48C5737" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcIsolatedSubnet2Subnet16364B91": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AssignIpv6AddressOnCreation": true, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.192.0/18", + "Ipv6CidrBlock": { + "Fn::Select": [ + 3, + { + "Fn::Cidr": [ + { + "Fn::Select": [ + 0, + { + "Fn::GetAtt": [ + "Vpc8378EB38", + "Ipv6CidrBlocks" + ] + } + ] + }, + 4, + "64" + ] + } + ] + }, + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Isolated" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Isolated" + }, + { + "Key": "Name", + "Value": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet2" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcIsolatedSubnet2RouteTable1D30AF7D": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet2" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcIsolatedSubnet2RouteTableAssociationF7B18CCA": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcIsolatedSubnet2RouteTable1D30AF7D" + }, + "SubnetId": { + "Ref": "VpcIsolatedSubnet2Subnet16364B91" + } + }, + "DependsOn": [ + "Vpcipv6cidr40D3CB78" + ] + }, + "VpcIGWD7BA715C": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "NlbEnablePrefixForIpv6NatStack/Vpc" + } + ] + } + }, + "VpcVPCGWBF912B6E": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "InternetGatewayId": { + "Ref": "VpcIGWD7BA715C" + }, + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "VpcEIGW61416F369": { + "Type": "AWS::EC2::EgressOnlyInternetGateway", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "DisabledLbSgB7154DC8": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "NlbEnablePrefixForIpv6NatStack/DisabledLbSg", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "DisabledLbF70482DB": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "EnablePrefixForIpv6SourceNat": "off", + "IpAddressType": "dualstack", + "LoadBalancerAttributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "false" + } + ], + "Scheme": "internet-facing", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "DisabledLbSgB7154DC8", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + ], + "Type": "network" + }, + "DependsOn": [ + "VpcPublicSubnet1DefaultRoute3DA9E72A", + "VpcPublicSubnet1DefaultRoute6A21265FB", + "VpcPublicSubnet1RouteTableAssociation97140677", + "VpcPublicSubnet2DefaultRoute97F91067", + "VpcPublicSubnet2DefaultRoute63E63096C", + "VpcPublicSubnet2RouteTableAssociationDD5762D8" + ] + }, + "DisabledLbTcpListener070B4D6E": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "TcpTargetGroupD98C5CDB" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "DisabledLbF70482DB" + }, + "Port": 1229, + "Protocol": "TCP" + } + }, + "TcpTargetGroupD98C5CDB": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "IpAddressType": "ipv6", + "Port": 1229, + "Protocol": "TCP", + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "EnabledLbSg11D53248": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "NlbEnablePrefixForIpv6NatStack/EnabledLbSg", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "EnabledLb9F3E8D30": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "EnablePrefixForIpv6SourceNat": "on", + "IpAddressType": "dualstack", + "LoadBalancerAttributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "false" + } + ], + "Scheme": "internet-facing", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "EnabledLbSg11D53248", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + ], + "Type": "network" + }, + "DependsOn": [ + "VpcPublicSubnet1DefaultRoute3DA9E72A", + "VpcPublicSubnet1DefaultRoute6A21265FB", + "VpcPublicSubnet1RouteTableAssociation97140677", + "VpcPublicSubnet2DefaultRoute97F91067", + "VpcPublicSubnet2DefaultRoute63E63096C", + "VpcPublicSubnet2RouteTableAssociationDD5762D8" + ] + }, + "EnabledLbUdpListener550E1122": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "UdpTargetGroup5F89FEC0" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "EnabledLb9F3E8D30" + }, + "Port": 1229, + "Protocol": "UDP" + } + }, + "EnabledLbTcpWithUdpListenerBBFA335D": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "TcpWithUdpTargetGroup827EE6D7" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "EnabledLb9F3E8D30" + }, + "Port": 3502, + "Protocol": "TCP_UDP" + } + }, + "UdpTargetGroup5F89FEC0": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "IpAddressType": "ipv6", + "Port": 1229, + "Protocol": "UDP", + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "TcpWithUdpTargetGroup827EE6D7": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "IpAddressType": "ipv6", + "Port": 3502, + "Protocol": "TCP_UDP", + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.assets.json new file mode 100644 index 0000000000000..a47c44feab324 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/cdk.out new file mode 100644 index 0000000000000..c6e612584e352 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/integ.json new file mode 100644 index 0000000000000..2512b45a69413 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "38.0.1", + "testCases": { + "NlbEnablePrefixForIpv6NatStackTest/DefaultTest": { + "stacks": [ + "NlbEnablePrefixForIpv6NatStack" + ], + "assertionStack": "NlbEnablePrefixForIpv6NatStackTest/DefaultTest/DeployAssert", + "assertionStackName": "NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/manifest.json new file mode 100644 index 0000000000000..c9ae9e3d676a6 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/manifest.json @@ -0,0 +1,311 @@ +{ + "version": "38.0.1", + "artifacts": { + "NlbEnablePrefixForIpv6NatStack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "NlbEnablePrefixForIpv6NatStack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "NlbEnablePrefixForIpv6NatStack": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "NlbEnablePrefixForIpv6NatStack.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/fa46958bcb246c27c21906c9bf41a44bce7f9613a3d90335588eedc4daeb49dd.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "NlbEnablePrefixForIpv6NatStack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "NlbEnablePrefixForIpv6NatStack.assets" + ], + "metadata": { + "/NlbEnablePrefixForIpv6NatStack/Vpc/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Vpc8378EB38" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/ipv6cidr": [ + { + "type": "aws:cdk:logicalId", + "data": "Vpcipv6cidr40D3CB78" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet1Subnet5C2D37C4" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet1RouteTable6C95E38E" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet1RouteTableAssociation97140677" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet1DefaultRoute3DA9E72A" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1/DefaultRoute6": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet1DefaultRoute6A21265FB" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet2Subnet691E08A3" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet2RouteTable94F7E489" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet2RouteTableAssociationDD5762D8" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet2DefaultRoute97F91067" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2/DefaultRoute6": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcPublicSubnet2DefaultRoute63E63096C" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcIsolatedSubnet1SubnetE48C5737" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcIsolatedSubnet1RouteTable4771E3E5" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcIsolatedSubnet1RouteTableAssociationD300FCBB" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcIsolatedSubnet2Subnet16364B91" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcIsolatedSubnet2RouteTable1D30AF7D" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcIsolatedSubnet2RouteTableAssociationF7B18CCA" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/IGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcIGWD7BA715C" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/VPCGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcVPCGWBF912B6E" + } + ], + "/NlbEnablePrefixForIpv6NatStack/Vpc/EIGW6": [ + { + "type": "aws:cdk:logicalId", + "data": "VpcEIGW61416F369" + } + ], + "/NlbEnablePrefixForIpv6NatStack/DisabledLbSg/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DisabledLbSgB7154DC8" + } + ], + "/NlbEnablePrefixForIpv6NatStack/DisabledLb/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DisabledLbF70482DB" + } + ], + "/NlbEnablePrefixForIpv6NatStack/DisabledLb/TcpListener/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "DisabledLbTcpListener070B4D6E" + } + ], + "/NlbEnablePrefixForIpv6NatStack/TcpTargetGroup": [ + { + "type": "aws:cdk:warning", + "data": "When creating an empty TargetGroup, you should specify a 'targetType' (this warning may become an error in the future). [ack: @aws-cdk/aws-elbv2:targetGroupSpecifyTargetTypeForEmptyTargetGroup]" + } + ], + "/NlbEnablePrefixForIpv6NatStack/TcpTargetGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TcpTargetGroupD98C5CDB" + } + ], + "/NlbEnablePrefixForIpv6NatStack/EnabledLbSg/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "EnabledLbSg11D53248" + } + ], + "/NlbEnablePrefixForIpv6NatStack/EnabledLb/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "EnabledLb9F3E8D30" + } + ], + "/NlbEnablePrefixForIpv6NatStack/EnabledLb/UdpListener/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "EnabledLbUdpListener550E1122" + } + ], + "/NlbEnablePrefixForIpv6NatStack/EnabledLb/TcpWithUdpListener/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "EnabledLbTcpWithUdpListenerBBFA335D" + } + ], + "/NlbEnablePrefixForIpv6NatStack/UdpTargetGroup": [ + { + "type": "aws:cdk:warning", + "data": "When creating an empty TargetGroup, you should specify a 'targetType' (this warning may become an error in the future). [ack: @aws-cdk/aws-elbv2:targetGroupSpecifyTargetTypeForEmptyTargetGroup]" + } + ], + "/NlbEnablePrefixForIpv6NatStack/UdpTargetGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "UdpTargetGroup5F89FEC0" + } + ], + "/NlbEnablePrefixForIpv6NatStack/TcpWithUdpTargetGroup": [ + { + "type": "aws:cdk:warning", + "data": "When creating an empty TargetGroup, you should specify a 'targetType' (this warning may become an error in the future). [ack: @aws-cdk/aws-elbv2:targetGroupSpecifyTargetTypeForEmptyTargetGroup]" + } + ], + "/NlbEnablePrefixForIpv6NatStack/TcpWithUdpTargetGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TcpWithUdpTargetGroup827EE6D7" + } + ], + "/NlbEnablePrefixForIpv6NatStack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/NlbEnablePrefixForIpv6NatStack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "NlbEnablePrefixForIpv6NatStack" + }, + "NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "NlbEnablePrefixForIpv6NatStackTestDefaultTestDeployAssert4C17D694.assets" + ], + "metadata": { + "/NlbEnablePrefixForIpv6NatStackTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/NlbEnablePrefixForIpv6NatStackTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "NlbEnablePrefixForIpv6NatStackTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/tree.json new file mode 100644 index 0000000000000..75cb2ae8bbbe6 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.js.snapshot/tree.json @@ -0,0 +1,1134 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "NlbEnablePrefixForIpv6NatStack": { + "id": "NlbEnablePrefixForIpv6NatStack", + "path": "NlbEnablePrefixForIpv6NatStack", + "children": { + "Vpc": { + "id": "Vpc", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc", + "children": { + "Resource": { + "id": "Resource", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.0.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default", + "tags": [ + { + "key": "Name", + "value": "NlbEnablePrefixForIpv6NatStack/Vpc" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "ipv6cidr": { + "id": "ipv6cidr", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/ipv6cidr", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCCidrBlock", + "aws:cdk:cloudformation:props": { + "amazonProvidedIpv6CidrBlock": true, + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "PublicSubnet1": { + "id": "PublicSubnet1", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "assignIpv6AddressOnCreation": true, + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.0.0/18", + "ipv6CidrBlock": { + "Fn::Select": [ + 0, + { + "Fn::Cidr": [ + { + "Fn::Select": [ + 0, + { + "Fn::GetAtt": [ + "Vpc8378EB38", + "Ipv6CidrBlocks" + ] + } + ] + }, + 4, + "64" + ] + } + ] + }, + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "Acl": { + "id": "Acl", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1/Acl", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "subnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VpcIGWD7BA715C" + }, + "routeTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "DefaultRoute6": { + "id": "DefaultRoute6", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet1/DefaultRoute6", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationIpv6CidrBlock": "::/0", + "gatewayId": { + "Ref": "VpcIGWD7BA715C" + }, + "routeTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "PublicSubnet2": { + "id": "PublicSubnet2", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "assignIpv6AddressOnCreation": true, + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.64.0/18", + "ipv6CidrBlock": { + "Fn::Select": [ + 1, + { + "Fn::Cidr": [ + { + "Fn::Select": [ + 0, + { + "Fn::GetAtt": [ + "Vpc8378EB38", + "Ipv6CidrBlocks" + ] + } + ] + }, + 4, + "64" + ] + } + ] + }, + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "Acl": { + "id": "Acl", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2/Acl", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "subnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VpcIGWD7BA715C" + }, + "routeTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "DefaultRoute6": { + "id": "DefaultRoute6", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/PublicSubnet2/DefaultRoute6", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationIpv6CidrBlock": "::/0", + "gatewayId": { + "Ref": "VpcIGWD7BA715C" + }, + "routeTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "IsolatedSubnet1": { + "id": "IsolatedSubnet1", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "assignIpv6AddressOnCreation": true, + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.128.0/18", + "ipv6CidrBlock": { + "Fn::Select": [ + 2, + { + "Fn::Cidr": [ + { + "Fn::Select": [ + 0, + { + "Fn::GetAtt": [ + "Vpc8378EB38", + "Ipv6CidrBlocks" + ] + } + ] + }, + 4, + "64" + ] + } + ] + }, + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Isolated" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Isolated" + }, + { + "key": "Name", + "value": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "Acl": { + "id": "Acl", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet1/Acl", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VpcIsolatedSubnet1RouteTable4771E3E5" + }, + "subnetId": { + "Ref": "VpcIsolatedSubnet1SubnetE48C5737" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "IsolatedSubnet2": { + "id": "IsolatedSubnet2", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "assignIpv6AddressOnCreation": true, + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.192.0/18", + "ipv6CidrBlock": { + "Fn::Select": [ + 3, + { + "Fn::Cidr": [ + { + "Fn::Select": [ + 0, + { + "Fn::GetAtt": [ + "Vpc8378EB38", + "Ipv6CidrBlocks" + ] + } + ] + }, + 4, + "64" + ] + } + ] + }, + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Isolated" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Isolated" + }, + { + "key": "Name", + "value": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet2" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "Acl": { + "id": "Acl", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet2/Acl", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet2" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/IsolatedSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VpcIsolatedSubnet2RouteTable1D30AF7D" + }, + "subnetId": { + "Ref": "VpcIsolatedSubnet2Subnet16364B91" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "IGW": { + "id": "IGW", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/IGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "NlbEnablePrefixForIpv6NatStack/Vpc" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "VPCGW": { + "id": "VPCGW", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/VPCGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", + "aws:cdk:cloudformation:props": { + "internetGatewayId": { + "Ref": "VpcIGWD7BA715C" + }, + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "EIGW6": { + "id": "EIGW6", + "path": "NlbEnablePrefixForIpv6NatStack/Vpc/EIGW6", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EgressOnlyInternetGateway", + "aws:cdk:cloudformation:props": { + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "DisabledLbSg": { + "id": "DisabledLbSg", + "path": "NlbEnablePrefixForIpv6NatStack/DisabledLbSg", + "children": { + "Resource": { + "id": "Resource", + "path": "NlbEnablePrefixForIpv6NatStack/DisabledLbSg/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "NlbEnablePrefixForIpv6NatStack/DisabledLbSg", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "DisabledLb": { + "id": "DisabledLb", + "path": "NlbEnablePrefixForIpv6NatStack/DisabledLb", + "children": { + "Resource": { + "id": "Resource", + "path": "NlbEnablePrefixForIpv6NatStack/DisabledLb/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "aws:cdk:cloudformation:props": { + "enablePrefixForIpv6SourceNat": "off", + "ipAddressType": "dualstack", + "loadBalancerAttributes": [ + { + "key": "deletion_protection.enabled", + "value": "false" + } + ], + "scheme": "internet-facing", + "securityGroups": [ + { + "Fn::GetAtt": [ + "DisabledLbSgB7154DC8", + "GroupId" + ] + } + ], + "subnets": [ + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + ], + "type": "network" + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "TcpListener": { + "id": "TcpListener", + "path": "NlbEnablePrefixForIpv6NatStack/DisabledLb/TcpListener", + "children": { + "Resource": { + "id": "Resource", + "path": "NlbEnablePrefixForIpv6NatStack/DisabledLb/TcpListener/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::Listener", + "aws:cdk:cloudformation:props": { + "defaultActions": [ + { + "type": "forward", + "targetGroupArn": { + "Ref": "TcpTargetGroupD98C5CDB" + } + } + ], + "loadBalancerArn": { + "Ref": "DisabledLbF70482DB" + }, + "port": 1229, + "protocol": "TCP" + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "TcpTargetGroup": { + "id": "TcpTargetGroup", + "path": "NlbEnablePrefixForIpv6NatStack/TcpTargetGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "NlbEnablePrefixForIpv6NatStack/TcpTargetGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "aws:cdk:cloudformation:props": { + "ipAddressType": "ipv6", + "port": 1229, + "protocol": "TCP", + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "EnabledLbSg": { + "id": "EnabledLbSg", + "path": "NlbEnablePrefixForIpv6NatStack/EnabledLbSg", + "children": { + "Resource": { + "id": "Resource", + "path": "NlbEnablePrefixForIpv6NatStack/EnabledLbSg/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "NlbEnablePrefixForIpv6NatStack/EnabledLbSg", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "EnabledLb": { + "id": "EnabledLb", + "path": "NlbEnablePrefixForIpv6NatStack/EnabledLb", + "children": { + "Resource": { + "id": "Resource", + "path": "NlbEnablePrefixForIpv6NatStack/EnabledLb/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "aws:cdk:cloudformation:props": { + "enablePrefixForIpv6SourceNat": "on", + "ipAddressType": "dualstack", + "loadBalancerAttributes": [ + { + "key": "deletion_protection.enabled", + "value": "false" + } + ], + "scheme": "internet-facing", + "securityGroups": [ + { + "Fn::GetAtt": [ + "EnabledLbSg11D53248", + "GroupId" + ] + } + ], + "subnets": [ + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + ], + "type": "network" + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "UdpListener": { + "id": "UdpListener", + "path": "NlbEnablePrefixForIpv6NatStack/EnabledLb/UdpListener", + "children": { + "Resource": { + "id": "Resource", + "path": "NlbEnablePrefixForIpv6NatStack/EnabledLb/UdpListener/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::Listener", + "aws:cdk:cloudformation:props": { + "defaultActions": [ + { + "type": "forward", + "targetGroupArn": { + "Ref": "UdpTargetGroup5F89FEC0" + } + } + ], + "loadBalancerArn": { + "Ref": "EnabledLb9F3E8D30" + }, + "port": 1229, + "protocol": "UDP" + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "TcpWithUdpListener": { + "id": "TcpWithUdpListener", + "path": "NlbEnablePrefixForIpv6NatStack/EnabledLb/TcpWithUdpListener", + "children": { + "Resource": { + "id": "Resource", + "path": "NlbEnablePrefixForIpv6NatStack/EnabledLb/TcpWithUdpListener/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::Listener", + "aws:cdk:cloudformation:props": { + "defaultActions": [ + { + "type": "forward", + "targetGroupArn": { + "Ref": "TcpWithUdpTargetGroup827EE6D7" + } + } + ], + "loadBalancerArn": { + "Ref": "EnabledLb9F3E8D30" + }, + "port": 3502, + "protocol": "TCP_UDP" + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "UdpTargetGroup": { + "id": "UdpTargetGroup", + "path": "NlbEnablePrefixForIpv6NatStack/UdpTargetGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "NlbEnablePrefixForIpv6NatStack/UdpTargetGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "aws:cdk:cloudformation:props": { + "ipAddressType": "ipv6", + "port": 1229, + "protocol": "UDP", + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "TcpWithUdpTargetGroup": { + "id": "TcpWithUdpTargetGroup", + "path": "NlbEnablePrefixForIpv6NatStack/TcpWithUdpTargetGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "NlbEnablePrefixForIpv6NatStack/TcpWithUdpTargetGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "aws:cdk:cloudformation:props": { + "ipAddressType": "ipv6", + "port": 3502, + "protocol": "TCP_UDP", + "vpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "NlbEnablePrefixForIpv6NatStack/BootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "NlbEnablePrefixForIpv6NatStack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "NlbEnablePrefixForIpv6NatStackTest": { + "id": "NlbEnablePrefixForIpv6NatStackTest", + "path": "NlbEnablePrefixForIpv6NatStackTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "NlbEnablePrefixForIpv6NatStackTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "NlbEnablePrefixForIpv6NatStackTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "NlbEnablePrefixForIpv6NatStackTest/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "NlbEnablePrefixForIpv6NatStackTest/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "NlbEnablePrefixForIpv6NatStackTest/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.ts new file mode 100644 index 0000000000000..f33dcb18f61b5 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.nlb-enable-prefix-for-ipv6-nat.ts @@ -0,0 +1,73 @@ +import * as ec2 from 'aws-cdk-lib/aws-ec2'; +import * as cdk from 'aws-cdk-lib'; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'NlbEnablePrefixForIpv6NatStack'); + +const vpc = new ec2.Vpc(stack, 'Vpc', { + restrictDefaultSecurityGroup: false, + maxAzs: 2, + ipProtocol: ec2.IpProtocol.DUAL_STACK, + natGateways: 0, +}); + +const disabledNlb = new elbv2.NetworkLoadBalancer(stack, 'DisabledLb', { + vpc, + internetFacing: true, + securityGroups: [ + new ec2.SecurityGroup(stack, 'DisabledLbSg', { vpc }), + ], + enablePrefixForIpv6SourceNat: false, + ipAddressType: elbv2.IpAddressType.DUAL_STACK, +}); + +const tcpListener = disabledNlb.addListener('TcpListener', { + port: 1229, + protocol: elbv2.Protocol.TCP, +}); +const tcpTargetGroup = new elbv2.NetworkTargetGroup(stack, 'TcpTargetGroup', { + vpc, + port: 1229, + protocol: elbv2.Protocol.TCP, + ipAddressType: elbv2.TargetGroupIpAddressType.IPV6, +}); +tcpListener.addTargetGroups('TcpTargetGroup', tcpTargetGroup); + +const enabledNlb = new elbv2.NetworkLoadBalancer(stack, 'EnabledLb', { + vpc, + internetFacing: true, + securityGroups: [ + new ec2.SecurityGroup(stack, 'EnabledLbSg', { vpc }), + ], + ipAddressType: elbv2.IpAddressType.DUAL_STACK, + enablePrefixForIpv6SourceNat: true, +}); +const udpListener = enabledNlb.addListener('UdpListener', { + port: 1229, + protocol: elbv2.Protocol.UDP, +}); +const udpTargetGroup = new elbv2.NetworkTargetGroup(stack, 'UdpTargetGroup', { + vpc, + port: 1229, + protocol: elbv2.Protocol.UDP, + ipAddressType: elbv2.TargetGroupIpAddressType.IPV6, +}); +udpListener.addTargetGroups('TargetGroup', udpTargetGroup); + +const tcpWithUdpListener = enabledNlb.addListener('TcpWithUdpListener', { + port: 3502, + protocol: elbv2.Protocol.TCP_UDP, +}); +const tcpWithUdpTargetGroup = new elbv2.NetworkTargetGroup(stack, 'TcpWithUdpTargetGroup', { + vpc, + port: 3502, + protocol: elbv2.Protocol.TCP_UDP, + ipAddressType: elbv2.TargetGroupIpAddressType.IPV6, +}); +tcpWithUdpListener.addTargetGroups('TcpWithUdpTargetGroup', tcpWithUdpTargetGroup); + +new integ.IntegTest(app, 'NlbEnablePrefixForIpv6NatStackTest', { + testCases: [stack], +}); diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/README.md b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/README.md index 2d839918f3cb8..f55effba63631 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/README.md +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/README.md @@ -366,7 +366,6 @@ and [Register targets with your Target Group](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/target-group-register-targets.html) for more information. - ### Dualstack Network Load Balancer You can create a dualstack Network Load Balancer using the `ipAddressType` property: @@ -380,7 +379,23 @@ const lb = new elbv2.NetworkLoadBalancer(this, 'LB', { }); ``` -You cannot add UDP or TCP_UDP listeners to a dualstack Network Load Balancer. +You can configure whether to use an IPv6 prefix from each subnet for source NAT by setting `enablePrefixForIpv6SourceNat` to `true`. +This must be enabled if you want to create a dualstack Network Load Balancer with a listener that uses UDP protocol. + +```ts +declare const vpc: ec2.Vpc; + +const lb = new elbv2.NetworkLoadBalancer(this, 'LB', { + vpc, + ipAddressType: elbv2.IpAddressType.DUAL_STACK, + enablePrefixForIpv6SourceNat: true, +}); + +const listener = lb.addListener('Listener', { + port: 1229, + protocol: elbv2.Protocol.UDP, +}); +``` ### Network Load Balancer attributes diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts index 6ef0e006e088f..6b97718474c21 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/nlb/network-listener.ts @@ -7,7 +7,7 @@ import * as cxschema from '../../../cloud-assembly-schema'; import { Duration, Resource, Lazy, Token } from '../../../core'; import { BaseListener, BaseListenerLookupOptions, IListener } from '../shared/base-listener'; import { HealthCheck } from '../shared/base-target-group'; -import { AlpnPolicy, IpAddressType, Protocol, SslPolicy } from '../shared/enums'; +import { AlpnPolicy, Protocol, SslPolicy } from '../shared/enums'; import { IListenerCertificate } from '../shared/listener-certificate'; import { validateNetworkProtocol } from '../shared/util'; @@ -195,13 +195,6 @@ export class NetworkListener extends BaseListener implements INetworkListener { throw new Error('Protocol must be TLS when alpnPolicy have been specified'); } - if ( - props.loadBalancer.ipAddressType === IpAddressType.DUAL_STACK && - (props.protocol === Protocol.UDP || props.protocol === Protocol.TCP_UDP) - ) { - throw new Error('UDP or TCP_UDP listeners cannot be added to a dualstack network load balancer.'); - } - super(scope, id, { loadBalancerArn: props.loadBalancer.loadBalancerArn, protocol: proto, diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts index a9284e8160d58..7a485b102155e 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/nlb/network-load-balancer.ts @@ -7,7 +7,7 @@ import { Lazy, Resource } from '../../../core'; import * as cxapi from '../../../cx-api'; import { NetworkELBMetrics } from '../elasticloadbalancingv2-canned-metrics.generated'; import { BaseLoadBalancer, BaseLoadBalancerLookupOptions, BaseLoadBalancerProps, ILoadBalancerV2 } from '../shared/base-load-balancer'; -import { IpAddressType } from '../shared/enums'; +import { IpAddressType, Protocol } from '../shared/enums'; import { parseLoadBalancerFullName } from '../shared/util'; /** @@ -75,6 +75,15 @@ export interface NetworkLoadBalancerProps extends BaseLoadBalancerProps { * @default false */ readonly zonalShift?: boolean; + + /** + * Indicates whether to use an IPv6 prefix from each subnet for source NAT. + * + * The IP address type must be IpAddressType.DUALSTACK. + * + * @default undefined - NLB default behavior is false + */ + readonly enablePrefixForIpv6SourceNat?: boolean; } /** @@ -241,6 +250,7 @@ export class NetworkLoadBalancer extends BaseLoadBalancer implements INetworkLoa public readonly connections: ec2.Connections; private readonly isSecurityGroupsPropertyDefined: boolean; private readonly _enforceSecurityGroupInboundRulesOnPrivateLinkTraffic?: boolean; + private enablePrefixForIpv6SourceNat?: boolean; /** * After the implementation of `IConnectable` (see https://github.com/aws/aws-cdk/pull/28494), the default @@ -262,8 +272,10 @@ export class NetworkLoadBalancer extends BaseLoadBalancer implements INetworkLoa enforceSecurityGroupInboundRulesOnPrivateLinkTraffic: Lazy.string({ produce: () => this.enforceSecurityGroupInboundRulesOnPrivateLinkTraffic, }), + enablePrefixForIpv6SourceNat: props.enablePrefixForIpv6SourceNat === true ? 'on': props.enablePrefixForIpv6SourceNat === false ? 'off' : undefined, }); + this.enablePrefixForIpv6SourceNat = props.enablePrefixForIpv6SourceNat; this.metrics = new NetworkLoadBalancerMetrics(this, this.loadBalancerFullName); this.isSecurityGroupsPropertyDefined = !!props.securityGroups; this.connections = new ec2.Connections({ securityGroups: props.securityGroups }); @@ -288,6 +300,14 @@ export class NetworkLoadBalancer extends BaseLoadBalancer implements INetworkLoa * @returns The newly created listener */ public addListener(id: string, props: BaseNetworkListenerProps): NetworkListener { + // UDP listener with dual stack NLB requires prefix IPv6 source NAT to be enabled + if ( + (props.protocol === Protocol.UDP || props.protocol === Protocol.TCP_UDP) && + (this.ipAddressType === IpAddressType.DUAL_STACK || this.ipAddressType === IpAddressType.DUAL_STACK_WITHOUT_PUBLIC_IPV4) && + this.enablePrefixForIpv6SourceNat !== true + ) { + throw new Error('To add a listener with UDP protocol to a dual stack NLB, \'enablePrefixForIpv6SourceNat\' must be set to true.'); + } return new NetworkListener(this, id, { loadBalancer: this, ...props, diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/nlb/load-balancer.test.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/nlb/load-balancer.test.ts index 6681443c6b1a9..1e0e6d602e23c 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/nlb/load-balancer.test.ts +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/nlb/load-balancer.test.ts @@ -1135,40 +1135,51 @@ describe('tests', () => { IpAddressType: 'dualstack', }); }); + }); - test('Cannot add UDP or TCP_UDP listeners to a dualstack network load balancer', () => { + describe('enable prefix for ipv6 source nat', () => { + test.each([ + { config: true, value: 'on' }, + { config: false, value: 'off' }, + ])('specify EnablePrefixForIpv6SourceNat', ({ config, value }) => { // GIVEN const stack = new cdk.Stack(); const vpc = new ec2.Vpc(stack, 'Stack'); // WHEN - const loadBalancer = new elbv2.NetworkLoadBalancer(stack, 'LB', { + new elbv2.NetworkLoadBalancer(stack, 'Lb', { vpc, - internetFacing: true, + enablePrefixForIpv6SourceNat: config, ipAddressType: elbv2.IpAddressType.DUAL_STACK, }); - const targetGroup = new elbv2.NetworkTargetGroup(stack, 'tg', { - vpc: loadBalancer.vpc, - port: 3000, + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ElasticLoadBalancingV2::LoadBalancer', { + Scheme: 'internal', + Type: 'network', + IpAddressType: 'dualstack', + EnablePrefixForIpv6SourceNat: value, + }); + }); + + test.each([false, undefined])('throw error for disabling `enablePrefixForIpv6SourceNat` and add UDP listener', (enablePrefixForIpv6SourceNat) => { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'Stack'); + const lb = new elbv2.NetworkLoadBalancer(stack, 'Lb', { + vpc, + ipAddressType: elbv2.IpAddressType.DUAL_STACK, + enablePrefixForIpv6SourceNat, }); // THEN expect(() => { - loadBalancer.addListener('listener', { + lb.addListener('Listener', { + port: 80, protocol: elbv2.Protocol.UDP, - port: 3000, - defaultAction: elbv2.NetworkListenerAction.forward([targetGroup]), - }); - }).toThrow(/UDP or TCP_UDP listeners cannot be added to a dualstack network load balancer/); - - expect(() => { - loadBalancer.addListener('listener', { - protocol: elbv2.Protocol.TCP_UDP, - port: 3000, - defaultAction: elbv2.NetworkListenerAction.forward([targetGroup]), + defaultTargetGroups: [new elbv2.NetworkTargetGroup(stack, 'Group', { vpc, port: 80 })], }); - }).toThrow(/UDP or TCP_UDP listeners cannot be added to a dualstack network load balancer/); + }).toThrow('To add a listener with UDP protocol to a dual stack NLB, \'enablePrefixForIpv6SourceNat\' must be set to true.'); }); }); From 093c54042acff6e362e6cf7eb30254f879b94966 Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Mon, 9 Dec 2024 06:53:36 -0800 Subject: [PATCH 7/7] feat: update L1 CloudFormation resource definitions (#32446) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates the L1 CloudFormation resource definitions with the latest changes from `@aws-cdk/aws-service-spec` **L1 CloudFormation resource definition changes:** ``` ├[~] service aws-amazonmq │ └ resources │ └[~] resource AWS::AmazonMQ::Configuration │ └ properties │ └ Data: - string (required) │ + string ├[~] service aws-apigateway │ └ resources │ ├[~] resource AWS::ApiGateway::BasePathMapping │ │ └ - documentation: The `AWS::ApiGateway::BasePathMapping` resource creates a base path that clients who call your API must use in the invocation URL. │ │ + documentation: The `AWS::ApiGateway::BasePathMapping` resource creates a base path that clients who call your API must use in the invocation URL. Supported only for public custom domain names. │ ├[~] resource AWS::ApiGateway::BasePathMappingV2 │ │ ├ - documentation: Resource Type definition for AWS::ApiGateway::BasePathMappingV2 │ │ │ + documentation: The `AWS::ApiGateway::BasePathMappingV2` resource creates a base path that clients who call your API must use in the invocation URL. Supported only for private custom domain names. │ │ └ properties │ │ ├ BasePath: (documentation changed) │ │ ├ DomainNameArn: (documentation changed) │ │ ├ RestApiId: (documentation changed) │ │ └ Stage: (documentation changed) │ ├[~] resource AWS::ApiGateway::DomainName │ │ ├ - documentation: The `AWS::ApiGateway::DomainName` resource specifies a custom domain name for your API in API Gateway. │ │ │ You can use a custom domain name to provide a URL that's more intuitive and easier to recall. For more information about using custom domain names, see [Set up Custom Domain Name for an API in API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html) in the *API Gateway Developer Guide* . │ │ │ + documentation: The `AWS::ApiGateway::DomainName` resource specifies a public custom domain name for your API in API Gateway. │ │ │ You can use a custom domain name to provide a URL that's more intuitive and easier to recall. For more information about using custom domain names, see [Set up Custom Domain Name for an API in API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html) in the *API Gateway Developer Guide* . │ │ └ properties │ │ └ CertificateArn: (documentation changed) │ ├[~] resource AWS::ApiGateway::DomainNameAccessAssociation │ │ ├ - documentation: Resource Type definition for AWS::ApiGateway::DomainNameAccessAssociation. │ │ │ + documentation: The `AWS::ApiGateway::DomainNameAccessAssociation` resource creates a domain name access association between an access association source and a private custom domain name. │ │ │ Use a domain name access association to invoke a private custom domain name while isolated from the public internet. │ │ │ You can only create or delete a DomainNameAccessAssociation using CloudFormation. To reject a domain name access association, use the AWS CLI. │ │ ├ properties │ │ │ ├ AccessAssociationSource: (documentation changed) │ │ │ ├ AccessAssociationSourceType: (documentation changed) │ │ │ ├ DomainNameArn: (documentation changed) │ │ │ └ Tags: (documentation changed) │ │ └ attributes │ │ └ DomainNameAccessAssociationArn: (documentation changed) │ └[~] resource AWS::ApiGateway::DomainNameV2 │ ├ - documentation: Resource Type definition for AWS::ApiGateway::DomainNameV2. │ │ + documentation: The `AWS::ApiGateway::DomainNameV2` resource specifies a custom domain name for your private APIs in API Gateway. You can use a private custom domain name to provide a URL for your private API that's more intuitive and easier to recall. │ ├ properties │ │ ├ CertificateArn: (documentation changed) │ │ ├ DomainName: (documentation changed) │ │ ├ EndpointConfiguration: (documentation changed) │ │ ├ Policy: (documentation changed) │ │ ├ SecurityPolicy: (documentation changed) │ │ └ Tags: (documentation changed) │ ├ attributes │ │ ├ DomainNameArn: (documentation changed) │ │ └ DomainNameId: (documentation changed) │ └ types │ └[~] type EndpointConfiguration │ ├ - documentation: undefined │ │ + documentation: The endpoint configuration to indicate the types of endpoints an API (RestApi) or its custom domain name (DomainName) has. │ └ properties │ └ Types: (documentation changed) ├[~] service aws-applicationautoscaling │ └ resources │ └[~] resource AWS::ApplicationAutoScaling::ScalingPolicy │ ├ properties │ │ └ PredictiveScalingPolicyConfiguration: (documentation changed) │ └ types │ ├[~] type PredictiveScalingCustomizedCapacityMetric │ │ ├ - documentation: undefined │ │ │ + documentation: Represents a CloudWatch metric of your choosing for a predictive scaling policy. │ │ └ properties │ │ └ MetricDataQueries: (documentation changed) │ ├[~] type PredictiveScalingCustomizedLoadMetric │ │ └ - documentation: undefined │ │ + documentation: The customized load metric specification. │ ├[~] type PredictiveScalingCustomizedScalingMetric │ │ └ properties │ │ └ MetricDataQueries: (documentation changed) │ ├[~] type PredictiveScalingMetric │ │ ├ - documentation: undefined │ │ │ + documentation: Describes the scaling metric. │ │ └ properties │ │ └ Dimensions: (documentation changed) │ ├[~] type PredictiveScalingMetricDataQuery │ │ ├ - documentation: undefined │ │ │ + documentation: The metric data to return. Also defines whether this call is returning data for one metric only, or whether it is performing a math expression on the values of returned metric statistics to create a new time series. A time series is a series of data points, each of which is associated with a timestamp. │ │ └ properties │ │ ├ Expression: (documentation changed) │ │ ├ Id: (documentation changed) │ │ ├ MetricStat: (documentation changed) │ │ └ ReturnData: (documentation changed) │ ├[~] type PredictiveScalingMetricDimension │ │ └ - documentation: undefined │ │ + documentation: Describes the dimension of a metric. │ ├[~] type PredictiveScalingMetricSpecification │ │ ├ - documentation: undefined │ │ │ + documentation: This structure specifies the metrics and target utilization settings for a predictive scaling policy. │ │ │ You must specify either a metric pair, or a load metric and a scaling metric individually. Specifying a metric pair instead of individual metrics provides a simpler way to configure metrics for a scaling policy. You choose the metric pair, and the policy automatically knows the correct sum and average statistics to use for the load metric and the scaling metric. │ │ └ properties │ │ ├ CustomizedCapacityMetricSpecification: (documentation changed) │ │ ├ CustomizedLoadMetricSpecification: (documentation changed) │ │ ├ CustomizedScalingMetricSpecification: (documentation changed) │ │ ├ PredefinedLoadMetricSpecification: (documentation changed) │ │ ├ PredefinedMetricPairSpecification: (documentation changed) │ │ ├ PredefinedScalingMetricSpecification: (documentation changed) │ │ └ TargetValue: (documentation changed) │ ├[~] type PredictiveScalingMetricStat │ │ ├ - documentation: undefined │ │ │ + documentation: This structure defines the CloudWatch metric to return, along with the statistic and unit. │ │ └ properties │ │ ├ Metric: (documentation changed) │ │ ├ Stat: (documentation changed) │ │ └ Unit: (documentation changed) │ ├[~] type PredictiveScalingPolicyConfiguration │ │ ├ - documentation: undefined │ │ │ + documentation: Represents a predictive scaling policy configuration. │ │ └ properties │ │ ├ MaxCapacityBreachBehavior: (documentation changed) │ │ ├ MaxCapacityBuffer: (documentation changed) │ │ ├ MetricSpecifications: (documentation changed) │ │ ├ Mode: (documentation changed) │ │ └ SchedulingBufferTime: (documentation changed) │ ├[~] type PredictiveScalingPredefinedLoadMetric │ │ ├ - documentation: undefined │ │ │ + documentation: Describes a load metric for a predictive scaling policy. │ │ │ When returned in the output of `DescribePolicies` , it indicates that a predictive scaling policy uses individually specified load and scaling metrics instead of a metric pair. │ │ └ properties │ │ ├ PredefinedMetricType: (documentation changed) │ │ └ ResourceLabel: (documentation changed) │ ├[~] type PredictiveScalingPredefinedMetricPair │ │ ├ - documentation: undefined │ │ │ + documentation: Represents a metric pair for a predictive scaling policy. │ │ └ properties │ │ ├ PredefinedMetricType: (documentation changed) │ │ └ ResourceLabel: (documentation changed) │ └[~] type PredictiveScalingPredefinedScalingMetric │ ├ - documentation: undefined │ │ + documentation: Describes a scaling metric for a predictive scaling policy. │ │ When returned in the output of `DescribePolicies` , it indicates that a predictive scaling policy uses individually specified load and scaling metrics instead of a metric pair. │ └ properties │ ├ PredefinedMetricType: (documentation changed) │ └ ResourceLabel: (documentation changed) ├[~] service aws-appsync │ └ resources │ └[~] resource AWS::AppSync::DataSource │ └ properties │ └ Type: (documentation changed) ├[~] service aws-autoscaling │ └ resources │ └[~] resource AWS::AutoScaling::ScalingPolicy │ └ types │ ├[~] type CustomizedMetricSpecification │ │ └ properties │ │ └ Period: (documentation changed) │ ├[~] type TargetTrackingMetricDataQuery │ │ └ properties │ │ └ Period: (documentation changed) │ └[~] type TargetTrackingMetricStat │ └ properties │ └ Period: (documentation changed) ├[~] service aws-bedrock │ └ resources │ ├[~] resource AWS::Bedrock::Agent │ │ └ types │ │ ├[~] type ActionGroupExecutor │ │ │ └ properties │ │ │ └ CustomControl: (documentation changed) │ │ ├[~] type AgentActionGroup │ │ │ ├ - documentation: Contains details about an action group. │ │ │ │ + documentation: Contains details of the inline agent's action group. │ │ │ └ properties │ │ │ ├ ApiSchema: (documentation changed) │ │ │ ├ Description: (documentation changed) │ │ │ └ FunctionSchema: (documentation changed) │ │ ├[~] type APISchema │ │ │ ├ - documentation: Contains details about the OpenAPI schema for the action group. For more information, see [Action group OpenAPI schemas](https://docs.aws.amazon.com/bedrock/latest/userguide/agents-api-schema.html) . You can either include the schema directly in the `payload` field or you can upload it to an S3 bucket and specify the S3 bucket location in the `s3` field. │ │ │ │ + documentation: Contains details about the OpenAPI schema for the action group. For more information, see [Action group OpenAPI schemas](https://docs.aws.amazon.com//bedrock/latest/userguide/agents-api-schema.html) . You can either include the schema directly in the payload field or you can upload it to an S3 bucket and specify the S3 bucket location in the s3 field. │ │ │ └ properties │ │ │ ├ Payload: (documentation changed) │ │ │ └ S3: (documentation changed) │ │ ├[~] type FunctionSchema │ │ │ └ - documentation: Defines functions that each define parameters that the agent needs to invoke from the user. Each function represents an action in an action group. │ │ │ This data type is used in the following API operations: │ │ │ - [CreateAgentActionGroup request](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent_CreateAgentActionGroup.html#API_agent_CreateAgentActionGroup_RequestSyntax) │ │ │ - [CreateAgentActionGroup response](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent_CreateAgentActionGroup.html#API_agent_CreateAgentActionGroup_ResponseSyntax) │ │ │ - [UpdateAgentActionGroup request](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent_UpdateAgentActionGroup.html#API_agent_UpdateAgentActionGroup_RequestSyntax) │ │ │ - [UpdateAgentActionGroup response](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent_UpdateAgentActionGroup.html#API_agent_UpdateAgentActionGroup_ResponseSyntax) │ │ │ - [GetAgentActionGroup response](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent_GetAgentActionGroup.html#API_agent_GetAgentActionGroup_ResponseSyntax) │ │ │ + documentation: Contains details about the function schema for the action group or the JSON or YAML-formatted payload defining the schema. │ │ ├[~] type ParameterDetail │ │ │ └ - documentation: Contains details about a parameter in a function for an action group. │ │ │ This data type is used in the following API operations: │ │ │ - [CreateAgentActionGroup request](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent_CreateAgentActionGroup.html#API_agent_CreateAgentActionGroup_RequestSyntax) │ │ │ - [CreateAgentActionGroup response](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent_CreateAgentActionGroup.html#API_agent_CreateAgentActionGroup_ResponseSyntax) │ │ │ - [UpdateAgentActionGroup request](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent_UpdateAgentActionGroup.html#API_agent_UpdateAgentActionGroup_RequestSyntax) │ │ │ - [UpdateAgentActionGroup response](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent_UpdateAgentActionGroup.html#API_agent_UpdateAgentActionGroup_ResponseSyntax) │ │ │ - [GetAgentActionGroup response](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent_GetAgentActionGroup.html#API_agent_GetAgentActionGroup_ResponseSyntax) │ │ │ + documentation: Contains details about a parameter in a function for an action group. │ │ └[~] type PromptConfiguration │ │ └ properties │ │ └ PromptState: (documentation changed) │ └[~] resource AWS::Bedrock::KnowledgeBase │ ├ properties │ │ └ Description: (documentation changed) │ └ attributes │ └ KnowledgeBaseId: (documentation changed) ├[~] service aws-chatbot │ └ resources │ ├[~] resource AWS::Chatbot::CustomAction │ │ ├ - documentation: Definition of AWS::Chatbot::CustomAction Resource Type │ │ │ + documentation: The `AWS::Chatbot::CustomAction` resource creates a custom action that can be invoked as an alias or as a button on a notification. │ │ ├ properties │ │ │ ├ ActionName: (documentation changed) │ │ │ ├ AliasName: (documentation changed) │ │ │ ├ Attachments: (documentation changed) │ │ │ ├ Definition: (documentation changed) │ │ │ └ Tags: (documentation changed) │ │ ├ attributes │ │ │ └ CustomActionArn: (documentation changed) │ │ └ types │ │ ├[~] type CustomActionAttachment │ │ │ ├ - documentation: undefined │ │ │ │ + documentation: Defines when a custom action button should be attached to a notification. │ │ │ └ properties │ │ │ ├ ButtonText: (documentation changed) │ │ │ ├ Criteria: (documentation changed) │ │ │ ├ NotificationType: (documentation changed) │ │ │ └ Variables: (documentation changed) │ │ ├[~] type CustomActionAttachmentCriteria │ │ │ ├ - documentation: undefined │ │ │ │ + documentation: A criteria for when a button should be shown based on values in the notification. │ │ │ └ properties │ │ │ ├ Operator: (documentation changed) │ │ │ ├ Value: (documentation changed) │ │ │ └ VariableName: (documentation changed) │ │ └[~] type CustomActionDefinition │ │ ├ - documentation: undefined │ │ │ + documentation: The definition of the command to run when invoked as an alias or as an action button. │ │ └ properties │ │ └ CommandText: (documentation changed) │ ├[~] resource AWS::Chatbot::MicrosoftTeamsChannelConfiguration │ │ ├ properties │ │ │ └ CustomizationResourceArns: (documentation changed) │ │ └ attributes │ │ └ Arn: (documentation changed) │ └[~] resource AWS::Chatbot::SlackChannelConfiguration │ ├ properties │ │ └ CustomizationResourceArns: (documentation changed) │ └ attributes │ └ Arn: (documentation changed) ├[~] service aws-cleanrooms │ └ resources │ └[~] resource AWS::CleanRooms::ConfiguredTable │ ├ properties │ │ └ TableReference: (documentation changed) │ └ types │ └[~] type TableReference │ └ - documentation: A pointer to the dataset that underlies this table. Currently, this can only be an AWS Glue table. │ + documentation: A pointer to the dataset that underlies this table. ├[~] service aws-cloudfront │ └ resources │ └[~] resource AWS::CloudFront::Distribution │ └ types │ └[~] type OriginGroup │ └ - documentation: An origin group includes two origins (a primary origin and a second origin to failover to) and a failover criteria that you specify. You create an origin group to support origin failover in CloudFront. When you create or update a distribution, you can specify the origin group instead of a single origin, and CloudFront will failover from the primary origin to the second origin under the failover conditions that you've chosen. │ + documentation: An origin group includes two origins (a primary origin and a secondary origin to failover to) and a failover criteria that you specify. You create an origin group to support origin failover in CloudFront. When you create or update a distribution, you can specify the origin group instead of a single origin, and CloudFront will failover from the primary origin to the secondary origin under the failover conditions that you've chosen. │ Optionally, you can choose selection criteria for your origin group to specify how your origins are selected when your distribution routes viewer requests. ├[~] service aws-cloudtrail │ └ resources │ ├[~] resource AWS::CloudTrail::Dashboard │ │ ├ - documentation: The Amazon CloudTrail dashboard resource allows customers to manage managed dashboards and create custom dashboards. You can manually refresh custom and managed dashboards. For custom dashboards, you can also set up an automatic refresh schedule and modify dashboard widgets. │ │ │ + documentation: Creates a custom dashboard or the Highlights dashboard. │ │ │ - *Custom dashboards* - Custom dashboards allow you to query events in any event data store type. You can add up to 10 widgets to a custom dashboard. You can manually refresh a custom dashboard, or you can set a refresh schedule. │ │ │ - *Highlights dashboard* - You can create the Highlights dashboard to see a summary of key user activities and API usage across all your event data stores. CloudTrail Lake manages the Highlights dashboard and refreshes the dashboard every 6 hours. To create the Highlights dashboard, you must set and enable a refresh schedule. │ │ │ CloudTrail runs queries to populate the dashboard's widgets during a manual or scheduled refresh. CloudTrail must be granted permissions to run the `StartQuery` operation on your behalf. To provide permissions, run the `PutResourcePolicy` operation to attach a resource-based policy to each event data store. For more information, see [Example: Allow CloudTrail to run queries to populate a dashboard](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/security_iam_resource-based-policy-examples.html#security_iam_resource-based-policy-examples-eds-dashboard) in the *AWS CloudTrail User Guide* . │ │ │ To set a refresh schedule, CloudTrail must be granted permissions to run the `StartDashboardRefresh` operation to refresh the dashboard on your behalf. To provide permissions, run the `PutResourcePolicy` operation to attach a resource-based policy to the dashboard. For more information, see [Resource-based policy example for a dashboard](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/security_iam_resource-based-policy-examples.html#security_iam_resource-based-policy-examples-dashboards) in the *AWS CloudTrail User Guide* . │ │ │ For more information about dashboards, see [CloudTrail Lake dashboards](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/lake-dashboard.html) in the *AWS CloudTrail User Guide* . │ │ ├ properties │ │ │ ├ Name: (documentation changed) │ │ │ ├ RefreshSchedule: (documentation changed) │ │ │ ├ Tags: (documentation changed) │ │ │ ├ TerminationProtectionEnabled: (documentation changed) │ │ │ └ Widgets: (documentation changed) │ │ ├ attributes │ │ │ ├ CreatedTimestamp: (documentation changed) │ │ │ ├ DashboardArn: (documentation changed) │ │ │ ├ Status: (documentation changed) │ │ │ ├ Type: (documentation changed) │ │ │ └ UpdatedTimestamp: (documentation changed) │ │ └ types │ │ ├[~] type Frequency │ │ │ ├ - documentation: undefined │ │ │ │ + documentation: Specifies the frequency for a dashboard refresh schedule. │ │ │ │ For a custom dashboard, you can schedule a refresh for every 1, 6, 12, or 24 hours, or every day. │ │ │ └ properties │ │ │ ├ Unit: (documentation changed) │ │ │ └ Value: (documentation changed) │ │ ├[~] type RefreshSchedule │ │ │ ├ - documentation: Configures the automatic refresh schedule for the dashboard. Includes the frequency unit (DAYS or HOURS) and value, as well as the status (ENABLED or DISABLED) of the refresh schedule. │ │ │ │ + documentation: The schedule for a dashboard refresh. │ │ │ └ properties │ │ │ ├ Frequency: (documentation changed) │ │ │ ├ Status: (documentation changed) │ │ │ └ TimeOfDay: (documentation changed) │ │ └[~] type Widget │ │ ├ - documentation: The dashboard widget │ │ │ + documentation: Contains information about a widget on a CloudTrail Lake dashboard. │ │ └ properties │ │ ├ QueryParameters: (documentation changed) │ │ ├ QueryStatement: (documentation changed) │ │ └ ViewProperties: (documentation changed) │ └[~] resource AWS::CloudTrail::ResourcePolicy │ ├ - documentation: Attaches a resource-based permission policy to a CloudTrail channel that is used for an integration with an event source outside of AWS . For more information about resource-based policies, see [CloudTrail resource-based policy examples](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/security_iam_resource-based-policy-examples.html) in the *CloudTrail User Guide* . │ │ + documentation: Attaches a resource-based permission policy to a CloudTrail event data store, dashboard, or channel. For more information about resource-based policies, see [CloudTrail resource-based policy examples](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/security_iam_resource-based-policy-examples.html) in the *CloudTrail User Guide* . │ └ properties │ ├ ResourceArn: (documentation changed) │ └ ResourcePolicy: (documentation changed) ├[~] service aws-codebuild │ └ resources │ └[~] resource AWS::CodeBuild::Project │ └ properties │ └[+] AutoRetryLimit: integer ├[~] service aws-codepipeline │ └ resources │ └[~] resource AWS::CodePipeline::Pipeline │ └ types │ ├[~] type Condition │ │ └ - documentation: The condition for the stage. A condition is made up of the rules and the result for the condition. │ │ + documentation: The condition for the stage. A condition is made up of the rules and the result for the condition. For more information about conditions, see [Stage conditions](https://docs.aws.amazon.com/codepipeline/latest/userguide/stage-conditions.html) . For more information about rules, see the [AWS CodePipeline rule reference](https://docs.aws.amazon.com/codepipeline/latest/userguide/rule-reference.html) . │ └[~] type RuleDeclaration │ ├ - documentation: Represents information about the rule to be created for an associated condition. An example would be creating a new rule for an entry condition, such as a rule that checks for a test result before allowing the run to enter the deployment stage. │ │ + documentation: Represents information about the rule to be created for an associated condition. An example would be creating a new rule for an entry condition, such as a rule that checks for a test result before allowing the run to enter the deployment stage. For more information about conditions, see [Stage conditions](https://docs.aws.amazon.com/codepipeline/latest/userguide/stage-conditions.html) . For more information about rules, see the [AWS CodePipeline rule reference](https://docs.aws.amazon.com/codepipeline/latest/userguide/rule-reference.html) . │ └ properties │ └ Name: (documentation changed) ├[~] service aws-cognito │ └ resources │ ├[~] resource AWS::Cognito::ManagedLoginBranding │ │ ├ - documentation: Resource Type definition for AWS::Cognito::ManagedLoginBranding │ │ │ + documentation: Creates a new set of branding settings for a user pool style and associates it with an app client. This operation is the programmatic option for the creation of a new style in the branding designer. │ │ │ Provides values for UI customization in a `Settings` JSON object and image files in an `Assets` array. To send the JSON object `Document` type parameter in `Settings` , you might need to update to the most recent version of your AWS SDK. │ │ │ This operation has a 2-megabyte request-size limit and include the CSS settings and image assets for your app client. Your branding settings might exceed 2MB in size. Amazon Cognito doesn't require that you pass all parameters in one request and preserves existing style settings that you don't specify. If your request is larger than 2MB, separate it into multiple requests, each with a size smaller than the limit. │ │ │ As a best practice, modify the output of [DescribeManagedLoginBrandingByClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DescribeManagedLoginBrandingByClient.html) into the request parameters for this operation. To get all settings, set `ReturnMergedResources` to `true` . For more information, see [API and SDK operations for managed login branding](https://docs.aws.amazon.com/cognito/latest/developerguide/managed-login-brandingdesigner.html#branding-designer-api) │ │ │ > Amazon Cognito evaluates AWS Identity and Access Management (IAM) policies in requests for this API operation. For this operation, you must use IAM credentials to authorize requests, and you must grant yourself the corresponding IAM permission in a policy. │ │ │ > │ │ │ > **Learn more** - [Signing AWS API Requests](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html) │ │ │ > - [Using the Amazon Cognito user pools API and user pool endpoints](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pools-API-operations.html) │ │ ├ properties │ │ │ ├ Assets: (documentation changed) │ │ │ ├ Settings: (documentation changed) │ │ │ ├ UseCognitoProvidedValues: (documentation changed) │ │ │ └ UserPoolId: (documentation changed) │ │ ├ attributes │ │ │ └ ManagedLoginBrandingId: (documentation changed) │ │ └ types │ │ └[~] type AssetType │ │ ├ - documentation: undefined │ │ │ + documentation: An image file from a managed login branding style in a user pool. │ │ │ This data type is a request parameter of [CreateManagedLoginBranding](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateManagedLoginBranding.html) and [UpdateManagedLoginBranding](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateManagedLoginBranding.html) , and a response parameter of [DescribeManagedLoginBranding](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DescribeManagedLoginBranding.html) . │ │ └ properties │ │ ├ Bytes: (documentation changed) │ │ ├ Category: (documentation changed) │ │ ├ ColorMode: (documentation changed) │ │ ├ Extension: (documentation changed) │ │ └ ResourceId: (documentation changed) │ ├[~] resource AWS::Cognito::UserPool │ │ ├ properties │ │ │ └ UserPoolTier: (documentation changed) │ │ └ types │ │ ├[~] type AdminCreateUserConfig │ │ │ └ properties │ │ │ └ InviteMessageTemplate: (documentation changed) │ │ └[~] type InviteMessageTemplate │ │ └ - documentation: The template for the welcome message to new users. │ │ See also [Customizing User Invitation Messages](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-message-customizations.html#cognito-user-pool-settings-user-invitation-message-customization) . │ │ + documentation: The template for the welcome message to new users. This template must include the `{####}` temporary password placeholder if you are creating users with passwords. If your users don't have passwords, you can omit the placeholder. │ │ See also [Customizing User Invitation Messages](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-message-customizations.html#cognito-user-pool-settings-user-invitation-message-customization) . │ ├[~] resource AWS::Cognito::UserPoolClient │ │ └ properties │ │ ├ EnablePropagateAdditionalUserContextData: (documentation changed) │ │ ├ ExplicitAuthFlows: (documentation changed) │ │ └ SupportedIdentityProviders: (documentation changed) │ ├[~] resource AWS::Cognito::UserPoolDomain │ │ └ properties │ │ ├ CustomDomainConfig: (documentation changed) │ │ └[+] ManagedLoginVersion: integer │ └[~] resource AWS::Cognito::UserPoolUser │ └ properties │ └ UserAttributes: (documentation changed) ├[~] service aws-config │ └ resources │ └[~] resource AWS::Config::ConfigurationRecorder │ ├ properties │ │ └ RecordingMode: (documentation changed) │ └ types │ ├[~] type RecordingMode │ │ └ properties │ │ └ RecordingFrequency: (documentation changed) │ └[~] type RecordingModeOverride │ └ properties │ └ ResourceTypes: (documentation changed) ├[~] service aws-connect │ └ resources │ ├[~] resource AWS::Connect::EmailAddress │ │ ├ - documentation: Resource Type definition for AWS::Connect::EmailAddress │ │ │ + documentation: Create new email address in the specified Amazon Connect instance. For more information about email addresses, see [Create email addresses](https://docs.aws.amazon.com/connect/latest/adminguide/create-email-address1.html) in the Amazon Connect Administrator Guide. │ │ ├ properties │ │ │ ├ Description: (documentation changed) │ │ │ ├ DisplayName: (documentation changed) │ │ │ ├ EmailAddress: (documentation changed) │ │ │ └ InstanceArn: (documentation changed) │ │ └ attributes │ │ └ EmailAddressArn: (documentation changed) │ └[~] resource AWS::Connect::PhoneNumber │ └ properties │ └ SourcePhoneNumberArn: (documentation changed) ├[~] service aws-connectcampaignsv2 │ └ resources │ └[~] resource AWS::ConnectCampaignsV2::Campaign │ ├ - documentation: Definition of AWS::ConnectCampaignsV2::Campaign Resource Type │ │ + documentation: Creates an outbound campaign. │ │ > - For users to be able to view or edit a campaign at a later date by using the Amazon Connect user interface, you must add the instance ID as a tag. For example, `{ "tags": {"owner": "arn:aws:connect:{REGION}:{AWS_ACCOUNT_ID}:instance/{CONNECT_INSTANCE_ID}"}}` . │ │ > - After a campaign is created, you can't add/remove source. │ ├ properties │ │ ├ ChannelSubtypeConfig: (documentation changed) │ │ ├ CommunicationLimitsOverride: (documentation changed) │ │ ├ CommunicationTimeConfig: (documentation changed) │ │ ├ ConnectCampaignFlowArn: (documentation changed) │ │ ├ ConnectInstanceId: (documentation changed) │ │ ├ Name: (documentation changed) │ │ ├ Schedule: (documentation changed) │ │ ├ Source: (documentation changed) │ │ └ Tags: (documentation changed) │ ├ attributes │ │ └ Arn: (documentation changed) │ └ types │ ├[~] type AnswerMachineDetectionConfig │ │ ├ - documentation: The configuration used for answering machine detection during outbound calls │ │ │ + documentation: Contains answering machine detection configuration. │ │ └ properties │ │ ├ AwaitAnswerMachinePrompt: (documentation changed) │ │ └ EnableAnswerMachineDetection: (documentation changed) │ ├[~] type ChannelSubtypeConfig │ │ ├ - documentation: The possible types of channel subtype config parameters │ │ │ + documentation: Contains channel subtype configuration for an outbound campaign. │ │ └ properties │ │ ├ Email: (documentation changed) │ │ ├ Sms: (documentation changed) │ │ └ Telephony: (documentation changed) │ ├[~] type CommunicationLimit │ │ ├ - documentation: Communication Limit │ │ │ + documentation: Contains information about a communication limit. │ │ └ properties │ │ ├ Frequency: (documentation changed) │ │ ├ MaxCountPerRecipient: (documentation changed) │ │ └ Unit: (documentation changed) │ ├[~] type CommunicationLimits │ │ ├ - documentation: Communication limits │ │ │ + documentation: Contains information about communication limits. │ │ └ properties │ │ └ CommunicationLimitList: (documentation changed) │ ├[~] type CommunicationLimitsConfig │ │ ├ - documentation: Communication limits config │ │ │ + documentation: Contains the communication limits configuration for an outbound campaign. │ │ └ properties │ │ └ AllChannelsSubtypes: (documentation changed) │ ├[~] type CommunicationTimeConfig │ │ ├ - documentation: Campaign communication time config │ │ │ + documentation: Communication time configuration for an outbound campaign. │ │ └ properties │ │ ├ Email: (documentation changed) │ │ ├ LocalTimeZoneConfig: (documentation changed) │ │ ├ Sms: (documentation changed) │ │ └ Telephony: (documentation changed) │ ├[~] type DailyHour │ │ ├ - documentation: Daily Hour │ │ │ + documentation: The daily hours configuration. │ │ └ properties │ │ ├ Key: (documentation changed) │ │ └ Value: (documentation changed) │ ├[~] type EmailChannelSubtypeConfig │ │ ├ - documentation: Email Channel Subtype config │ │ │ + documentation: The configuration for the email channel subtype. │ │ └ properties │ │ ├ Capacity: (documentation changed) │ │ ├ DefaultOutboundConfig: (documentation changed) │ │ └ OutboundMode: (documentation changed) │ ├[~] type EmailOutboundConfig │ │ ├ - documentation: Default SMS outbound config │ │ │ + documentation: The outbound configuration for email. │ │ └ properties │ │ ├ ConnectSourceEmailAddress: (documentation changed) │ │ ├ SourceEmailAddressDisplayName: (documentation changed) │ │ └ WisdomTemplateArn: (documentation changed) │ ├[~] type EmailOutboundMode │ │ ├ - documentation: Email Outbound Mode │ │ │ + documentation: Contains information about email outbound mode. │ │ └ properties │ │ └ AgentlessConfig: (documentation changed) │ ├[~] type LocalTimeZoneConfig │ │ ├ - documentation: Local time zone config │ │ │ + documentation: The configuration of timezone for recipient. │ │ └ properties │ │ ├ DefaultTimeZone: (documentation changed) │ │ └ LocalTimeZoneDetection: (documentation changed) │ ├[~] type OpenHours │ │ ├ - documentation: Open Hours config │ │ │ + documentation: Contains information about open hours. │ │ └ properties │ │ └ DailyHours: (documentation changed) │ ├[~] type PredictiveConfig │ │ ├ - documentation: Predictive config │ │ │ + documentation: Contains predictive outbound mode configuration. │ │ └ properties │ │ └ BandwidthAllocation: (documentation changed) │ ├[~] type ProgressiveConfig │ │ ├ - documentation: Progressive config │ │ │ + documentation: Contains the progressive outbound mode configuration. │ │ └ properties │ │ └ BandwidthAllocation: (documentation changed) │ ├[~] type RestrictedPeriod │ │ ├ - documentation: Restricted period │ │ │ + documentation: Contains information about a restricted period. │ │ └ properties │ │ ├ EndDate: (documentation changed) │ │ ├ Name: (documentation changed) │ │ └ StartDate: (documentation changed) │ ├[~] type RestrictedPeriods │ │ ├ - documentation: Restricted period config │ │ │ + documentation: Contains information about restricted periods. │ │ └ properties │ │ └ RestrictedPeriodList: (documentation changed) │ ├[~] type Schedule │ │ ├ - documentation: Campaign schedule │ │ │ + documentation: Contains the schedule configuration. │ │ └ properties │ │ ├ EndTime: (documentation changed) │ │ ├ RefreshFrequency: (documentation changed) │ │ └ StartTime: (documentation changed) │ ├[~] type SmsChannelSubtypeConfig │ │ ├ - documentation: SMS Channel Subtype config │ │ │ + documentation: The configuration for the SMS channel subtype. │ │ └ properties │ │ ├ Capacity: (documentation changed) │ │ ├ DefaultOutboundConfig: (documentation changed) │ │ └ OutboundMode: (documentation changed) │ ├[~] type SmsOutboundConfig │ │ ├ - documentation: Default SMS outbound config │ │ │ + documentation: The outbound configuration for SMS. │ │ └ properties │ │ ├ ConnectSourcePhoneNumberArn: (documentation changed) │ │ └ WisdomTemplateArn: (documentation changed) │ ├[~] type SmsOutboundMode │ │ ├ - documentation: SMS Outbound Mode │ │ │ + documentation: Contains information about the SMS outbound mode. │ │ └ properties │ │ └ AgentlessConfig: (documentation changed) │ ├[~] type Source │ │ ├ - documentation: The possible types of channel config parameters │ │ │ + documentation: Contains source configuration. │ │ └ properties │ │ └ CustomerProfilesSegmentArn: (documentation changed) │ ├[~] type TelephonyChannelSubtypeConfig │ │ ├ - documentation: Telephony Channel Subtype config │ │ │ + documentation: The configuration for the telephony channel subtype. │ │ └ properties │ │ ├ Capacity: (documentation changed) │ │ ├ ConnectQueueId: (documentation changed) │ │ ├ DefaultOutboundConfig: (documentation changed) │ │ └ OutboundMode: (documentation changed) │ ├[~] type TelephonyOutboundConfig │ │ ├ - documentation: Default Telephone Outbound config │ │ │ + documentation: The outbound configuration for telephony. │ │ └ properties │ │ ├ AnswerMachineDetectionConfig: (documentation changed) │ │ ├ ConnectContactFlowId: (documentation changed) │ │ └ ConnectSourcePhoneNumber: (documentation changed) │ ├[~] type TelephonyOutboundMode │ │ ├ - documentation: Telephony Outbound Mode │ │ │ + documentation: Contains information about telephony outbound mode. │ │ └ properties │ │ ├ AgentlessConfig: (documentation changed) │ │ ├ PredictiveConfig: (documentation changed) │ │ └ ProgressiveConfig: (documentation changed) │ ├[~] type TimeRange │ │ ├ - documentation: Time range in 24 hour format │ │ │ + documentation: Contains information about a time range. │ │ └ properties │ │ ├ EndTime: (documentation changed) │ │ └ StartTime: (documentation changed) │ └[~] type TimeWindow │ ├ - documentation: Time window config │ │ + documentation: Contains information about a time window. │ └ properties │ ├ OpenHours: (documentation changed) │ └ RestrictedPeriods: (documentation changed) ├[~] service aws-docdb │ └ resources │ └[~] resource AWS::DocDB::DBCluster │ ├ properties │ │ └[+] ServerlessV2ScalingConfiguration: ServerlessV2ScalingConfiguration │ └ types │ └[+] type ServerlessV2ScalingConfiguration │ ├ name: ServerlessV2ScalingConfiguration │ └ properties │ ├MinCapacity: number (required) │ └MaxCapacity: number (required) ├[~] service aws-ec2 │ └ resources │ ├[~] resource AWS::EC2::CapacityReservation │ │ └ properties │ │ ├ EndDate: (documentation changed) │ │ ├ InstanceCount: (documentation changed) │ │ ├ InstanceMatchCriteria: (documentation changed) │ │ ├ InstanceType: (documentation changed) │ │ ├ OutPostArn: (documentation changed) │ │ └ PlacementGroupArn: (documentation changed) │ ├[~] resource AWS::EC2::EC2Fleet │ │ └ types │ │ └[~] type InstanceRequirementsRequest │ │ └ properties │ │ └ CpuManufacturers: (documentation changed) │ ├[~] resource AWS::EC2::LaunchTemplate │ │ └ types │ │ ├[~] type BaselinePerformanceFactors │ │ │ ├ - documentation: undefined │ │ │ │ + documentation: The baseline performance to consider, using an instance family as a baseline reference. The instance family establishes the lowest acceptable level of performance. Amazon EC2 uses this baseline to guide instance type selection, but there is no guarantee that the selected instance types will always exceed the baseline for every application. │ │ │ │ Currently, this parameter only supports CPU performance as a baseline performance factor. For example, specifying `c6i` would use the CPU performance of the `c6i` family as the baseline reference. │ │ │ └ properties │ │ │ └ Cpu: (documentation changed) │ │ ├[~] type CapacityReservationSpecification │ │ │ └ properties │ │ │ └ CapacityReservationPreference: (documentation changed) │ │ └[~] type InstanceRequirements │ │ └ properties │ │ ├ BaselinePerformanceFactors: (documentation changed) │ │ └ CpuManufacturers: (documentation changed) │ ├[~] resource AWS::EC2::SpotFleet │ │ └ types │ │ └[~] type InstanceRequirementsRequest │ │ └ properties │ │ └ CpuManufacturers: (documentation changed) │ ├[~] resource AWS::EC2::VPCBlockPublicAccessExclusion │ │ ├ - documentation: Resource Type definition for AWS::EC2::VPCBlockPublicAccessExclusion. │ │ │ + documentation: Create a VPC Block Public Access (BPA) exclusion. A VPC BPA exclusion is a mode that can be applied to a single VPC or subnet that exempts it from the account’s BPA mode and will allow bidirectional or egress-only access. You can create BPA exclusions for VPCs and subnets even when BPA is not enabled on the account to ensure that there is no traffic disruption to the exclusions when VPC BPA is turned on. To learn more about VPC BPA, see [Block public access to VPCs and subnets](https://docs.aws.amazon.com/vpc/latest/userguide/security-vpc-bpa.html) in the *Amazon VPC User Guide* . │ │ ├ properties │ │ │ ├ InternetGatewayExclusionMode: (documentation changed) │ │ │ ├ SubnetId: (documentation changed) │ │ │ └ VpcId: (documentation changed) │ │ └ attributes │ │ └ ExclusionId: (documentation changed) │ └[~] resource AWS::EC2::VPCBlockPublicAccessOptions │ ├ - documentation: Resource Type definition for AWS::EC2::VPCBlockPublicAccessOptions │ │ + documentation: VPC Block Public Access (BPA) enables you to block resources in VPCs and subnets that you own in a Region from reaching or being reached from the internet through internet gateways and egress-only internet gateways. To learn more about VPC BPA, see [Block public access to VPCs and subnets](https://docs.aws.amazon.com/vpc/latest/userguide/security-vpc-bpa.html) in the *Amazon VPC User Guide* . │ ├ properties │ │ └ InternetGatewayBlockMode: (documentation changed) │ └ attributes │ └ AccountId: (documentation changed) ├[~] service aws-ecs │ └ resources │ ├[~] resource AWS::ECS::Cluster │ │ ├ properties │ │ │ └ ClusterSettings: (documentation changed) │ │ └ types │ │ └[~] type ClusterSettings │ │ ├ - documentation: The settings to use when creating a cluster. This parameter is used to turn on CloudWatch Container Insights for a cluster. │ │ │ + documentation: The settings to use when creating a cluster. This parameter is used to turn on CloudWatch Container Insights with enhanced observability or CloudWatch Container Insights for a cluster. │ │ │ Container Insights with enhanced observability provides all the Container Insights metrics, plus additional task and container metrics. This version supports enhanced observability for Amazon ECS clusters using the Amazon EC2 and Fargate launch types. After you configure Container Insights with enhanced observability on Amazon ECS, Container Insights auto-collects detailed infrastructure telemetry from the cluster level down to the container level in your environment and displays these critical performance data in curated dashboards removing the heavy lifting in observability set-up. │ │ │ For more information, see [Monitor Amazon ECS containers using Container Insights with enhanced observability](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cloudwatch-container-insights.html) in the *Amazon Elastic Container Service Developer Guide* . │ │ └ properties │ │ └ Value: (documentation changed) │ ├[~] resource AWS::ECS::Service │ │ └ types │ │ └[~] type AwsVpcConfiguration │ │ └ properties │ │ └ AssignPublicIp: (documentation changed) │ ├[~] resource AWS::ECS::TaskDefinition │ │ └ types │ │ └[~] type EphemeralStorage │ │ └ properties │ │ └ SizeInGiB: (documentation changed) │ └[~] resource AWS::ECS::TaskSet │ └ types │ └[~] type AwsVpcConfiguration │ └ properties │ └ AssignPublicIp: (documentation changed) ├[~] service aws-eks │ └ resources │ └[~] resource AWS::EKS::Cluster │ ├ properties │ │ ├ ComputeConfig: (documentation changed) │ │ ├ RemoteNetworkConfig: (documentation changed) │ │ └ StorageConfig: (documentation changed) │ └ types │ ├[~] type BlockStorage │ │ ├ - documentation: Todo: add description │ │ │ + documentation: Indicates the current configuration of the block storage capability on your EKS Auto Mode cluster. For example, if the capability is enabled or disabled. If the block storage capability is enabled, EKS Auto Mode will create and delete EBS volumes in your AWS account. For more information, see EKS Auto Mode block storage capability in the EKS User Guide. │ │ └ properties │ │ └ Enabled: (documentation changed) │ ├[~] type ElasticLoadBalancing │ │ ├ - documentation: Todo: add description │ │ │ + documentation: Indicates the current configuration of the load balancing capability on your EKS Auto Mode cluster. For example, if the capability is enabled or disabled. For more information, see EKS Auto Mode load balancing capability in the EKS User Guide. │ │ └ properties │ │ └ Enabled: (documentation changed) │ ├[~] type RemoteNodeNetwork │ │ ├ - documentation: Network configuration of nodes run on-premises with EKS Hybrid Nodes. │ │ │ + documentation: A network CIDR that can contain hybrid nodes. │ │ │ These CIDR blocks define the expected IP address range of the hybrid nodes that join the cluster. These blocks are typically determined by your network administrator. │ │ │ Enter one or more IPv4 CIDR blocks in decimal dotted-quad notation (for example, `10.2.0.0/16` ). │ │ │ It must satisfy the following requirements: │ │ │ - Each block must be within an `IPv4` RFC-1918 network range. Minimum allowed size is /24, maximum allowed size is /8. Publicly-routable addresses aren't supported. │ │ │ - Each block cannot overlap with the range of the VPC CIDR blocks for your EKS resources, or the block of the Kubernetes service IP range. │ │ │ - Each block must have a route to the VPC that uses the VPC CIDR blocks, not public IPs or Elastic IPs. There are many options including AWS Transit Gateway , AWS Site-to-Site VPN , or AWS Direct Connect . │ │ │ - Each host must allow outbound connection to the EKS cluster control plane on TCP ports `443` and `10250` . │ │ │ - Each host must allow inbound connection from the EKS cluster control plane on TCP port 10250 for logs, exec and port-forward operations. │ │ │ - Each host must allow TCP and UDP network connectivity to and from other hosts that are running `CoreDNS` on UDP port `53` for service and pod DNS names. │ │ └ properties │ │ └ Cidrs: (documentation changed) │ └[~] type RemotePodNetwork │ ├ - documentation: Network configuration of pods run on-premises with EKS Hybrid Nodes. │ │ + documentation: A network CIDR that can contain pods that run Kubernetes webhooks on hybrid nodes. │ │ These CIDR blocks are determined by configuring your Container Network Interface (CNI) plugin. We recommend the Calico CNI or Cilium CNI. Note that the Amazon VPC CNI plugin for Kubernetes isn't available for on-premises and edge locations. │ │ Enter one or more IPv4 CIDR blocks in decimal dotted-quad notation (for example, `10.2.0.0/16` ). │ │ It must satisfy the following requirements: │ │ - Each block must be within an `IPv4` RFC-1918 network range. Minimum allowed size is /24, maximum allowed size is /8. Publicly-routable addresses aren't supported. │ │ - Each block cannot overlap with the range of the VPC CIDR blocks for your EKS resources, or the block of the Kubernetes service IP range. │ └ properties │ └ Cidrs: (documentation changed) ├[~] service aws-elasticache │ └ resources │ ├[~] resource AWS::ElastiCache::CacheCluster │ │ └ properties │ │ ├ IpDiscovery: (documentation changed) │ │ └ NetworkType: (documentation changed) │ ├[~] resource AWS::ElastiCache::ReplicationGroup │ │ └ properties │ │ ├ IpDiscovery: (documentation changed) │ │ └ NetworkType: (documentation changed) │ ├[~] resource AWS::ElastiCache::ServerlessCache │ │ └ properties │ │ ├ DailySnapshotTime: (documentation changed) │ │ └ SnapshotRetentionLimit: (documentation changed) │ └[~] resource AWS::ElastiCache::User │ └ properties │ └ Engine: (documentation changed) ├[~] service aws-elasticloadbalancingv2 │ └ resources │ ├[~] resource AWS::ElasticLoadBalancingV2::Listener │ │ └ types │ │ ├[~] type ListenerAttribute │ │ │ └ properties │ │ │ └ Key: (documentation changed) │ │ └[~] type MutualAuthentication │ │ └ properties │ │ └[+] AdvertiseTrustStoreCaNames: string │ └[~] resource AWS::ElasticLoadBalancingV2::LoadBalancer │ ├ properties │ │ └ MinimumLoadBalancerCapacity: (documentation changed) │ └ types │ ├[~] type LoadBalancerAttribute │ │ └ properties │ │ └ Key: (documentation changed) │ └[~] type MinimumLoadBalancerCapacity │ ├ - documentation: undefined │ │ + documentation: The minimum capacity for a load balancer. │ └ properties │ └ CapacityUnits: (documentation changed) ├[~] service aws-events │ └ resources │ ├[~] resource AWS::Events::Connection │ │ ├ - documentation: Creates a connection. A connection defines the authorization type and credentials to use for authorization with an API destination HTTP endpoint. │ │ │ + documentation: Creates a connection. A connection defines the authorization type and credentials to use for authorization with an API destination HTTP endpoint. │ │ │ For more information, see [Connections for endpoint targets](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-target-connection.html) in the *Amazon EventBridge User Guide* . │ │ ├ properties │ │ │ └ AuthParameters: (documentation changed) │ │ ├ attributes │ │ │ ├ AuthParameters.ConnectivityParameters.ResourceParameters.ResourceAssociationArn: (documentation changed) │ │ │ └ InvocationConnectivityParameters.ResourceParameters.ResourceAssociationArn: (documentation changed) │ │ └ types │ │ ├[~] type ApiKeyAuthParameters │ │ │ └ - documentation: Contains the API key authorization parameters for the connection. │ │ │ + documentation: The API key authorization parameters for the connection. │ │ ├[~] type AuthParameters │ │ │ └ - documentation: Contains the authorization parameters to use for the connection. │ │ │ + documentation: Tthe authorization parameters to use for the connection. │ │ ├[~] type BasicAuthParameters │ │ │ └ - documentation: Contains the Basic authorization parameters for the connection. │ │ │ + documentation: The Basic authorization parameters for the connection. │ │ ├[~] type ClientParameters │ │ │ └ - documentation: Contains the OAuth authorization parameters to use for the connection. │ │ │ + documentation: The OAuth authorization parameters to use for the connection. │ │ ├[~] type ConnectionHttpParameters │ │ │ ├ - documentation: Contains additional parameters for the connection. │ │ │ │ + documentation: Any additional parameters for the connection. │ │ │ └ properties │ │ │ ├ BodyParameters: (documentation changed) │ │ │ ├ HeaderParameters: (documentation changed) │ │ │ └ QueryStringParameters: (documentation changed) │ │ ├[~] type OAuthParameters │ │ │ └ properties │ │ │ ├ ClientParameters: (documentation changed) │ │ │ └ OAuthHttpParameters: (documentation changed) │ │ ├[~] type Parameter │ │ │ └ - documentation: Additional query string parameter for the connection. You can include up to 100 additional query string parameters per request. Each additional parameter counts towards the event payload size, which cannot exceed 64 KB. │ │ │ + documentation: Any additional query string parameter for the connection. You can include up to 100 additional query string parameters per request. Each additional parameter counts towards the event payload size, which cannot exceed 64 KB. │ │ └[~] type ResourceParameters │ │ └ properties │ │ └ ResourceAssociationArn: (documentation changed) │ └[~] resource AWS::Events::Rule │ └ types │ └[~] type Target │ └ properties │ └ RetryPolicy: (documentation changed) ├[~] service aws-fsx │ └ resources │ ├[~] resource AWS::FSx::FileSystem │ │ ├ properties │ │ │ └ StorageType: (documentation changed) │ │ └ types │ │ ├[~] type LustreConfiguration │ │ │ └ properties │ │ │ └[+] EfaEnabled: boolean │ │ ├[~] type OpenZFSConfiguration │ │ │ └ properties │ │ │ └[+] ReadCacheConfiguration: ReadCacheConfiguration │ │ └[+] type ReadCacheConfiguration │ │ ├ name: ReadCacheConfiguration │ │ └ properties │ │ ├SizingMode: string │ │ └SizeGiB: integer │ └[~] resource AWS::FSx::Volume │ └ types │ └[~] type OpenZFSConfiguration │ └ properties │ └ RecordSizeKiB: (documentation changed) ├[~] service aws-imagebuilder │ └ resources │ ├[~] resource AWS::ImageBuilder::ContainerRecipe │ │ └ types │ │ └[~] type TargetContainerRepository │ │ └ properties │ │ └ RepositoryName: (documentation changed) │ ├[~] resource AWS::ImageBuilder::DistributionConfiguration │ │ └ types │ │ └[~] type TargetContainerRepository │ │ └ properties │ │ └ RepositoryName: (documentation changed) │ ├[~] resource AWS::ImageBuilder::Image │ │ └ types │ │ └[~] type ImageTestsConfiguration │ │ └ properties │ │ └ TimeoutMinutes: (documentation changed) │ └[~] resource AWS::ImageBuilder::ImagePipeline │ └ types │ └[~] type ImageTestsConfiguration │ └ properties │ └ TimeoutMinutes: (documentation changed) ├[+] service aws-invoicing │ ├ capitalized: Invoicing │ │ cloudFormationNamespace: AWS::Invoicing │ │ name: aws-invoicing │ │ shortName: invoicing │ └ resources │ └resource AWS::Invoicing::InvoiceUnit │ ├ name: InvoiceUnit │ │ cloudFormationType: AWS::Invoicing::InvoiceUnit │ │ documentation: An invoice unit is a set of mutually exclusive accounts that correspond to your business entity. Invoice units allow you to separate AWS account costs and configures your invoice for each business entity. │ │ tagInformation: {"tagPropertyName":"ResourceTags","variant":"standard"} │ ├ properties │ │ ├InvoiceReceiver: string (required, immutable) │ │ ├Name: string (required, immutable) │ │ ├Description: string │ │ ├TaxInheritanceDisabled: boolean │ │ ├Rule: Rule (required) │ │ └ResourceTags: Array │ ├ attributes │ │ ├InvoiceUnitArn: string │ │ └LastModified: number │ └ types │ ├type Rule │ │├ name: Rule │ │└ properties │ │ └LinkedAccounts: Array (required) │ └type ResourceTag │ ├ name: ResourceTag │ └ properties │ ├Key: string (required) │ └Value: string (required) ├[~] service aws-iot │ └ resources │ └[~] resource AWS::IoT::ThingType │ ├ properties │ │ ├ DeprecateThingType: (documentation changed) │ │ └ ThingTypeProperties: (documentation changed) │ └ types │ ├[~] type Mqtt5Configuration │ │ ├ - documentation: undefined │ │ │ + documentation: The configuration to add user-defined properties to enrich MQTT 5 messages. │ │ └ properties │ │ └ PropagatingAttributes: (documentation changed) │ ├[~] type PropagatingAttribute │ │ ├ - documentation: undefined │ │ │ + documentation: An object that represents the connection attribute, the thing attribute, and the MQTT 5 user property key. │ │ └ properties │ │ ├ ConnectionAttribute: (documentation changed) │ │ ├ ThingAttribute: (documentation changed) │ │ └ UserPropertyKey: (documentation changed) │ └[~] type ThingTypeProperties │ └ properties │ └ Mqtt5Configuration: (documentation changed) ├[~] service aws-iotfleetwise │ └ resources │ ├[~] resource AWS::IoTFleetWise::Campaign │ │ ├ - documentation: Creates an orchestration of data collection rules. The AWS IoT FleetWise Edge Agent software running in vehicles uses campaigns to decide how to collect and transfer data to the cloud. You create campaigns in the cloud. After you or your team approve campaigns, AWS IoT FleetWise automatically deploys them to vehicles. │ │ │ For more information, see [Collect and transfer data with campaigns](https://docs.aws.amazon.com/iot-fleetwise/latest/developerguide/campaigns.html) in the *AWS IoT FleetWise Developer Guide* . │ │ │ + documentation: Creates an orchestration of data collection rules. The AWS IoT FleetWise Edge Agent software running in vehicles uses campaigns to decide how to collect and transfer data to the cloud. You create campaigns in the cloud. After you or your team approve campaigns, AWS IoT FleetWise automatically deploys them to vehicles. │ │ │ For more information, see [Campaigns](https://docs.aws.amazon.com/iot-fleetwise/latest/developerguide/campaigns.html) in the *AWS IoT FleetWise Developer Guide* . │ │ │ > Access to certain AWS IoT FleetWise features is currently gated. For more information, see [AWS Region and feature availability](https://docs.aws.amazon.com/iot-fleetwise/latest/developerguide/fleetwise-regions.html) in the *AWS IoT FleetWise Developer Guide* . │ │ ├ properties │ │ │ ├ Compression: (documentation changed) │ │ │ ├ DataDestinationConfigs: (documentation changed) │ │ │ ├ DataExtraDimensions: (documentation changed) │ │ │ ├ DataPartitions: (documentation changed) │ │ │ ├ Description: (documentation changed) │ │ │ ├ DiagnosticsMode: (documentation changed) │ │ │ ├ ExpiryTime: (documentation changed) │ │ │ ├ PostTriggerCollectionDuration: (documentation changed) │ │ │ ├ Priority: (documentation changed) │ │ │ ├ SignalsToCollect: (documentation changed) │ │ │ ├ SignalsToFetch: (documentation changed) │ │ │ ├ SpoolingMode: (documentation changed) │ │ │ ├ StartTime: (documentation changed) │ │ │ └ Tags: (documentation changed) │ │ └ types │ │ ├[~] type CollectionScheme │ │ │ └ properties │ │ │ ├ ConditionBasedCollectionScheme: (documentation changed) │ │ │ └ TimeBasedCollectionScheme: (documentation changed) │ │ ├[~] type ConditionBasedCollectionScheme │ │ │ └ properties │ │ │ ├ ConditionLanguageVersion: (documentation changed) │ │ │ ├ MinimumTriggerIntervalMs: (documentation changed) │ │ │ └ TriggerMode: (documentation changed) │ │ ├[~] type ConditionBasedSignalFetchConfig │ │ │ ├ - documentation: undefined │ │ │ │ + documentation: Specifies the condition under which a signal fetch occurs. │ │ │ └ properties │ │ │ ├ ConditionExpression: (documentation changed) │ │ │ └ TriggerMode: (documentation changed) │ │ ├[~] type DataDestinationConfig │ │ │ └ properties │ │ │ ├ MqttTopicConfig: (documentation changed) │ │ │ ├ S3Config: (documentation changed) │ │ │ └ TimestreamConfig: (documentation changed) │ │ ├[~] type DataPartition │ │ │ ├ - documentation: undefined │ │ │ │ + documentation: The configuration for signal data storage and upload options. You can only specify these options when the campaign's spooling mode is `TO_DISK` . │ │ │ │ > Access to certain AWS IoT FleetWise features is currently gated. For more information, see [AWS Region and feature availability](https://docs.aws.amazon.com/iot-fleetwise/latest/developerguide/fleetwise-regions.html) in the *AWS IoT FleetWise Developer Guide* . │ │ │ └ properties │ │ │ ├ Id: (documentation changed) │ │ │ ├ StorageOptions: (documentation changed) │ │ │ └ UploadOptions: (documentation changed) │ │ ├[~] type DataPartitionStorageOptions │ │ │ ├ - documentation: undefined │ │ │ │ + documentation: Size, time, and location options for the data partition. │ │ │ └ properties │ │ │ ├ MaximumSize: (documentation changed) │ │ │ ├ MinimumTimeToLive: (documentation changed) │ │ │ └ StorageLocation: (documentation changed) │ │ ├[~] type DataPartitionUploadOptions │ │ │ ├ - documentation: undefined │ │ │ │ + documentation: The upload options for the data partition. If upload options are specified, you must also specify storage options. See [DataPartitionStorageOptions](https://docs.aws.amazon.com/iot-fleetwise/latest/APIReference/API_DataPartitionStorageOptions.html) . │ │ │ │ > Access to cer --- .../@aws-cdk/cloudformation-diff/package.json | 4 +- packages/@aws-cdk/integ-runner/package.json | 2 +- .../aws-cdk-lib/aws-invoicing/.jsiirc.json | 13 ++++ packages/aws-cdk-lib/aws-invoicing/README.md | 39 +++++++++++ packages/aws-cdk-lib/aws-invoicing/index.ts | 1 + .../aws-cdk-lib/aws-invoicing/lib/index.ts | 2 + packages/aws-cdk-lib/index.ts | 1 + packages/aws-cdk-lib/package.json | 3 +- packages/aws-cdk-lib/scripts/scope-map.json | 3 + tools/@aws-cdk/spec2cdk/package.json | 6 +- yarn.lock | 67 +++++++++---------- 11 files changed, 97 insertions(+), 44 deletions(-) create mode 100644 packages/aws-cdk-lib/aws-invoicing/.jsiirc.json create mode 100644 packages/aws-cdk-lib/aws-invoicing/README.md create mode 100644 packages/aws-cdk-lib/aws-invoicing/index.ts create mode 100644 packages/aws-cdk-lib/aws-invoicing/lib/index.ts diff --git a/packages/@aws-cdk/cloudformation-diff/package.json b/packages/@aws-cdk/cloudformation-diff/package.json index 09298cdf533b9..beab2ec9a1cad 100644 --- a/packages/@aws-cdk/cloudformation-diff/package.json +++ b/packages/@aws-cdk/cloudformation-diff/package.json @@ -23,8 +23,8 @@ }, "license": "Apache-2.0", "dependencies": { - "@aws-cdk/aws-service-spec": "^0.1.36", - "@aws-cdk/service-spec-types": "^0.0.103", + "@aws-cdk/aws-service-spec": "^0.1.37", + "@aws-cdk/service-spec-types": "^0.0.104", "chalk": "^4", "diff": "^5.2.0", "fast-deep-equal": "^3.1.3", diff --git a/packages/@aws-cdk/integ-runner/package.json b/packages/@aws-cdk/integ-runner/package.json index 60e68d52c8819..ea18202dc0dd9 100644 --- a/packages/@aws-cdk/integ-runner/package.json +++ b/packages/@aws-cdk/integ-runner/package.json @@ -74,7 +74,7 @@ "@aws-cdk/cloud-assembly-schema": "^38.0.0", "@aws-cdk/cloudformation-diff": "0.0.0", "@aws-cdk/cx-api": "0.0.0", - "@aws-cdk/aws-service-spec": "^0.1.36", + "@aws-cdk/aws-service-spec": "^0.1.37", "cdk-assets": "3.0.0-rc.32", "@aws-cdk/cdk-cli-wrapper": "0.0.0", "aws-cdk": "0.0.0", diff --git a/packages/aws-cdk-lib/aws-invoicing/.jsiirc.json b/packages/aws-cdk-lib/aws-invoicing/.jsiirc.json new file mode 100644 index 0000000000000..a0688b60d6628 --- /dev/null +++ b/packages/aws-cdk-lib/aws-invoicing/.jsiirc.json @@ -0,0 +1,13 @@ +{ + "targets": { + "java": { + "package": "software.amazon.awscdk.services.invoicing" + }, + "dotnet": { + "package": "Amazon.CDK.AWS.Invoicing" + }, + "python": { + "module": "aws_cdk.aws_invoicing" + } + } +} diff --git a/packages/aws-cdk-lib/aws-invoicing/README.md b/packages/aws-cdk-lib/aws-invoicing/README.md new file mode 100644 index 0000000000000..f49edcf2601e3 --- /dev/null +++ b/packages/aws-cdk-lib/aws-invoicing/README.md @@ -0,0 +1,39 @@ +# AWS::Invoicing 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 nofixture +import * as invoicing from 'aws-cdk-lib/aws-invoicing'; +``` + + + +There are no official hand-written ([L2](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib)) constructs for this service yet. Here are some suggestions on how to proceed: + +- Search [Construct Hub for Invoicing construct libraries](https://constructs.dev/search?q=invoicing) +- Use the automatically generated [L1](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_l1_using) constructs, in the same way you would use [the CloudFormation AWS::Invoicing resources](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_Invoicing.html) directly. + + + + +There are no hand-written ([L2](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib)) constructs for this service yet. +However, you can still use the automatically generated [L1](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_l1_using) constructs, and use this service exactly as you would using CloudFormation directly. + +For more information on the resources and properties available for this service, see the [CloudFormation documentation for AWS::Invoicing](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_Invoicing.html). + +(Read the [CDK Contributing Guide](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and submit an RFC if you are interested in contributing to this construct library.) + + diff --git a/packages/aws-cdk-lib/aws-invoicing/index.ts b/packages/aws-cdk-lib/aws-invoicing/index.ts new file mode 100644 index 0000000000000..f41a696fd204d --- /dev/null +++ b/packages/aws-cdk-lib/aws-invoicing/index.ts @@ -0,0 +1 @@ +export * from './lib'; diff --git a/packages/aws-cdk-lib/aws-invoicing/lib/index.ts b/packages/aws-cdk-lib/aws-invoicing/lib/index.ts new file mode 100644 index 0000000000000..479c320abc55f --- /dev/null +++ b/packages/aws-cdk-lib/aws-invoicing/lib/index.ts @@ -0,0 +1,2 @@ +// AWS::Invoicing Cloudformation Resources +export * from './invoicing.generated'; diff --git a/packages/aws-cdk-lib/index.ts b/packages/aws-cdk-lib/index.ts index b859427964915..3a1ed040cadae 100644 --- a/packages/aws-cdk-lib/index.ts +++ b/packages/aws-cdk-lib/index.ts @@ -131,6 +131,7 @@ export * as aws_imagebuilder from './aws-imagebuilder'; export * as aws_inspector from './aws-inspector'; export * as aws_inspectorv2 from './aws-inspectorv2'; export * as aws_internetmonitor from './aws-internetmonitor'; +export * as aws_invoicing from './aws-invoicing'; export * as aws_iot from './aws-iot'; export * as aws_iot1click from './aws-iot1click'; export * as aws_iotanalytics from './aws-iotanalytics'; diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json index 7d509f2ada438..398a110c5989b 100644 --- a/packages/aws-cdk-lib/package.json +++ b/packages/aws-cdk-lib/package.json @@ -136,7 +136,7 @@ "mime-types": "^2.1.35" }, "devDependencies": { - "@aws-cdk/aws-service-spec": "^0.1.36", + "@aws-cdk/aws-service-spec": "^0.1.37", "@aws-cdk/cdk-build-tools": "0.0.0", "@aws-cdk/custom-resource-handlers": "0.0.0", "@aws-cdk/pkglint": "0.0.0", @@ -345,6 +345,7 @@ "./aws-inspector": "./aws-inspector/index.js", "./aws-inspectorv2": "./aws-inspectorv2/index.js", "./aws-internetmonitor": "./aws-internetmonitor/index.js", + "./aws-invoicing": "./aws-invoicing/index.js", "./aws-iot": "./aws-iot/index.js", "./aws-iot1click": "./aws-iot1click/index.js", "./aws-iotanalytics": "./aws-iotanalytics/index.js", diff --git a/packages/aws-cdk-lib/scripts/scope-map.json b/packages/aws-cdk-lib/scripts/scope-map.json index f6f3a1375d753..586b54aede737 100644 --- a/packages/aws-cdk-lib/scripts/scope-map.json +++ b/packages/aws-cdk-lib/scripts/scope-map.json @@ -353,6 +353,9 @@ "aws-internetmonitor": [ "AWS::InternetMonitor" ], + "aws-invoicing": [ + "AWS::Invoicing" + ], "aws-iot": [ "AWS::IoT" ], diff --git a/tools/@aws-cdk/spec2cdk/package.json b/tools/@aws-cdk/spec2cdk/package.json index b2e9aa8f606d0..b3ea047386690 100644 --- a/tools/@aws-cdk/spec2cdk/package.json +++ b/tools/@aws-cdk/spec2cdk/package.json @@ -32,9 +32,9 @@ }, "license": "Apache-2.0", "dependencies": { - "@aws-cdk/aws-service-spec": "^0.1.36", - "@aws-cdk/service-spec-importers": "^0.0.57", - "@aws-cdk/service-spec-types": "^0.0.103", + "@aws-cdk/aws-service-spec": "^0.1.37", + "@aws-cdk/service-spec-importers": "^0.0.58", + "@aws-cdk/service-spec-types": "^0.0.104", "@cdklabs/tskb": "^0.0.3", "@cdklabs/typewriter": "^0.0.3", "camelcase": "^6", diff --git a/yarn.lock b/yarn.lock index a808475e25a25..e6708045bb24c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -63,12 +63,12 @@ resolved "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.1.0.tgz#6d3c7860354d4856a7e75375f2f0ecab313b4989" integrity sha512-7bY3J8GCVxLupn/kNmpPc5VJz8grx+4RKfnnJiO1LG+uxkZfANZG3RMHhE+qQxxwkyQ9/MfPtTpf748UhR425A== -"@aws-cdk/aws-service-spec@^0.1.36": - version "0.1.36" - resolved "https://registry.npmjs.org/@aws-cdk/aws-service-spec/-/aws-service-spec-0.1.36.tgz#a64c518bd246c7d7ab1fdda12da6e1bbb0a34822" - integrity sha512-Pgs70xwtV4tUdDpslutB3+JqBp1+Q9WLd3kVkgTyUiGJU7Db6wQ9oLHNKRF41mtO31VYo+oyVmH8eomFfqvXew== +"@aws-cdk/aws-service-spec@^0.1.37": + version "0.1.37" + resolved "https://registry.npmjs.org/@aws-cdk/aws-service-spec/-/aws-service-spec-0.1.37.tgz#39e78a07079fc276f2f2bfdb31c3c7226939a04a" + integrity sha512-WFGAvjslG8Jdj9XmzDtV4JbsWEmLj8K9pA882mc6iNK59l4ocGt2GqS4n3JuzRdzoEpzcVYqfgrqGUuV1ez7vg== dependencies: - "@aws-cdk/service-spec-types" "^0.0.103" + "@aws-cdk/service-spec-types" "^0.0.104" "@cdklabs/tskb" "^0.0.3" "@aws-cdk/cloud-assembly-schema@^38.0.0", "@aws-cdk/cloud-assembly-schema@^38.0.1": @@ -106,12 +106,12 @@ resolved "https://registry.npmjs.org/@aws-cdk/lambda-layer-kubectl-v31/-/lambda-layer-kubectl-v31-2.0.0.tgz#d87799d7d0d5dad77af45281a36942e4b7996b6b" integrity sha512-8JI0sMDbqCubOyt1TbQFEwicYok9KYSrNSfzREgjGJcoPy17/Kd0gbe44ATyLMfjae7dExUhhwKMhr6GK7Hmrw== -"@aws-cdk/service-spec-importers@^0.0.57": - version "0.0.57" - resolved "https://registry.npmjs.org/@aws-cdk/service-spec-importers/-/service-spec-importers-0.0.57.tgz#d4c6021e7477bae4f86f0db8f2d85cabcb6a2840" - integrity sha512-7i5ZUFHNeLvvJo9bWVn9HQC5y+kka+sNgtAc1apzqx1IeL0TW/11ZQiWCav+uIhs60xnZZHgeT+iSgpMyApBCw== +"@aws-cdk/service-spec-importers@^0.0.58": + version "0.0.58" + resolved "https://registry.npmjs.org/@aws-cdk/service-spec-importers/-/service-spec-importers-0.0.58.tgz#8fdd3ef8d10247cb948f5021bd67c9d56f47ef62" + integrity sha512-qyjPFYGeuqVxrR5xa4GmDeL/w24nmbaE1gGbc/Li5Xd7f4jINvCjCV9SMaMXz5o/nJRpKs6BQVpMWWYKWXr97A== dependencies: - "@aws-cdk/service-spec-types" "^0.0.102" + "@aws-cdk/service-spec-types" "^0.0.104" "@cdklabs/tskb" "^0.0.3" ajv "^6" canonicalize "^2.0.0" @@ -122,17 +122,10 @@ glob "^8" sort-json "^2.0.1" -"@aws-cdk/service-spec-types@^0.0.102": - version "0.0.102" - resolved "https://registry.npmjs.org/@aws-cdk/service-spec-types/-/service-spec-types-0.0.102.tgz#1a7554556a4890c6ccfe62b7d15c4f9297c11e3d" - integrity sha512-CL9hyaPB4C4mcMinkO56uRHFlgtuy57LlpzQv3Qc3Z9FIElK8KG76GDD1SCy+FE/7B13EpIVJmJFRCvjJvyNng== - dependencies: - "@cdklabs/tskb" "^0.0.3" - -"@aws-cdk/service-spec-types@^0.0.103": - version "0.0.103" - resolved "https://registry.npmjs.org/@aws-cdk/service-spec-types/-/service-spec-types-0.0.103.tgz#0519026090f40fb1937f84683800594662ab9f41" - integrity sha512-gt2mx0GpwmY0jQxDtxREskqHGtAvUwRU5YtTA65cdGwkjh/TXlw7nUXnHgG+JRQFrfvCIgqL1D+SB18UAo2zvA== +"@aws-cdk/service-spec-types@^0.0.104": + version "0.0.104" + resolved "https://registry.npmjs.org/@aws-cdk/service-spec-types/-/service-spec-types-0.0.104.tgz#9f7e632ee00c5f6d2c68b3950fa118c663beef64" + integrity sha512-VMDgWLLmCXV81VzI9tOGZ6AQWOSQvXEGlIemaJZRmO3mK9foZtO068PFZbY92h/5BO0WCUh5JJII5g3pFqKQRQ== dependencies: "@cdklabs/tskb" "^0.0.3" @@ -12724,6 +12717,11 @@ ip-regex@^4.1.0: resolved "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + is-arguments@^1.0.4: version "1.1.1" resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" @@ -12732,11 +12730,6 @@ is-arguments@^1.0.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - is-array-buffer@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz#7a1f92b3d61edd2bc65d24f130530ea93d7fae98" @@ -16699,11 +16692,6 @@ qrcode-terminal@^0.12.0: resolved "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819" integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== - qs@6.13.0: version "6.13.0" resolved "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" @@ -16711,6 +16699,11 @@ qs@6.13.0: dependencies: side-channel "^1.0.6" +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -18683,16 +18676,16 @@ utility-types@^3.10.0: resolved "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz#607c40edb4f258915e901ea7995607fdf319424c" integrity sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw== -uuid@8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz#bc6ccf91b5ff0ac07bbcdbf1c7c4e150db4dbb6c" - integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw== - utils-merge@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== +uuid@8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz#bc6ccf91b5ff0ac07bbcdbf1c7c4e150db4dbb6c" + integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw== + uuid@^10.0.0: version "10.0.0" resolved "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294" @@ -19091,7 +19084,7 @@ xmlbuilder@~11.0.0: resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== -xtend@~4.0.1: +xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==