From 9076d6e522002357da307bc09417a5b12bcfb35e Mon Sep 17 00:00:00 2001 From: GZ Date: Thu, 14 Mar 2024 15:17:20 -0700 Subject: [PATCH 1/4] fix(kms): kms key grant methods misidentify region when enclosing stack is different region (#29315) ### Issue # (if applicable) Closes https://github.com/aws/aws-cdk/issues/29308 ### Reason for this change This problem is grant() determines the region of a Key using Stack.of(key).region, however the enclosing Stack's region may differ to that of the actual resource. When this happens, the IAM policy generated allows a `*` resource which is against the least privilege rule. ### Description of changes KMS key already has `env` value on account and region, use this first. If not exist, use stack account and region. ### Description of how you validated changes New unit test ### 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* --------- Co-authored-by: paulhcsun <47882901+paulhcsun@users.noreply.github.com> --- packages/aws-cdk-lib/aws-kms/lib/key.ts | 12 ++++ packages/aws-cdk-lib/aws-kms/test/key.test.ts | 61 +++++++++++++++++++ packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md | 18 +++++- packages/aws-cdk-lib/cx-api/README.md | 17 ++++++ packages/aws-cdk-lib/cx-api/lib/features.ts | 13 ++++ 5 files changed, 120 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-kms/lib/key.ts b/packages/aws-cdk-lib/aws-kms/lib/key.ts index 1f2c13e0615c7..ba5d33c2988e9 100644 --- a/packages/aws-cdk-lib/aws-kms/lib/key.ts +++ b/packages/aws-cdk-lib/aws-kms/lib/key.ts @@ -262,6 +262,12 @@ abstract class KeyBase extends Resource implements IKey { } const bucketStack = Stack.of(this); const identityStack = Stack.of(grantee.grantPrincipal); + + if (FeatureFlags.of(this).isEnabled(cxapi.KMS_REDUCE_CROSS_ACCOUNT_REGION_POLICY_SCOPE)) { + // if two compared stacks have the same region, this should return 'false' since it's from the + // same region; if two stacks have different region, then compare env.region + return bucketStack.region !== identityStack.region && this.env.region !== identityStack.region; + } return bucketStack.region !== identityStack.region; } @@ -271,6 +277,12 @@ abstract class KeyBase extends Resource implements IKey { } const bucketStack = Stack.of(this); const identityStack = Stack.of(grantee.grantPrincipal); + + if (FeatureFlags.of(this).isEnabled(cxapi.KMS_REDUCE_CROSS_ACCOUNT_REGION_POLICY_SCOPE)) { + // if two compared stacks have the same region, this should return 'false' since it's from the + // same region; if two stacks have different region, then compare env.account + return bucketStack.account !== identityStack.account && this.env.account !== identityStack.account; + } return bucketStack.account !== identityStack.account; } } diff --git a/packages/aws-cdk-lib/aws-kms/test/key.test.ts b/packages/aws-cdk-lib/aws-kms/test/key.test.ts index 9c0ce901dd910..3493c31dff3ac 100644 --- a/packages/aws-cdk-lib/aws-kms/test/key.test.ts +++ b/packages/aws-cdk-lib/aws-kms/test/key.test.ts @@ -2,6 +2,7 @@ import { describeDeprecated } from '@aws-cdk/cdk-build-tools'; import { Match, Template } from '../../assertions'; import * as iam from '../../aws-iam'; import * as cdk from '../../core'; +import * as cxapi from '../../cx-api'; import * as kms from '../lib'; import { KeySpec, KeyUsage } from '../lib'; @@ -81,6 +82,66 @@ describe('key policies', () => { }); }); + test('cross region key with iam role grant', () => { + const app = new cdk.App({ context: { [cxapi.KMS_REDUCE_CROSS_ACCOUNT_REGION_POLICY_SCOPE]: true } }); + const stack = new cdk.Stack(app, 'test-stack', { env: { account: '000000000000', region: 'us-west-2' } }); + const key = kms.Key.fromKeyArn( + stack, + 'Key', + 'arn:aws:kms:eu-north-1:000000000000:key/e3ab59e5-3dc3-4bc4-9c3f-c790231d2287', + ); + + const roleStack = new cdk.Stack(app, 'RoleStack', { + env: { account: '000000000000', region: 'eu-north-1' }, + }); + const role = new iam.Role(roleStack, 'Role', { + assumedBy: new iam.AccountPrincipal('000000000000'), + }); + key.grantEncryptDecrypt(role); + + Template.fromStack(roleStack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Effect: 'Allow', + Resource: 'arn:aws:kms:eu-north-1:000000000000:key/e3ab59e5-3dc3-4bc4-9c3f-c790231d2287', + }, + ], + Version: '2012-10-17', + }, + }); + }); + + test('cross region key with iam role grant when feature flag is disabled', () => { + const app = new cdk.App({ context: { [cxapi.KMS_REDUCE_CROSS_ACCOUNT_REGION_POLICY_SCOPE]: false } }); + const stack = new cdk.Stack(app, 'test-stack', { env: { account: '000000000000', region: 'us-west-2' } }); + const key = kms.Key.fromKeyArn( + stack, + 'Key', + 'arn:aws:kms:eu-north-1:000000000000:key/e3ab59e5-3dc3-4bc4-9c3f-c790231d2287', + ); + + const roleStack = new cdk.Stack(app, 'RoleStack', { + env: { account: '000000000000', region: 'eu-north-1' }, + }); + const role = new iam.Role(roleStack, 'Role', { + assumedBy: new iam.AccountPrincipal('000000000000'), + }); + key.grantEncryptDecrypt(role); + + Template.fromStack(roleStack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Effect: 'Allow', + Resource: '*', + }, + ], + Version: '2012-10-17', + }, + }); + }); + test('can append to the default key policy', () => { const stack = new cdk.Stack(); const statement = new iam.PolicyStatement({ resources: ['*'], actions: ['kms:Put*'] }); diff --git a/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md b/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md index 86bb8373fa803..d73e3b1657e52 100644 --- a/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +++ b/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md @@ -66,6 +66,7 @@ Flags come in three types: | [@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction](#aws-cdkaws-cloudwatch-actionschangelambdapermissionlogicalidforlambdaaction) | When enabled, the logical ID of a Lambda permission for a Lambda action includes an alarm ID. | 2.124.0 | (fix) | | [@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse](#aws-cdkaws-codepipelinecrossaccountkeysdefaultvaluetofalse) | Enables Pipeline to set the default value for crossAccountKeys to false. | 2.127.0 | (default) | | [@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2](#aws-cdkaws-codepipelinedefaultpipelinetypetov2) | Enables Pipeline to set the default pipeline type to V2. | V2NEXT | (default) | +| [@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope](#aws-cdkaws-kmsreducecrossaccountregionpolicyscope) | When enabled, IAM Policy created from KMS key grant will reduce the resource scope to this key only. | V2NEXT | (fix) | @@ -122,7 +123,8 @@ The following json shows the current recommended set of flags, as `cdk init` wou "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, - "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true } } ``` @@ -1249,4 +1251,18 @@ construct, the construct automatically defaults the value of this property to `P **Compatibility with old behavior:** Pass `pipelineType: PipelineType.V1` to `Pipeline` construct to restore the previous behavior. +### @aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope + +*When enabled, IAM Policy created from KMS key grant will reduce the resource scope to this key only.* (fix) + +When this feature flag is enabled and calling KMS key grant method, the created IAM policy will reduce the resource scope from +'*' to this specific granting KMS key. + + +| Since | Default | Recommended | +| ----- | ----- | ----- | +| (not in v1) | | | +| V2NEXT | `false` | `true` | + + diff --git a/packages/aws-cdk-lib/cx-api/README.md b/packages/aws-cdk-lib/cx-api/README.md index 394a47009b24d..cdbd86f3ae08e 100644 --- a/packages/aws-cdk-lib/cx-api/README.md +++ b/packages/aws-cdk-lib/cx-api/README.md @@ -292,3 +292,20 @@ _cdk.json_ } } ``` + +* `@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope` + +Reduce resource scope of the IAM Policy created from KMS key grant to granting key only. + +When this feature flag is enabled and calling KMS key grant method, the created IAM policy will reduce the resource scope from +'*' to this specific granting KMS key. + +_cdk.json_ + +```json +{ + "context": { + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true + } +} +``` diff --git a/packages/aws-cdk-lib/cx-api/lib/features.ts b/packages/aws-cdk-lib/cx-api/lib/features.ts index 28b15de29a57c..7a241858c5f82 100644 --- a/packages/aws-cdk-lib/cx-api/lib/features.ts +++ b/packages/aws-cdk-lib/cx-api/lib/features.ts @@ -100,6 +100,7 @@ export const CODECOMMIT_SOURCE_ACTION_DEFAULT_BRANCH_NAME = '@aws-cdk/aws-codepi export const LAMBDA_PERMISSION_LOGICAL_ID_FOR_LAMBDA_ACTION = '@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction'; export const CODEPIPELINE_CROSS_ACCOUNT_KEYS_DEFAULT_VALUE_TO_FALSE = '@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse'; export const CODEPIPELINE_DEFAULT_PIPELINE_TYPE_TO_V2 = '@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2'; +export const KMS_REDUCE_CROSS_ACCOUNT_REGION_POLICY_SCOPE = '@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope'; export const FLAGS: Record = { ////////////////////////////////////////////////////////////////////// @@ -1021,6 +1022,18 @@ export const FLAGS: Record = { recommendedValue: true, compatibilityWithOldBehaviorMd: 'Pass `pipelineType: PipelineType.V1` to `Pipeline` construct to restore the previous behavior.', }, + + ////////////////////////////////////////////////////////////////////// + [KMS_REDUCE_CROSS_ACCOUNT_REGION_POLICY_SCOPE]: { + type: FlagType.BugFix, + summary: 'When enabled, IAM Policy created from KMS key grant will reduce the resource scope to this key only.', + detailsMd: ` + When this feature flag is enabled and calling KMS key grant method, the created IAM policy will reduce the resource scope from + '*' to this specific granting KMS key. + `, + introducedIn: { v2: 'V2NEXT' }, + recommendedValue: true, + }, }; const CURRENT_MV = 'v2'; From bc9d0b44ef0717c6bd98fd37ab7883d830094461 Mon Sep 17 00:00:00 2001 From: kazuho cryer-shinozuka Date: Fri, 15 Mar 2024 07:46:35 +0900 Subject: [PATCH 2/4] feat(rds): eliminating the need for explicit `secret.grantRead()` invokes when using DataAPI with Aurora cluster (#29399) ### Issue # (if applicable) Closes #29362. ### Reason for this change As discussed [there](https://github.com/aws/aws-cdk/pull/29338#discussion_r1512026791), we should invoke `secret.grantRead()` explicitly when using DataAPI with Aurora cluster. Because it's inconvenient for users, I made `secret.grantRead()` be invoked within `cluster.grantDataApiAccess()`. ### Description of changes - move `cluster.secret` from `DatabaseClusterNew` to `DatabaseClusterBase` to use it within `DatabaseClusterBase.grantDataApiAccess()` - add `secret.grantRead()` in `cluster.grantDataApiAccess()` - add `secret` property to `DatabaseClusterAttributes` #### Points of concern `DatabaseClusterBase` class is extended by `ImportedDatabaseCluster` class. Therefore, it is necessary to define `ImportedDatabaseCluster.secret`. I simply added `secret` props to `DatabaseClusterAttributes` but I cannot believe this is the best way. Other ways are.. - add `secretArn` to `DatabaseClusterAttributes` - don't add secret info and `ImportedDatabaseCluster.secret` becomes always undefined ### Description of how you validated changes ### 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* --- ...sets.json => cluster-data-api.assets.json} | 6 +- ...te.json => cluster-data-api.template.json} | 48 ++--- .../integ.json | 2 +- .../manifest.json | 90 ++++----- .../tree.json | 174 +++++++++--------- .../aws-rds/test/integ.cluster-data-api.ts | 3 +- packages/aws-cdk-lib/aws-rds/README.md | 2 - .../aws-cdk-lib/aws-rds/lib/cluster-ref.ts | 7 + packages/aws-cdk-lib/aws-rds/lib/cluster.ts | 13 +- .../aws-cdk-lib/aws-rds/test/cluster.test.ts | 10 + 10 files changed, 186 insertions(+), 169 deletions(-) rename packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/{cluster-kerberos.assets.json => cluster-data-api.assets.json} (82%) rename packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/{cluster-kerberos.template.json => cluster-data-api.template.json} (95%) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/cluster-kerberos.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/cluster-data-api.assets.json similarity index 82% rename from packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/cluster-kerberos.assets.json rename to packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/cluster-data-api.assets.json index df5838befd59b..b800063a0def3 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/cluster-kerberos.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/cluster-data-api.assets.json @@ -14,15 +14,15 @@ } } }, - "30c06211c853a3fd7c30a7376cbd63b2155519a67ba90ed0a731aa67dcd179e2": { + "b2fb40833cc33946a3656aa5e2cdb19e4259b9a84dbabe7a6559ad319344359d": { "source": { - "path": "cluster-kerberos.template.json", + "path": "cluster-data-api.template.json", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "30c06211c853a3fd7c30a7376cbd63b2155519a67ba90ed0a731aa67dcd179e2.json", + "objectKey": "b2fb40833cc33946a3656aa5e2cdb19e4259b9a84dbabe7a6559ad319344359d.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/cluster-kerberos.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/cluster-data-api.template.json similarity index 95% rename from packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/cluster-kerberos.template.json rename to packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/cluster-data-api.template.json index 43e8e05ad0450..76ea729cef991 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/cluster-kerberos.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/cluster-data-api.template.json @@ -10,7 +10,7 @@ "Tags": [ { "Key": "Name", - "Value": "cluster-kerberos/VPC" + "Value": "cluster-data-api/VPC" } ] } @@ -39,7 +39,7 @@ }, { "Key": "Name", - "Value": "cluster-kerberos/VPC/PublicSubnet1" + "Value": "cluster-data-api/VPC/PublicSubnet1" } ], "VpcId": { @@ -53,7 +53,7 @@ "Tags": [ { "Key": "Name", - "Value": "cluster-kerberos/VPC/PublicSubnet1" + "Value": "cluster-data-api/VPC/PublicSubnet1" } ], "VpcId": { @@ -94,7 +94,7 @@ "Tags": [ { "Key": "Name", - "Value": "cluster-kerberos/VPC/PublicSubnet1" + "Value": "cluster-data-api/VPC/PublicSubnet1" } ] } @@ -114,7 +114,7 @@ "Tags": [ { "Key": "Name", - "Value": "cluster-kerberos/VPC/PublicSubnet1" + "Value": "cluster-data-api/VPC/PublicSubnet1" } ] }, @@ -147,7 +147,7 @@ }, { "Key": "Name", - "Value": "cluster-kerberos/VPC/PublicSubnet2" + "Value": "cluster-data-api/VPC/PublicSubnet2" } ], "VpcId": { @@ -161,7 +161,7 @@ "Tags": [ { "Key": "Name", - "Value": "cluster-kerberos/VPC/PublicSubnet2" + "Value": "cluster-data-api/VPC/PublicSubnet2" } ], "VpcId": { @@ -202,7 +202,7 @@ "Tags": [ { "Key": "Name", - "Value": "cluster-kerberos/VPC/PublicSubnet2" + "Value": "cluster-data-api/VPC/PublicSubnet2" } ] } @@ -222,7 +222,7 @@ "Tags": [ { "Key": "Name", - "Value": "cluster-kerberos/VPC/PublicSubnet2" + "Value": "cluster-data-api/VPC/PublicSubnet2" } ] }, @@ -255,7 +255,7 @@ }, { "Key": "Name", - "Value": "cluster-kerberos/VPC/PrivateSubnet1" + "Value": "cluster-data-api/VPC/PrivateSubnet1" } ], "VpcId": { @@ -269,7 +269,7 @@ "Tags": [ { "Key": "Name", - "Value": "cluster-kerberos/VPC/PrivateSubnet1" + "Value": "cluster-data-api/VPC/PrivateSubnet1" } ], "VpcId": { @@ -324,7 +324,7 @@ }, { "Key": "Name", - "Value": "cluster-kerberos/VPC/PrivateSubnet2" + "Value": "cluster-data-api/VPC/PrivateSubnet2" } ], "VpcId": { @@ -338,7 +338,7 @@ "Tags": [ { "Key": "Name", - "Value": "cluster-kerberos/VPC/PrivateSubnet2" + "Value": "cluster-data-api/VPC/PrivateSubnet2" } ], "VpcId": { @@ -375,7 +375,7 @@ "Tags": [ { "Key": "Name", - "Value": "cluster-kerberos/VPC" + "Value": "cluster-data-api/VPC" } ] } @@ -543,6 +543,16 @@ "Properties": { "PolicyDocument": { "Statement": [ + { + "Action": [ + "secretsmanager:DescribeSecret", + "secretsmanager:GetSecretValue" + ], + "Effect": "Allow", + "Resource": { + "Ref": "DatabaseSecretAttachmentE5D1B020" + } + }, { "Action": [ "rds-data:BatchExecuteStatement", @@ -575,16 +585,6 @@ ] ] } - }, - { - "Action": [ - "secretsmanager:DescribeSecret", - "secretsmanager:GetSecretValue" - ], - "Effect": "Allow", - "Resource": { - "Ref": "DatabaseSecretAttachmentE5D1B020" - } } ], "Version": "2012-10-17" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/integ.json index 9d07906800ea0..f58e123a17c69 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/integ.json @@ -3,7 +3,7 @@ "testCases": { "integ-cluster-data-api/DefaultTest": { "stacks": [ - "cluster-kerberos" + "cluster-data-api" ], "assertionStack": "integ-cluster-data-api/DefaultTest/DeployAssert", "assertionStackName": "integclusterdataapiDefaultTestDeployAssertACD87C08" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/manifest.json index 97dcacd1833fa..873f1cd7cb6c8 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/manifest.json @@ -1,28 +1,28 @@ { "version": "36.0.0", "artifacts": { - "cluster-kerberos.assets": { + "cluster-data-api.assets": { "type": "cdk:asset-manifest", "properties": { - "file": "cluster-kerberos.assets.json", + "file": "cluster-data-api.assets.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" } }, - "cluster-kerberos": { + "cluster-data-api": { "type": "aws:cloudformation:stack", "environment": "aws://unknown-account/unknown-region", "properties": { - "templateFile": "cluster-kerberos.template.json", + "templateFile": "cluster-data-api.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}/30c06211c853a3fd7c30a7376cbd63b2155519a67ba90ed0a731aa67dcd179e2.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/b2fb40833cc33946a3656aa5e2cdb19e4259b9a84dbabe7a6559ad319344359d.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ - "cluster-kerberos.assets" + "cluster-data-api.assets" ], "lookupRole": { "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", @@ -31,233 +31,233 @@ } }, "dependencies": [ - "cluster-kerberos.assets" + "cluster-data-api.assets" ], "metadata": { - "/cluster-kerberos/VPC/Resource": [ + "/cluster-data-api/VPC/Resource": [ { "type": "aws:cdk:logicalId", "data": "VPCB9E5F0B4" } ], - "/cluster-kerberos/VPC/PublicSubnet1/Subnet": [ + "/cluster-data-api/VPC/PublicSubnet1/Subnet": [ { "type": "aws:cdk:logicalId", "data": "VPCPublicSubnet1SubnetB4246D30" } ], - "/cluster-kerberos/VPC/PublicSubnet1/RouteTable": [ + "/cluster-data-api/VPC/PublicSubnet1/RouteTable": [ { "type": "aws:cdk:logicalId", "data": "VPCPublicSubnet1RouteTableFEE4B781" } ], - "/cluster-kerberos/VPC/PublicSubnet1/RouteTableAssociation": [ + "/cluster-data-api/VPC/PublicSubnet1/RouteTableAssociation": [ { "type": "aws:cdk:logicalId", "data": "VPCPublicSubnet1RouteTableAssociation0B0896DC" } ], - "/cluster-kerberos/VPC/PublicSubnet1/DefaultRoute": [ + "/cluster-data-api/VPC/PublicSubnet1/DefaultRoute": [ { "type": "aws:cdk:logicalId", "data": "VPCPublicSubnet1DefaultRoute91CEF279" } ], - "/cluster-kerberos/VPC/PublicSubnet1/EIP": [ + "/cluster-data-api/VPC/PublicSubnet1/EIP": [ { "type": "aws:cdk:logicalId", "data": "VPCPublicSubnet1EIP6AD938E8" } ], - "/cluster-kerberos/VPC/PublicSubnet1/NATGateway": [ + "/cluster-data-api/VPC/PublicSubnet1/NATGateway": [ { "type": "aws:cdk:logicalId", "data": "VPCPublicSubnet1NATGatewayE0556630" } ], - "/cluster-kerberos/VPC/PublicSubnet2/Subnet": [ + "/cluster-data-api/VPC/PublicSubnet2/Subnet": [ { "type": "aws:cdk:logicalId", "data": "VPCPublicSubnet2Subnet74179F39" } ], - "/cluster-kerberos/VPC/PublicSubnet2/RouteTable": [ + "/cluster-data-api/VPC/PublicSubnet2/RouteTable": [ { "type": "aws:cdk:logicalId", "data": "VPCPublicSubnet2RouteTable6F1A15F1" } ], - "/cluster-kerberos/VPC/PublicSubnet2/RouteTableAssociation": [ + "/cluster-data-api/VPC/PublicSubnet2/RouteTableAssociation": [ { "type": "aws:cdk:logicalId", "data": "VPCPublicSubnet2RouteTableAssociation5A808732" } ], - "/cluster-kerberos/VPC/PublicSubnet2/DefaultRoute": [ + "/cluster-data-api/VPC/PublicSubnet2/DefaultRoute": [ { "type": "aws:cdk:logicalId", "data": "VPCPublicSubnet2DefaultRouteB7481BBA" } ], - "/cluster-kerberos/VPC/PublicSubnet2/EIP": [ + "/cluster-data-api/VPC/PublicSubnet2/EIP": [ { "type": "aws:cdk:logicalId", "data": "VPCPublicSubnet2EIP4947BC00" } ], - "/cluster-kerberos/VPC/PublicSubnet2/NATGateway": [ + "/cluster-data-api/VPC/PublicSubnet2/NATGateway": [ { "type": "aws:cdk:logicalId", "data": "VPCPublicSubnet2NATGateway3C070193" } ], - "/cluster-kerberos/VPC/PrivateSubnet1/Subnet": [ + "/cluster-data-api/VPC/PrivateSubnet1/Subnet": [ { "type": "aws:cdk:logicalId", "data": "VPCPrivateSubnet1Subnet8BCA10E0" } ], - "/cluster-kerberos/VPC/PrivateSubnet1/RouteTable": [ + "/cluster-data-api/VPC/PrivateSubnet1/RouteTable": [ { "type": "aws:cdk:logicalId", "data": "VPCPrivateSubnet1RouteTableBE8A6027" } ], - "/cluster-kerberos/VPC/PrivateSubnet1/RouteTableAssociation": [ + "/cluster-data-api/VPC/PrivateSubnet1/RouteTableAssociation": [ { "type": "aws:cdk:logicalId", "data": "VPCPrivateSubnet1RouteTableAssociation347902D1" } ], - "/cluster-kerberos/VPC/PrivateSubnet1/DefaultRoute": [ + "/cluster-data-api/VPC/PrivateSubnet1/DefaultRoute": [ { "type": "aws:cdk:logicalId", "data": "VPCPrivateSubnet1DefaultRouteAE1D6490" } ], - "/cluster-kerberos/VPC/PrivateSubnet2/Subnet": [ + "/cluster-data-api/VPC/PrivateSubnet2/Subnet": [ { "type": "aws:cdk:logicalId", "data": "VPCPrivateSubnet2SubnetCFCDAA7A" } ], - "/cluster-kerberos/VPC/PrivateSubnet2/RouteTable": [ + "/cluster-data-api/VPC/PrivateSubnet2/RouteTable": [ { "type": "aws:cdk:logicalId", "data": "VPCPrivateSubnet2RouteTable0A19E10E" } ], - "/cluster-kerberos/VPC/PrivateSubnet2/RouteTableAssociation": [ + "/cluster-data-api/VPC/PrivateSubnet2/RouteTableAssociation": [ { "type": "aws:cdk:logicalId", "data": "VPCPrivateSubnet2RouteTableAssociation0C73D413" } ], - "/cluster-kerberos/VPC/PrivateSubnet2/DefaultRoute": [ + "/cluster-data-api/VPC/PrivateSubnet2/DefaultRoute": [ { "type": "aws:cdk:logicalId", "data": "VPCPrivateSubnet2DefaultRouteF4F5CFD2" } ], - "/cluster-kerberos/VPC/IGW": [ + "/cluster-data-api/VPC/IGW": [ { "type": "aws:cdk:logicalId", "data": "VPCIGWB7E252D3" } ], - "/cluster-kerberos/VPC/VPCGW": [ + "/cluster-data-api/VPC/VPCGW": [ { "type": "aws:cdk:logicalId", "data": "VPCVPCGW99B986DC" } ], - "/cluster-kerberos/VPC/RestrictDefaultSecurityGroupCustomResource/Default": [ + "/cluster-data-api/VPC/RestrictDefaultSecurityGroupCustomResource/Default": [ { "type": "aws:cdk:logicalId", "data": "VPCRestrictDefaultSecurityGroupCustomResource59474679" } ], - "/cluster-kerberos/Custom::VpcRestrictDefaultSGCustomResourceProvider/Role": [ + "/cluster-data-api/Custom::VpcRestrictDefaultSGCustomResourceProvider/Role": [ { "type": "aws:cdk:logicalId", "data": "CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0" } ], - "/cluster-kerberos/Custom::VpcRestrictDefaultSGCustomResourceProvider/Handler": [ + "/cluster-data-api/Custom::VpcRestrictDefaultSGCustomResourceProvider/Handler": [ { "type": "aws:cdk:logicalId", "data": "CustomVpcRestrictDefaultSGCustomResourceProviderHandlerDC833E5E" } ], - "/cluster-kerberos/Function/ServiceRole/Resource": [ + "/cluster-data-api/Function/ServiceRole/Resource": [ { "type": "aws:cdk:logicalId", "data": "FunctionServiceRole675BB04A" } ], - "/cluster-kerberos/Function/ServiceRole/DefaultPolicy/Resource": [ + "/cluster-data-api/Function/ServiceRole/DefaultPolicy/Resource": [ { "type": "aws:cdk:logicalId", "data": "FunctionServiceRoleDefaultPolicy2F49994A" } ], - "/cluster-kerberos/Function/Resource": [ + "/cluster-data-api/Function/Resource": [ { "type": "aws:cdk:logicalId", "data": "Function76856677" } ], - "/cluster-kerberos/Database/Subnets/Default": [ + "/cluster-data-api/Database/Subnets/Default": [ { "type": "aws:cdk:logicalId", "data": "DatabaseSubnets56F17B9A" } ], - "/cluster-kerberos/Database/SecurityGroup/Resource": [ + "/cluster-data-api/Database/SecurityGroup/Resource": [ { "type": "aws:cdk:logicalId", "data": "DatabaseSecurityGroup5C91FDCB" } ], - "/cluster-kerberos/Database/Secret/Resource": [ + "/cluster-data-api/Database/Secret/Resource": [ { "type": "aws:cdk:logicalId", "data": "DatabaseSecret3B817195" } ], - "/cluster-kerberos/Database/Secret/Attachment/Resource": [ + "/cluster-data-api/Database/Secret/Attachment/Resource": [ { "type": "aws:cdk:logicalId", "data": "DatabaseSecretAttachmentE5D1B020" } ], - "/cluster-kerberos/Database/Resource": [ + "/cluster-data-api/Database/Resource": [ { "type": "aws:cdk:logicalId", "data": "DatabaseB269D8BB" } ], - "/cluster-kerberos/Database/writerInstance/Resource": [ + "/cluster-data-api/Database/writerInstance/Resource": [ { "type": "aws:cdk:logicalId", "data": "DatabasewriterInstanceEBFCC003" } ], - "/cluster-kerberos/BootstrapVersion": [ + "/cluster-data-api/BootstrapVersion": [ { "type": "aws:cdk:logicalId", "data": "BootstrapVersion" } ], - "/cluster-kerberos/CheckBootstrapVersion": [ + "/cluster-data-api/CheckBootstrapVersion": [ { "type": "aws:cdk:logicalId", "data": "CheckBootstrapVersion" } ] }, - "displayName": "cluster-kerberos" + "displayName": "cluster-data-api" }, "integclusterdataapiDefaultTestDeployAssertACD87C08.assets": { "type": "cdk:asset-manifest", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/tree.json index c9bbb077426b1..5b1165f6b9b53 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.js.snapshot/tree.json @@ -4,17 +4,17 @@ "id": "App", "path": "", "children": { - "cluster-kerberos": { - "id": "cluster-kerberos", - "path": "cluster-kerberos", + "cluster-data-api": { + "id": "cluster-data-api", + "path": "cluster-data-api", "children": { "VPC": { "id": "VPC", - "path": "cluster-kerberos/VPC", + "path": "cluster-data-api/VPC", "children": { "Resource": { "id": "Resource", - "path": "cluster-kerberos/VPC/Resource", + "path": "cluster-data-api/VPC/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::VPC", "aws:cdk:cloudformation:props": { @@ -25,7 +25,7 @@ "tags": [ { "key": "Name", - "value": "cluster-kerberos/VPC" + "value": "cluster-data-api/VPC" } ] } @@ -37,11 +37,11 @@ }, "PublicSubnet1": { "id": "PublicSubnet1", - "path": "cluster-kerberos/VPC/PublicSubnet1", + "path": "cluster-data-api/VPC/PublicSubnet1", "children": { "Subnet": { "id": "Subnet", - "path": "cluster-kerberos/VPC/PublicSubnet1/Subnet", + "path": "cluster-data-api/VPC/PublicSubnet1/Subnet", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", "aws:cdk:cloudformation:props": { @@ -66,7 +66,7 @@ }, { "key": "Name", - "value": "cluster-kerberos/VPC/PublicSubnet1" + "value": "cluster-data-api/VPC/PublicSubnet1" } ], "vpcId": { @@ -81,7 +81,7 @@ }, "Acl": { "id": "Acl", - "path": "cluster-kerberos/VPC/PublicSubnet1/Acl", + "path": "cluster-data-api/VPC/PublicSubnet1/Acl", "constructInfo": { "fqn": "aws-cdk-lib.Resource", "version": "0.0.0" @@ -89,14 +89,14 @@ }, "RouteTable": { "id": "RouteTable", - "path": "cluster-kerberos/VPC/PublicSubnet1/RouteTable", + "path": "cluster-data-api/VPC/PublicSubnet1/RouteTable", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", "aws:cdk:cloudformation:props": { "tags": [ { "key": "Name", - "value": "cluster-kerberos/VPC/PublicSubnet1" + "value": "cluster-data-api/VPC/PublicSubnet1" } ], "vpcId": { @@ -111,7 +111,7 @@ }, "RouteTableAssociation": { "id": "RouteTableAssociation", - "path": "cluster-kerberos/VPC/PublicSubnet1/RouteTableAssociation", + "path": "cluster-data-api/VPC/PublicSubnet1/RouteTableAssociation", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", "aws:cdk:cloudformation:props": { @@ -130,7 +130,7 @@ }, "DefaultRoute": { "id": "DefaultRoute", - "path": "cluster-kerberos/VPC/PublicSubnet1/DefaultRoute", + "path": "cluster-data-api/VPC/PublicSubnet1/DefaultRoute", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Route", "aws:cdk:cloudformation:props": { @@ -150,7 +150,7 @@ }, "EIP": { "id": "EIP", - "path": "cluster-kerberos/VPC/PublicSubnet1/EIP", + "path": "cluster-data-api/VPC/PublicSubnet1/EIP", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::EIP", "aws:cdk:cloudformation:props": { @@ -158,7 +158,7 @@ "tags": [ { "key": "Name", - "value": "cluster-kerberos/VPC/PublicSubnet1" + "value": "cluster-data-api/VPC/PublicSubnet1" } ] } @@ -170,7 +170,7 @@ }, "NATGateway": { "id": "NATGateway", - "path": "cluster-kerberos/VPC/PublicSubnet1/NATGateway", + "path": "cluster-data-api/VPC/PublicSubnet1/NATGateway", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", "aws:cdk:cloudformation:props": { @@ -186,7 +186,7 @@ "tags": [ { "key": "Name", - "value": "cluster-kerberos/VPC/PublicSubnet1" + "value": "cluster-data-api/VPC/PublicSubnet1" } ] } @@ -204,11 +204,11 @@ }, "PublicSubnet2": { "id": "PublicSubnet2", - "path": "cluster-kerberos/VPC/PublicSubnet2", + "path": "cluster-data-api/VPC/PublicSubnet2", "children": { "Subnet": { "id": "Subnet", - "path": "cluster-kerberos/VPC/PublicSubnet2/Subnet", + "path": "cluster-data-api/VPC/PublicSubnet2/Subnet", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", "aws:cdk:cloudformation:props": { @@ -233,7 +233,7 @@ }, { "key": "Name", - "value": "cluster-kerberos/VPC/PublicSubnet2" + "value": "cluster-data-api/VPC/PublicSubnet2" } ], "vpcId": { @@ -248,7 +248,7 @@ }, "Acl": { "id": "Acl", - "path": "cluster-kerberos/VPC/PublicSubnet2/Acl", + "path": "cluster-data-api/VPC/PublicSubnet2/Acl", "constructInfo": { "fqn": "aws-cdk-lib.Resource", "version": "0.0.0" @@ -256,14 +256,14 @@ }, "RouteTable": { "id": "RouteTable", - "path": "cluster-kerberos/VPC/PublicSubnet2/RouteTable", + "path": "cluster-data-api/VPC/PublicSubnet2/RouteTable", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", "aws:cdk:cloudformation:props": { "tags": [ { "key": "Name", - "value": "cluster-kerberos/VPC/PublicSubnet2" + "value": "cluster-data-api/VPC/PublicSubnet2" } ], "vpcId": { @@ -278,7 +278,7 @@ }, "RouteTableAssociation": { "id": "RouteTableAssociation", - "path": "cluster-kerberos/VPC/PublicSubnet2/RouteTableAssociation", + "path": "cluster-data-api/VPC/PublicSubnet2/RouteTableAssociation", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", "aws:cdk:cloudformation:props": { @@ -297,7 +297,7 @@ }, "DefaultRoute": { "id": "DefaultRoute", - "path": "cluster-kerberos/VPC/PublicSubnet2/DefaultRoute", + "path": "cluster-data-api/VPC/PublicSubnet2/DefaultRoute", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Route", "aws:cdk:cloudformation:props": { @@ -317,7 +317,7 @@ }, "EIP": { "id": "EIP", - "path": "cluster-kerberos/VPC/PublicSubnet2/EIP", + "path": "cluster-data-api/VPC/PublicSubnet2/EIP", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::EIP", "aws:cdk:cloudformation:props": { @@ -325,7 +325,7 @@ "tags": [ { "key": "Name", - "value": "cluster-kerberos/VPC/PublicSubnet2" + "value": "cluster-data-api/VPC/PublicSubnet2" } ] } @@ -337,7 +337,7 @@ }, "NATGateway": { "id": "NATGateway", - "path": "cluster-kerberos/VPC/PublicSubnet2/NATGateway", + "path": "cluster-data-api/VPC/PublicSubnet2/NATGateway", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", "aws:cdk:cloudformation:props": { @@ -353,7 +353,7 @@ "tags": [ { "key": "Name", - "value": "cluster-kerberos/VPC/PublicSubnet2" + "value": "cluster-data-api/VPC/PublicSubnet2" } ] } @@ -371,11 +371,11 @@ }, "PrivateSubnet1": { "id": "PrivateSubnet1", - "path": "cluster-kerberos/VPC/PrivateSubnet1", + "path": "cluster-data-api/VPC/PrivateSubnet1", "children": { "Subnet": { "id": "Subnet", - "path": "cluster-kerberos/VPC/PrivateSubnet1/Subnet", + "path": "cluster-data-api/VPC/PrivateSubnet1/Subnet", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", "aws:cdk:cloudformation:props": { @@ -400,7 +400,7 @@ }, { "key": "Name", - "value": "cluster-kerberos/VPC/PrivateSubnet1" + "value": "cluster-data-api/VPC/PrivateSubnet1" } ], "vpcId": { @@ -415,7 +415,7 @@ }, "Acl": { "id": "Acl", - "path": "cluster-kerberos/VPC/PrivateSubnet1/Acl", + "path": "cluster-data-api/VPC/PrivateSubnet1/Acl", "constructInfo": { "fqn": "aws-cdk-lib.Resource", "version": "0.0.0" @@ -423,14 +423,14 @@ }, "RouteTable": { "id": "RouteTable", - "path": "cluster-kerberos/VPC/PrivateSubnet1/RouteTable", + "path": "cluster-data-api/VPC/PrivateSubnet1/RouteTable", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", "aws:cdk:cloudformation:props": { "tags": [ { "key": "Name", - "value": "cluster-kerberos/VPC/PrivateSubnet1" + "value": "cluster-data-api/VPC/PrivateSubnet1" } ], "vpcId": { @@ -445,7 +445,7 @@ }, "RouteTableAssociation": { "id": "RouteTableAssociation", - "path": "cluster-kerberos/VPC/PrivateSubnet1/RouteTableAssociation", + "path": "cluster-data-api/VPC/PrivateSubnet1/RouteTableAssociation", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", "aws:cdk:cloudformation:props": { @@ -464,7 +464,7 @@ }, "DefaultRoute": { "id": "DefaultRoute", - "path": "cluster-kerberos/VPC/PrivateSubnet1/DefaultRoute", + "path": "cluster-data-api/VPC/PrivateSubnet1/DefaultRoute", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Route", "aws:cdk:cloudformation:props": { @@ -490,11 +490,11 @@ }, "PrivateSubnet2": { "id": "PrivateSubnet2", - "path": "cluster-kerberos/VPC/PrivateSubnet2", + "path": "cluster-data-api/VPC/PrivateSubnet2", "children": { "Subnet": { "id": "Subnet", - "path": "cluster-kerberos/VPC/PrivateSubnet2/Subnet", + "path": "cluster-data-api/VPC/PrivateSubnet2/Subnet", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", "aws:cdk:cloudformation:props": { @@ -519,7 +519,7 @@ }, { "key": "Name", - "value": "cluster-kerberos/VPC/PrivateSubnet2" + "value": "cluster-data-api/VPC/PrivateSubnet2" } ], "vpcId": { @@ -534,7 +534,7 @@ }, "Acl": { "id": "Acl", - "path": "cluster-kerberos/VPC/PrivateSubnet2/Acl", + "path": "cluster-data-api/VPC/PrivateSubnet2/Acl", "constructInfo": { "fqn": "aws-cdk-lib.Resource", "version": "0.0.0" @@ -542,14 +542,14 @@ }, "RouteTable": { "id": "RouteTable", - "path": "cluster-kerberos/VPC/PrivateSubnet2/RouteTable", + "path": "cluster-data-api/VPC/PrivateSubnet2/RouteTable", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", "aws:cdk:cloudformation:props": { "tags": [ { "key": "Name", - "value": "cluster-kerberos/VPC/PrivateSubnet2" + "value": "cluster-data-api/VPC/PrivateSubnet2" } ], "vpcId": { @@ -564,7 +564,7 @@ }, "RouteTableAssociation": { "id": "RouteTableAssociation", - "path": "cluster-kerberos/VPC/PrivateSubnet2/RouteTableAssociation", + "path": "cluster-data-api/VPC/PrivateSubnet2/RouteTableAssociation", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", "aws:cdk:cloudformation:props": { @@ -583,7 +583,7 @@ }, "DefaultRoute": { "id": "DefaultRoute", - "path": "cluster-kerberos/VPC/PrivateSubnet2/DefaultRoute", + "path": "cluster-data-api/VPC/PrivateSubnet2/DefaultRoute", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::Route", "aws:cdk:cloudformation:props": { @@ -609,14 +609,14 @@ }, "IGW": { "id": "IGW", - "path": "cluster-kerberos/VPC/IGW", + "path": "cluster-data-api/VPC/IGW", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway", "aws:cdk:cloudformation:props": { "tags": [ { "key": "Name", - "value": "cluster-kerberos/VPC" + "value": "cluster-data-api/VPC" } ] } @@ -628,7 +628,7 @@ }, "VPCGW": { "id": "VPCGW", - "path": "cluster-kerberos/VPC/VPCGW", + "path": "cluster-data-api/VPC/VPCGW", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", "aws:cdk:cloudformation:props": { @@ -647,11 +647,11 @@ }, "RestrictDefaultSecurityGroupCustomResource": { "id": "RestrictDefaultSecurityGroupCustomResource", - "path": "cluster-kerberos/VPC/RestrictDefaultSecurityGroupCustomResource", + "path": "cluster-data-api/VPC/RestrictDefaultSecurityGroupCustomResource", "children": { "Default": { "id": "Default", - "path": "cluster-kerberos/VPC/RestrictDefaultSecurityGroupCustomResource/Default", + "path": "cluster-data-api/VPC/RestrictDefaultSecurityGroupCustomResource/Default", "constructInfo": { "fqn": "aws-cdk-lib.CfnResource", "version": "0.0.0" @@ -671,11 +671,11 @@ }, "Custom::VpcRestrictDefaultSGCustomResourceProvider": { "id": "Custom::VpcRestrictDefaultSGCustomResourceProvider", - "path": "cluster-kerberos/Custom::VpcRestrictDefaultSGCustomResourceProvider", + "path": "cluster-data-api/Custom::VpcRestrictDefaultSGCustomResourceProvider", "children": { "Staging": { "id": "Staging", - "path": "cluster-kerberos/Custom::VpcRestrictDefaultSGCustomResourceProvider/Staging", + "path": "cluster-data-api/Custom::VpcRestrictDefaultSGCustomResourceProvider/Staging", "constructInfo": { "fqn": "aws-cdk-lib.AssetStaging", "version": "0.0.0" @@ -683,7 +683,7 @@ }, "Role": { "id": "Role", - "path": "cluster-kerberos/Custom::VpcRestrictDefaultSGCustomResourceProvider/Role", + "path": "cluster-data-api/Custom::VpcRestrictDefaultSGCustomResourceProvider/Role", "constructInfo": { "fqn": "aws-cdk-lib.CfnResource", "version": "0.0.0" @@ -691,7 +691,7 @@ }, "Handler": { "id": "Handler", - "path": "cluster-kerberos/Custom::VpcRestrictDefaultSGCustomResourceProvider/Handler", + "path": "cluster-data-api/Custom::VpcRestrictDefaultSGCustomResourceProvider/Handler", "constructInfo": { "fqn": "aws-cdk-lib.CfnResource", "version": "0.0.0" @@ -705,15 +705,15 @@ }, "Function": { "id": "Function", - "path": "cluster-kerberos/Function", + "path": "cluster-data-api/Function", "children": { "ServiceRole": { "id": "ServiceRole", - "path": "cluster-kerberos/Function/ServiceRole", + "path": "cluster-data-api/Function/ServiceRole", "children": { "ImportServiceRole": { "id": "ImportServiceRole", - "path": "cluster-kerberos/Function/ServiceRole/ImportServiceRole", + "path": "cluster-data-api/Function/ServiceRole/ImportServiceRole", "constructInfo": { "fqn": "aws-cdk-lib.Resource", "version": "0.0.0" @@ -721,7 +721,7 @@ }, "Resource": { "id": "Resource", - "path": "cluster-kerberos/Function/ServiceRole/Resource", + "path": "cluster-data-api/Function/ServiceRole/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::IAM::Role", "aws:cdk:cloudformation:props": { @@ -760,16 +760,26 @@ }, "DefaultPolicy": { "id": "DefaultPolicy", - "path": "cluster-kerberos/Function/ServiceRole/DefaultPolicy", + "path": "cluster-data-api/Function/ServiceRole/DefaultPolicy", "children": { "Resource": { "id": "Resource", - "path": "cluster-kerberos/Function/ServiceRole/DefaultPolicy/Resource", + "path": "cluster-data-api/Function/ServiceRole/DefaultPolicy/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::IAM::Policy", "aws:cdk:cloudformation:props": { "policyDocument": { "Statement": [ + { + "Action": [ + "secretsmanager:DescribeSecret", + "secretsmanager:GetSecretValue" + ], + "Effect": "Allow", + "Resource": { + "Ref": "DatabaseSecretAttachmentE5D1B020" + } + }, { "Action": [ "rds-data:BatchExecuteStatement", @@ -802,16 +812,6 @@ ] ] } - }, - { - "Action": [ - "secretsmanager:DescribeSecret", - "secretsmanager:GetSecretValue" - ], - "Effect": "Allow", - "Resource": { - "Ref": "DatabaseSecretAttachmentE5D1B020" - } } ], "Version": "2012-10-17" @@ -843,7 +843,7 @@ }, "Resource": { "id": "Resource", - "path": "cluster-kerberos/Function/Resource", + "path": "cluster-data-api/Function/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::Lambda::Function", "aws:cdk:cloudformation:props": { @@ -873,15 +873,15 @@ }, "Database": { "id": "Database", - "path": "cluster-kerberos/Database", + "path": "cluster-data-api/Database", "children": { "Subnets": { "id": "Subnets", - "path": "cluster-kerberos/Database/Subnets", + "path": "cluster-data-api/Database/Subnets", "children": { "Default": { "id": "Default", - "path": "cluster-kerberos/Database/Subnets/Default", + "path": "cluster-data-api/Database/Subnets/Default", "attributes": { "aws:cdk:cloudformation:type": "AWS::RDS::DBSubnetGroup", "aws:cdk:cloudformation:props": { @@ -909,11 +909,11 @@ }, "SecurityGroup": { "id": "SecurityGroup", - "path": "cluster-kerberos/Database/SecurityGroup", + "path": "cluster-data-api/Database/SecurityGroup", "children": { "Resource": { "id": "Resource", - "path": "cluster-kerberos/Database/SecurityGroup/Resource", + "path": "cluster-data-api/Database/SecurityGroup/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", "aws:cdk:cloudformation:props": { @@ -943,7 +943,7 @@ }, "AuroraPostgreSqlDatabaseClusterEngineDefaultParameterGroup": { "id": "AuroraPostgreSqlDatabaseClusterEngineDefaultParameterGroup", - "path": "cluster-kerberos/Database/AuroraPostgreSqlDatabaseClusterEngineDefaultParameterGroup", + "path": "cluster-data-api/Database/AuroraPostgreSqlDatabaseClusterEngineDefaultParameterGroup", "constructInfo": { "fqn": "aws-cdk-lib.Resource", "version": "0.0.0" @@ -951,11 +951,11 @@ }, "Secret": { "id": "Secret", - "path": "cluster-kerberos/Database/Secret", + "path": "cluster-data-api/Database/Secret", "children": { "Resource": { "id": "Resource", - "path": "cluster-kerberos/Database/Secret/Resource", + "path": "cluster-data-api/Database/Secret/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::SecretsManager::Secret", "aws:cdk:cloudformation:props": { @@ -985,11 +985,11 @@ }, "Attachment": { "id": "Attachment", - "path": "cluster-kerberos/Database/Secret/Attachment", + "path": "cluster-data-api/Database/Secret/Attachment", "children": { "Resource": { "id": "Resource", - "path": "cluster-kerberos/Database/Secret/Attachment/Resource", + "path": "cluster-data-api/Database/Secret/Attachment/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::SecretsManager::SecretTargetAttachment", "aws:cdk:cloudformation:props": { @@ -1021,7 +1021,7 @@ }, "Resource": { "id": "Resource", - "path": "cluster-kerberos/Database/Resource", + "path": "cluster-data-api/Database/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::RDS::DBCluster", "aws:cdk:cloudformation:props": { @@ -1079,11 +1079,11 @@ }, "writerInstance": { "id": "writerInstance", - "path": "cluster-kerberos/Database/writerInstance", + "path": "cluster-data-api/Database/writerInstance", "children": { "Resource": { "id": "Resource", - "path": "cluster-kerberos/Database/writerInstance/Resource", + "path": "cluster-data-api/Database/writerInstance/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::RDS::DBInstance", "aws:cdk:cloudformation:props": { @@ -1114,7 +1114,7 @@ }, "BootstrapVersion": { "id": "BootstrapVersion", - "path": "cluster-kerberos/BootstrapVersion", + "path": "cluster-data-api/BootstrapVersion", "constructInfo": { "fqn": "aws-cdk-lib.CfnParameter", "version": "0.0.0" @@ -1122,7 +1122,7 @@ }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", - "path": "cluster-kerberos/CheckBootstrapVersion", + "path": "cluster-data-api/CheckBootstrapVersion", "constructInfo": { "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.ts index 16394b4b5cd5e..f9c4f1cf28127 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.cluster-data-api.ts @@ -6,7 +6,7 @@ import * as lambda from 'aws-cdk-lib/aws-lambda'; const app = new cdk.App(); -const stack = new cdk.Stack(app, 'cluster-kerberos'); +const stack = new cdk.Stack(app, 'cluster-data-api'); const vpc = new ec2.Vpc(stack, 'VPC'); const fucntion = new lambda.Function(stack, 'Function', { @@ -23,7 +23,6 @@ const cluster = new rds.DatabaseCluster(stack, 'Database', { }); cluster.grantDataApiAccess(fucntion); -cluster.secret?.grantRead(fucntion); new integ.IntegTest(app, 'integ-cluster-data-api', { testCases: [stack], diff --git a/packages/aws-cdk-lib/aws-rds/README.md b/packages/aws-cdk-lib/aws-rds/README.md index 7ee7a8df813dc..f1c677dc434da 100644 --- a/packages/aws-cdk-lib/aws-rds/README.md +++ b/packages/aws-cdk-lib/aws-rds/README.md @@ -1191,8 +1191,6 @@ const cluster = new rds.DatabaseCluster(this, 'Cluster', { enableDataApi: true, // Optional - will be automatically set if you call grantDataApiAccess() }); cluster.grantDataApiAccess(fn); -// It is necessary to grant the function access to the secret associated with the cluster for `DatabaseCluster`. -cluster.secret!.grantRead(fn); ``` **Note**: To invoke the Data API, the resource will need to read the secret associated with the cluster. diff --git a/packages/aws-cdk-lib/aws-rds/lib/cluster-ref.ts b/packages/aws-cdk-lib/aws-rds/lib/cluster-ref.ts index a55a0c4f52396..1785548c82af4 100644 --- a/packages/aws-cdk-lib/aws-rds/lib/cluster-ref.ts +++ b/packages/aws-cdk-lib/aws-rds/lib/cluster-ref.ts @@ -137,4 +137,11 @@ export interface DatabaseClusterAttributes { * @default - the imported Cluster's engine is unknown */ readonly engine?: IClusterEngine; + + /** + * The secret attached to the database cluster + * + * @default - the imported Cluster's secret is unknown + */ + readonly secret?: secretsmanager.ISecret; } diff --git a/packages/aws-cdk-lib/aws-rds/lib/cluster.ts b/packages/aws-cdk-lib/aws-rds/lib/cluster.ts index 41bcc57d35a6c..5119f57a3dec5 100644 --- a/packages/aws-cdk-lib/aws-rds/lib/cluster.ts +++ b/packages/aws-cdk-lib/aws-rds/lib/cluster.ts @@ -467,6 +467,11 @@ export abstract class DatabaseClusterBase extends Resource implements IDatabaseC protected abstract enableDataApi?: boolean; + /** + * Secret in SecretsManager to store the database cluster user credentials. + */ + public abstract readonly secret?: secretsmanager.ISecret; + /** * The ARN of the cluster */ @@ -521,6 +526,7 @@ export abstract class DatabaseClusterBase extends Resource implements IDatabaseC } this.enableDataApi = true; + this.secret?.grantRead(grantee); return iam.Grant.addToPrincipal({ actions: DATA_API_ACTIONS, grantee, @@ -546,11 +552,6 @@ abstract class DatabaseClusterNew extends DatabaseClusterBase { private readonly domainId?: string; private readonly domainRole?: iam.IRole; - /** - * Secret in SecretsManager to store the database cluster user credentials. - */ - public abstract readonly secret?: secretsmanager.ISecret; - /** * The VPC network to place the cluster in. */ @@ -964,6 +965,7 @@ class ImportedDatabaseCluster extends DatabaseClusterBase implements IDatabaseCl public readonly clusterIdentifier: string; public readonly connections: ec2.Connections; public readonly engine?: IClusterEngine; + public readonly secret?: secretsmanager.ISecret; private readonly _clusterResourceIdentifier?: string; private readonly _clusterEndpoint?: Endpoint; @@ -985,6 +987,7 @@ class ImportedDatabaseCluster extends DatabaseClusterBase implements IDatabaseCl defaultPort, }); this.engine = attrs.engine; + this.secret = attrs.secret; this._clusterEndpoint = (attrs.clusterEndpointAddress && attrs.port) ? new Endpoint(attrs.clusterEndpointAddress, attrs.port) : undefined; this._clusterReadEndpoint = (attrs.readerEndpointAddress && attrs.port) ? new Endpoint(attrs.readerEndpointAddress, attrs.port) : undefined; 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 7563065fd0f10..b3a67928987b5 100644 --- a/packages/aws-cdk-lib/aws-rds/test/cluster.test.ts +++ b/packages/aws-cdk-lib/aws-rds/test/cluster.test.ts @@ -4249,6 +4249,16 @@ describe('cluster', () => { Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ + { + Action: [ + 'secretsmanager:GetSecretValue', + 'secretsmanager:DescribeSecret', + ], + Effect: 'Allow', + Resource: { + Ref: 'DatabaseSecretAttachmentE5D1B020', + }, + }, { Action: [ 'rds-data:BatchExecuteStatement', From cc377785c00a021c9b519bdda945be8e99cb1148 Mon Sep 17 00:00:00 2001 From: GZ Date: Thu, 14 Mar 2024 16:13:49 -0700 Subject: [PATCH 3/4] fix(cloudwatch): cloudwatch ec2 alarm action with multiple dimension results in error (#29364) ### Issue # (if applicable) Closes https://github.com/aws/aws-cdk/issues/29331 ### Reason for this change While trying to create a Custom Metric with multiple dimension, and adding EC2 action, the CDK synth fails. ### Description of changes As long as there's instance id in dimension, we should accept it instead of raising exception. ### Description of how you validated changes new tests and existing tests pass. ### 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-cloudwatch/lib/alarm.ts | 2 +- .../aws-cloudwatch/test/alarm.test.ts | 63 ++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/aws-cloudwatch/lib/alarm.ts b/packages/aws-cdk-lib/aws-cloudwatch/lib/alarm.ts index 2c470512a2e81..e25bf8cfe1aef 100644 --- a/packages/aws-cdk-lib/aws-cloudwatch/lib/alarm.ts +++ b/packages/aws-cdk-lib/aws-cloudwatch/lib/alarm.ts @@ -267,7 +267,7 @@ export class Alarm extends AlarmBase { if (ec2ActionsRegexp.test(actionArn)) { // Check per-instance metric const metricConfig = this.metric.toMetricConfig(); - if (metricConfig.metricStat?.dimensions?.length != 1 || metricConfig.metricStat?.dimensions![0].name != 'InstanceId') { + if (metricConfig.metricStat?.dimensions?.length != 1 || !metricConfig.metricStat?.dimensions?.some(dimension => dimension.name === 'InstanceId')) { throw new Error(`EC2 alarm actions requires an EC2 Per-Instance Metric. (${JSON.stringify(metricConfig)} does not have an 'InstanceId' dimension)`); } } diff --git a/packages/aws-cdk-lib/aws-cloudwatch/test/alarm.test.ts b/packages/aws-cdk-lib/aws-cloudwatch/test/alarm.test.ts index ffc79405b1fe8..85feb315eda91 100644 --- a/packages/aws-cdk-lib/aws-cloudwatch/test/alarm.test.ts +++ b/packages/aws-cdk-lib/aws-cloudwatch/test/alarm.test.ts @@ -1,6 +1,8 @@ import { Construct } from 'constructs'; import { Match, Template, Annotations } from '../../assertions'; -import { Duration, Stack } from '../../core'; +import { Ec2Action, Ec2InstanceAction } from '../../aws-cloudwatch-actions/lib'; +import { Duration, Stack, App } from '../../core'; +import { ENABLE_PARTITION_LITERALS } from '../../cx-api'; import { Alarm, IAlarm, IAlarmAction, Metric, MathExpression, IMetric, Stats } from '../lib'; const testMetric = new Metric({ @@ -232,6 +234,65 @@ describe('Alarm', () => { }); }); + test('EC2 alarm actions with InstanceId dimension', () => { + // GIVEN + const app = new App({ context: { [ ENABLE_PARTITION_LITERALS]: true } }); + const stack = new Stack(app, 'EC2AlarmStack', { env: { region: 'us-west-2', account: '123456789012' } }); + + // WHEN + const metric = new Metric({ + namespace: 'CWAgent', + metricName: 'disk_used_percent', + dimensionsMap: { + InstanceId: 'instance-id', + }, + period: Duration.minutes(5), + statistic: 'Average', + }); + + const sev3Alarm = new Alarm(stack, 'DISK_USED_PERCENT_SEV3', { + alarmName: 'DISK_USED_PERCENT_SEV3', + actionsEnabled: true, + metric: metric, + threshold: 1, + evaluationPeriods: 1, + }); + + expect(() => { + sev3Alarm.addAlarmAction(new Ec2Action(Ec2InstanceAction.REBOOT)); + }).not.toThrow(); + }); + + test('EC2 alarm actions without InstanceId dimension', () => { + // GIVEN + const app = new App({ context: { [ ENABLE_PARTITION_LITERALS]: true } }); + const stack = new Stack(app, 'EC2AlarmStack', { env: { region: 'us-west-2', account: '123456789012' } }); + + // WHEN + const metric = new Metric({ + namespace: 'CWAgent', + metricName: 'disk_used_percent', + dimensionsMap: { + ImageId: 'image-id', + InstanceType: 't2.micro', + }, + period: Duration.minutes(5), + statistic: 'Average', + }); + + const sev3Alarm = new Alarm(stack, 'DISK_USED_PERCENT_SEV3', { + alarmName: 'DISK_USED_PERCENT_SEV3', + actionsEnabled: true, + metric: metric, + threshold: 1, + evaluationPeriods: 1, + }); + + expect(() => { + sev3Alarm.addAlarmAction(new Ec2Action(Ec2InstanceAction.REBOOT)); + }).toThrow(/EC2 alarm actions requires an EC2 Per-Instance Metric/); + }); + test('can use percentile string to make alarm', () => { // GIVEN const stack = new Stack(); From 3c1307ed6a4b7f09db929093914eeaad93dae097 Mon Sep 17 00:00:00 2001 From: Michael Sambol Date: Thu, 14 Mar 2024 17:42:08 -0600 Subject: [PATCH 4/4] chore(synthetics): deprecate nodejs runtimes (#29472) Per this [doc](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html#CloudWatch_Synthetics_Canaries_runtime_support), these 5 runtimes were deprecated on March 8, 2024. ---- *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-synthetics/lib/runtime.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/aws-cdk-lib/aws-synthetics/lib/runtime.ts b/packages/aws-cdk-lib/aws-synthetics/lib/runtime.ts index b2b5207e6235b..f56b3f2114927 100644 --- a/packages/aws-cdk-lib/aws-synthetics/lib/runtime.ts +++ b/packages/aws-cdk-lib/aws-synthetics/lib/runtime.ts @@ -98,6 +98,7 @@ export class Runtime { * - **Dependency upgrades**: The Node.js dependency is updated to 16.x. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Library_nodejs_puppeteer.html#CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-4.0 + * @deprecated Legacy runtime no longer supported by AWS Lambda. Migrate to the latest NodeJS Puppeteer runtime. */ public static readonly SYNTHETICS_NODEJS_PUPPETEER_4_0 = new Runtime('syn-nodejs-puppeteer-4.0', RuntimeFamily.NODEJS); @@ -111,6 +112,7 @@ export class Runtime { * - **Dependency upgrade**: The Puppeteer-core version is updated to 19.7.0. The Chromium version is upgraded to 111.0.5563.146. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Library_nodejs_puppeteer.html#CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-5.0 + * @deprecated Legacy runtime no longer supported by AWS Lambda. Migrate to the latest NodeJS Puppeteer runtime. */ public static readonly SYNTHETICS_NODEJS_PUPPETEER_5_0 = new Runtime('syn-nodejs-puppeteer-5.0', RuntimeFamily.NODEJS); @@ -124,6 +126,7 @@ export class Runtime { * - **Bug fix**: This runtime fixes a bug in `syn-nodejs-puppeteer-5.0` where the HAR files created by the canaries were missing request headers. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Library_nodejs_puppeteer.html#CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-5.1 + * @deprecated Legacy runtime no longer supported by AWS Lambda. Migrate to the latest NodeJS Puppeteer runtime. */ public static readonly SYNTHETICS_NODEJS_PUPPETEER_5_1 = new Runtime('syn-nodejs-puppeteer-5.1', RuntimeFamily.NODEJS); @@ -153,6 +156,7 @@ export class Runtime { * - **Bug fix**: Clean up core dump generated when Chromium crashes during a canary run. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Library_nodejs_puppeteer.html#CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-6.0 + * @deprecated Legacy runtime no longer supported by AWS Lambda. Migrate to the latest NodeJS Puppeteer runtime. */ public static readonly SYNTHETICS_NODEJS_PUPPETEER_6_0 = new Runtime('syn-nodejs-puppeteer-6.0', RuntimeFamily.NODEJS); @@ -168,6 +172,7 @@ export class Runtime { * - **Canaries without Amazon S3 permissions**: Bug fixes, such that canaries that don't have any Amazon S3 permissions can still run. These canaries with no Amazon S3 permissions won't be able to upload screenshots or other artifacts to Amazon S3. For more information about permissions for canaries, see Required roles and permissions for canaries. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Library_nodejs_puppeteer.html#CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-6.1 + * @deprecated Legacy runtime no longer supported by AWS Lambda. Migrate to the latest NodeJS Puppeteer runtime. */ public static readonly SYNTHETICS_NODEJS_PUPPETEER_6_1 = new Runtime('syn-nodejs-puppeteer-6.1', RuntimeFamily.NODEJS);