diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/CompositeAlarmImportIntegrationTest.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/CompositeAlarmImportIntegrationTest.assets.json index 4801cb2cefc9d..0a509d2cfcb5e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/CompositeAlarmImportIntegrationTest.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/CompositeAlarmImportIntegrationTest.assets.json @@ -1,13 +1,14 @@ { - "version": "31.0.0", + "version": "48.0.0", "files": { "a29bbb21cb63cde6a2d31ed4212e73dab8bfd786cf26aab0156b74490595c0a6": { + "displayName": "CompositeAlarmImportIntegrationTest Template", "source": { "path": "CompositeAlarmImportIntegrationTest.template.json", "packaging": "file" }, "destinations": { - "current_account-current_region": { + "current_account-current_region-972e9596": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", "objectKey": "a29bbb21cb63cde6a2d31ed4212e73dab8bfd786cf26aab0156b74490595c0a6.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-cloudwatch/test/integ.composite-alarm.js.snapshot/CompositeAlarmIntegrationTest.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/CompositeAlarmIntegrationTest.assets.json index 94febd1e90497..dcd6635c80a96 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/CompositeAlarmIntegrationTest.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/CompositeAlarmIntegrationTest.assets.json @@ -1,15 +1,16 @@ { - "version": "31.0.0", + "version": "48.0.0", "files": { - "de5a3d0e66f4d4eab13b64e32203fdcae3b36670c889c72a3b4b752e6a5d0fc2": { + "8284aa5320b6b544ab48fdc0420699ed873087ee3c1007224ffefea31e22caf2": { + "displayName": "CompositeAlarmIntegrationTest Template", "source": { "path": "CompositeAlarmIntegrationTest.template.json", "packaging": "file" }, "destinations": { - "current_account-current_region": { + "current_account-current_region-de3be2dc": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "de5a3d0e66f4d4eab13b64e32203fdcae3b36670c889c72a3b4b752e6a5d0fc2.json", + "objectKey": "8284aa5320b6b544ab48fdc0420699ed873087ee3c1007224ffefea31e22caf2.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-cloudwatch/test/integ.composite-alarm.js.snapshot/CompositeAlarmIntegrationTest.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/CompositeAlarmIntegrationTest.template.json index e3e92708c65a9..5dd128f4b10c6 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/CompositeAlarmIntegrationTest.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/CompositeAlarmIntegrationTest.template.json @@ -51,9 +51,9 @@ "Alarm548383B2F": { "Type": "AWS::CloudWatch::Alarm", "Properties": { + "AlarmName": "Alarm with space in name", "ComparisonOperator": "GreaterThanOrEqualToThreshold", "EvaluationPeriods": 3, - "AlarmName": "Alarm with space in name", "MetricName": "Metric", "Namespace": "CDK/Test", "Period": 300, @@ -64,6 +64,15 @@ "CompositeAlarmF4C3D082": { "Type": "AWS::CloudWatch::CompositeAlarm", "Properties": { + "ActionsSuppressor": { + "Fn::GetAtt": [ + "Alarm548383B2F", + "Arn" + ] + }, + "ActionsSuppressorExtensionPeriod": 60, + "ActionsSuppressorWaitPeriod": 60, + "AlarmName": "CompositeAlarmIntegrationTestCompositeAlarm742D2FBA", "AlarmRule": { "Fn::Join": [ "", @@ -103,19 +112,52 @@ "Arn" ] }, - "\")))) OR FALSE)" + "\"))) AND AT_LEAST(2, ALARM, (", + { + "Fn::GetAtt": [ + "Alarm1F9009D71", + "Arn" + ] + }, + ", ", + { + "Fn::GetAtt": [ + "Alarm2A7122E13", + "Arn" + ] + }, + ", ", + { + "Fn::GetAtt": [ + "Alarm32341D8D9", + "Arn" + ] + }, + ")) AND AT_LEAST(60%, NOT OK, (", + { + "Fn::GetAtt": [ + "Alarm1F9009D71", + "Arn" + ] + }, + ", ", + { + "Fn::GetAtt": [ + "Alarm2A7122E13", + "Arn" + ] + }, + ", ", + { + "Fn::GetAtt": [ + "Alarm32341D8D9", + "Arn" + ] + }, + "))) OR FALSE)" ] ] - }, - "ActionsSuppressor": { - "Fn::GetAtt": [ - "Alarm548383B2F", - "Arn" - ] - }, - "ActionsSuppressorExtensionPeriod": 60, - "ActionsSuppressorWaitPeriod": 60, - "AlarmName": "CompositeAlarmIntegrationTestCompositeAlarm742D2FBA" + } } } }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/cdk.out index 7925065efbcc4..523a9aac37cbf 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"31.0.0"} \ No newline at end of file +{"version":"48.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/cdkintegcompositealarmDefaultTestDeployAssertF4EF969E.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/cdkintegcompositealarmDefaultTestDeployAssertF4EF969E.assets.json index 7cbfec60588f0..6b22cb2940d99 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/cdkintegcompositealarmDefaultTestDeployAssertF4EF969E.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/cdkintegcompositealarmDefaultTestDeployAssertF4EF969E.assets.json @@ -1,13 +1,14 @@ { - "version": "31.0.0", + "version": "48.0.0", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "displayName": "cdkintegcompositealarmDefaultTestDeployAssertF4EF969E Template", "source": { "path": "cdkintegcompositealarmDefaultTestDeployAssertF4EF969E.template.json", "packaging": "file" }, "destinations": { - "current_account-current_region": { + "current_account-current_region-d8d86b35": { "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}" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/integ.json index b56d7d84db9f6..a74e29f1201af 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "31.0.0", + "version": "48.0.0", "testCases": { "cdk-integ-composite-alarm/DefaultTest": { "stacks": [ @@ -9,5 +9,6 @@ "assertionStack": "cdk-integ-composite-alarm/DefaultTest/DeployAssert", "assertionStackName": "cdkintegcompositealarmDefaultTestDeployAssertF4EF969E" } - } + }, + "minimumCliVersion": "2.1027.0" } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/manifest.json index 3872b65b9b43a..863d6040cd7fa 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "31.0.0", + "version": "48.0.0", "artifacts": { "CompositeAlarmIntegrationTest.assets": { "type": "cdk:asset-manifest", @@ -14,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "CompositeAlarmIntegrationTest.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}/de5a3d0e66f4d4eab13b64e32203fdcae3b36670c889c72a3b4b752e6a5d0fc2.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/8284aa5320b6b544ab48fdc0420699ed873087ee3c1007224ffefea31e22caf2.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -33,36 +34,111 @@ "CompositeAlarmIntegrationTest.assets" ], "metadata": { + "/CompositeAlarmIntegrationTest/Alarm1": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "metric": { + "warnings": "*", + "warningsV2": "*" + }, + "threshold": "*", + "evaluationPeriods": "*" + } + } + ], "/CompositeAlarmIntegrationTest/Alarm1/Resource": [ { "type": "aws:cdk:logicalId", "data": "Alarm1F9009D71" } ], + "/CompositeAlarmIntegrationTest/Alarm2": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "metric": { + "warnings": "*", + "warningsV2": "*" + }, + "threshold": "*", + "evaluationPeriods": "*" + } + } + ], "/CompositeAlarmIntegrationTest/Alarm2/Resource": [ { "type": "aws:cdk:logicalId", "data": "Alarm2A7122E13" } ], + "/CompositeAlarmIntegrationTest/Alarm3": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "metric": { + "warnings": "*", + "warningsV2": "*" + }, + "threshold": "*", + "evaluationPeriods": "*" + } + } + ], "/CompositeAlarmIntegrationTest/Alarm3/Resource": [ { "type": "aws:cdk:logicalId", "data": "Alarm32341D8D9" } ], + "/CompositeAlarmIntegrationTest/Alarm4": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "metric": { + "warnings": "*", + "warningsV2": "*" + }, + "threshold": "*", + "evaluationPeriods": "*" + } + } + ], "/CompositeAlarmIntegrationTest/Alarm4/Resource": [ { "type": "aws:cdk:logicalId", "data": "Alarm4671832C8" } ], + "/CompositeAlarmIntegrationTest/Alarm5": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "alarmName": "*", + "metric": { + "warnings": "*", + "warningsV2": "*" + }, + "threshold": "*", + "evaluationPeriods": "*" + } + } + ], "/CompositeAlarmIntegrationTest/Alarm5/Resource": [ { "type": "aws:cdk:logicalId", "data": "Alarm548383B2F" } ], + "/CompositeAlarmIntegrationTest/CompositeAlarm": [ + { + "type": "aws:cdk:analytics:construct", + "data": { + "alarmRule": "*", + "actionsSuppressor": "*" + } + } + ], "/CompositeAlarmIntegrationTest/CompositeAlarm/Resource": [ { "type": "aws:cdk:logicalId", @@ -97,6 +173,7 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "CompositeAlarmImportIntegrationTest.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}", @@ -156,6 +233,7 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "cdkintegcompositealarmDefaultTestDeployAssertF4EF969E.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}", @@ -195,6 +273,502 @@ "properties": { "file": "tree.json" } + }, + "aws-cdk-lib/feature-flag-report": { + "type": "cdk:feature-flag-report", + "properties": { + "module": "aws-cdk-lib", + "flags": { + "@aws-cdk/aws-signer:signingProfileNamePassedToCfn": { + "userValue": true, + "recommendedValue": true, + "explanation": "Pass signingProfileName to CfnSigningProfile" + }, + "@aws-cdk/core:newStyleStackSynthesis": { + "recommendedValue": true, + "explanation": "Switch to new stack synthesis method which enables CI/CD", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:stackRelativeExports": { + "recommendedValue": true, + "explanation": "Name exports based on the construct paths relative to the stack, rather than the global construct path", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-ecs-patterns:secGroupsDisablesImplicitOpenListener": { + "userValue": true, + "recommendedValue": true, + "explanation": "Disable implicit openListener when custom security groups are provided" + }, + "@aws-cdk/aws-rds:lowercaseDbIdentifier": { + "recommendedValue": true, + "explanation": "Force lowercasing of RDS Cluster names in CDK", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": { + "recommendedValue": true, + "explanation": "Allow adding/removing multiple UsagePlanKeys independently", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-lambda:recognizeVersionProps": { + "recommendedValue": true, + "explanation": "Enable this feature flag to opt in to the updated logical id calculation for Lambda Version created using the `fn.currentVersion`.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-lambda:recognizeLayerVersion": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to opt in to the updated logical id calculation for Lambda Version created using the `fn.currentVersion`." + }, + "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": { + "recommendedValue": true, + "explanation": "Enable this feature flag to have cloudfront distributions use the security policy TLSv1.2_2021 by default.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:checkSecretUsage": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this flag to make it impossible to accidentally use SecretValues in unsafe locations" + }, + "@aws-cdk/core:target-partitions": { + "recommendedValue": [ + "aws", + "aws-cn" + ], + "explanation": "What regions to include in lookup tables of environment agnostic stacks" + }, + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": { + "userValue": true, + "recommendedValue": true, + "explanation": "ECS extensions will automatically add an `awslogs` driver if no logging is specified" + }, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to have Launch Templates generated by the `InstanceRequireImdsv2Aspect` use unique names." + }, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": { + "userValue": true, + "recommendedValue": true, + "explanation": "ARN format used by ECS. In the new ARN format, the cluster name is part of the resource ID." + }, + "@aws-cdk/aws-iam:minimizePolicies": { + "userValue": true, + "recommendedValue": true, + "explanation": "Minimize IAM policies by combining Statements" + }, + "@aws-cdk/core:validateSnapshotRemovalPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Error on snapshot removal policies on resources that do not support it." + }, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate key aliases that include the stack name" + }, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature flag to create an S3 bucket policy by default in cases where an AWS service would automatically create the Policy if one does not exist." + }, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": { + "userValue": true, + "recommendedValue": true, + "explanation": "Restrict KMS key policy for encrypted Queues a bit more" + }, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": { + "userValue": true, + "recommendedValue": true, + "explanation": "Make default CloudWatch Role behavior safe for multiple API Gateways in one environment" + }, + "@aws-cdk/core:enablePartitionLiterals": { + "userValue": true, + "recommendedValue": true, + "explanation": "Make ARNs concrete if AWS partition is known" + }, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": { + "userValue": true, + "recommendedValue": true, + "explanation": "Event Rules may only push to encrypted SQS queues in the same account" + }, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": { + "userValue": true, + "recommendedValue": true, + "explanation": "Avoid setting the \"ECS\" deployment controller when adding a circuit breaker" + }, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable this feature to create default policy names for imported roles that depend on the stack the role is in." + }, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use S3 Bucket Policy instead of ACLs for Server Access Logging" + }, + "@aws-cdk/aws-route53-patters:useCertificate": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use the official `Certificate` resource instead of `DnsValidatedCertificate`" + }, + "@aws-cdk/customresources:installLatestAwsSdkDefault": { + "userValue": false, + "recommendedValue": false, + "explanation": "Whether to install the latest SDK by default in AwsCustomResource" + }, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": { + "userValue": true, + "recommendedValue": true, + "explanation": "Use unique resource name for Database Proxy" + }, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "Remove CloudWatch alarms from deployment group" + }, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Include authorizer configuration in the calculation of the API deployment logical ID." + }, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": { + "userValue": true, + "recommendedValue": true, + "explanation": "Define user data for a launch template by default when a machine image is provided." + }, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": { + "userValue": true, + "recommendedValue": true, + "explanation": "SecretTargetAttachments uses the ResourcePolicy of the attached Secret." + }, + "@aws-cdk/aws-redshift:columnId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Whether to use an ID to track Redshift column changes" + }, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable AmazonEMRServicePolicy_v2 managed policies" + }, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "Restrict access to the VPC default security group" + }, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate a unique id for each RequestValidator added to a method" + }, + "@aws-cdk/aws-kms:aliasNameRef": { + "userValue": true, + "recommendedValue": true, + "explanation": "KMS Alias name and keyArn will have implicit reference to KMS Key" + }, + "@aws-cdk/aws-kms:applyImportedAliasPermissionsToPrincipal": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enable grant methods on Aliases imported by name to use kms:ResourceAliases condition" + }, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": { + "userValue": true, + "recommendedValue": true, + "explanation": "Generate a launch template when creating an AutoScalingGroup" + }, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": { + "userValue": true, + "recommendedValue": true, + "explanation": "Include the stack prefix in the stack name generation process" + }, + "@aws-cdk/aws-efs:denyAnonymousAccess": { + "userValue": true, + "recommendedValue": true, + "explanation": "EFS denies anonymous clients accesses" + }, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables support for Multi-AZ with Standby deployment for opensearch domains" + }, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables aws-lambda-nodejs.Function to use the latest available NodeJs runtime as the default" + }, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, mount targets will have a stable logicalId that is linked to the associated subnet." + }, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, a scope of InstanceParameterGroup for AuroraClusterInstance with each parameters will change." + }, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, will always use the arn for identifiers for CfnSourceApiAssociation in the GraphqlApi construct rather than id." + }, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, creating an RDS database cluster from a snapshot will only render credentials for snapshot credentials." + }, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the CodeCommit source action is using the default branch name 'main'." + }, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the logical ID of a Lambda permission for a Lambda action includes an alarm ID." + }, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables Pipeline to set the default value for crossAccountKeys to false." + }, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "Enables Pipeline to set the default pipeline type to V2." + }, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, IAM Policy created from KMS key grant will reduce the resource scope to this key only." + }, + "@aws-cdk/pipelines:reduceAssetRoleTrustScope": { + "recommendedValue": true, + "explanation": "Remove the root account principal from PipelineAssetsFileRole trust policy", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-eks:nodegroupNameAttribute": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, nodegroupName attribute of the provisioned EKS NodeGroup will not have the cluster name prefix." + }, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default volume type of the EBS volume will be GP3" + }, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, remove default deployment alarm settings" + }, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": { + "userValue": false, + "recommendedValue": false, + "explanation": "When enabled, the custom resource used for `AwsCustomResource` will configure the `logApiResponseData` property as true by default" + }, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": { + "userValue": false, + "recommendedValue": false, + "explanation": "When enabled, Adding notifications to a bucket in the current stack will not remove notification from imported stack." + }, + "@aws-cdk/aws-stepfunctions-tasks:useNewS3UriParametersForBedrockInvokeModelTask": { + "recommendedValue": true, + "explanation": "When enabled, use new props for S3 URI field in task definition of state machine for bedrock invoke model.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/core:explicitStackTags": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, stack tags need to be assigned explicitly on a Stack." + }, + "@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": { + "userValue": false, + "recommendedValue": false, + "explanation": "When set to true along with canContainersAccessInstanceRole=false in ECS cluster, new updated commands will be added to UserData to block container accessing IMDS. **Applicable to Linux only. IMPORTANT: See [details.](#aws-cdkaws-ecsenableImdsBlockingDeprecatedFeature)**" + }, + "@aws-cdk/aws-ecs:disableEcsImdsBlocking": { + "userValue": true, + "recommendedValue": true, + "explanation": "When set to true, CDK synth will throw exception if canContainersAccessInstanceRole is false. **IMPORTANT: See [details.](#aws-cdkaws-ecsdisableEcsImdsBlocking)**" + }, + "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, we will only grant the necessary permissions when users specify cloudwatch log group through logConfiguration" + }, + "@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled will allow you to specify a resource policy per replica, and not copy the source table policy to all replicas" + }, + "@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, initOptions.timeout and resourceSignalTimeout values will be summed together." + }, + "@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, a Lambda authorizer Permission created when using GraphqlApi will be properly scoped with a SourceArn." + }, + "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the value of property `instanceResourceId` in construct `DatabaseInstanceReadReplica` will be set to the correct value which is `DbiResourceId` instead of currently `DbInstanceArn`" + }, + "@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": { + "userValue": true, + "recommendedValue": true, + "explanation": "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." + }, + "@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, both `@aws-sdk` and `@smithy` packages will be excluded from the Lambda Node.js 18.x runtime to prevent version mismatches in bundled applications." + }, + "@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the resource of IAM Run Ecs policy generated by SFN EcsRunTask will reference the definition, instead of constructing ARN." + }, + "@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the BastionHost construct will use the latest Amazon Linux 2023 AMI, instead of Amazon Linux 2." + }, + "@aws-cdk/core:aspectStabilization": { + "recommendedValue": true, + "explanation": "When enabled, a stabilization loop will be run when invoking Aspects during synthesis.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, use a new method for DNS Name of user pool domain target without creating a custom resource." + }, + "@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default security group ingress rules will allow IPv6 ingress from anywhere" + }, + "@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the default behaviour of OIDC provider will reject unauthorized connections" + }, + "@aws-cdk/core:enableAdditionalMetadataCollection": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK will expand the scope of usage data collected to better inform CDK development and improve communication for security concerns and emerging issues." + }, + "@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": { + "userValue": false, + "recommendedValue": false, + "explanation": "[Deprecated] When enabled, Lambda will create new inline policies with AddToRolePolicy instead of adding to the Default Policy Statement" + }, + "@aws-cdk/aws-s3:setUniqueReplicationRoleName": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK will automatically generate a unique role name that is used for s3 object replication." + }, + "@aws-cdk/pipelines:reduceStageRoleTrustScope": { + "recommendedValue": true, + "explanation": "Remove the root account principal from Stage addActions trust policy", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-events:requireEventBusPolicySid": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, grantPutEventsTo() will use resource policies with Statement IDs for service principals." + }, + "@aws-cdk/core:aspectPrioritiesMutating": { + "userValue": true, + "recommendedValue": true, + "explanation": "When set to true, Aspects added by the construct library on your behalf will be given a priority of MUTATING." + }, + "@aws-cdk/aws-dynamodb:retainTableReplica": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, table replica will be default to the removal policy of source table unless specified otherwise." + }, + "@aws-cdk/cognito:logUserPoolClientSecretValue": { + "recommendedValue": false, + "explanation": "When disabled, the value of the user pool client secret will not be logged in the custom resource lambda function logs." + }, + "@aws-cdk/pipelines:reduceCrossAccountActionRoleTrustScope": { + "recommendedValue": true, + "explanation": "When enabled, scopes down the trust policy for the cross-account action role", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-stepfunctions:useDistributedMapResultWriterV2": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the resultWriterV2 property of DistributedMap will be used insted of resultWriter" + }, + "@aws-cdk/s3-notifications:addS3TrustKeyPolicyForSnsSubscriptions": { + "userValue": true, + "recommendedValue": true, + "explanation": "Add an S3 trust policy to a KMS key resource policy for SNS subscriptions." + }, + "@aws-cdk/aws-ec2:requirePrivateSubnetsForEgressOnlyInternetGateway": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, the EgressOnlyGateway resource is only created if private subnets are defined in the dual-stack VPC." + }, + "@aws-cdk/aws-ec2-alpha:useResourceIdForVpcV2Migration": { + "recommendedValue": false, + "explanation": "When enabled, use resource IDs for VPC V2 migration" + }, + "@aws-cdk/aws-s3:publicAccessBlockedByDefault": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, setting any combination of options for BlockPublicAccess will automatically set true for any options not defined." + }, + "@aws-cdk/aws-lambda:useCdkManagedLogGroup": { + "userValue": true, + "recommendedValue": true, + "explanation": "When enabled, CDK creates and manages loggroup for the lambda function" + }, + "@aws-cdk/aws-elasticloadbalancingv2:networkLoadBalancerWithSecurityGroupByDefault": { + "recommendedValue": true, + "explanation": "When enabled, Network Load Balancer will be created with a security group by default." + }, + "@aws-cdk/aws-stepfunctions-tasks:httpInvokeDynamicJsonPathEndpoint": { + "recommendedValue": true, + "explanation": "When enabled, allows using a dynamic apiEndpoint with JSONPath format in HttpInvoke tasks.", + "unconfiguredBehavesLike": { + "v2": true + } + }, + "@aws-cdk/aws-ecs-patterns:uniqueTargetGroupId": { + "recommendedValue": true, + "explanation": "When enabled, ECS patterns will generate unique target group IDs to prevent conflicts during load balancer replacement" + } + } + } } - } + }, + "minimumCliVersion": "2.1031.2" } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/tree.json index da3102f047b38..96dd6d551f307 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.js.snapshot/tree.json @@ -1,377 +1 @@ -{ - "version": "tree-0.1", - "tree": { - "id": "App", - "path": "", - "children": { - "CompositeAlarmIntegrationTest": { - "id": "CompositeAlarmIntegrationTest", - "path": "CompositeAlarmIntegrationTest", - "children": { - "Alarm1": { - "id": "Alarm1", - "path": "CompositeAlarmIntegrationTest/Alarm1", - "children": { - "Resource": { - "id": "Resource", - "path": "CompositeAlarmIntegrationTest/Alarm1/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::CloudWatch::Alarm", - "aws:cdk:cloudformation:props": { - "comparisonOperator": "GreaterThanOrEqualToThreshold", - "evaluationPeriods": 3, - "metricName": "Metric", - "namespace": "CDK/Test", - "period": 300, - "statistic": "Average", - "threshold": 100 - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_cloudwatch.CfnAlarm", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_cloudwatch.Alarm", - "version": "0.0.0" - } - }, - "Alarm2": { - "id": "Alarm2", - "path": "CompositeAlarmIntegrationTest/Alarm2", - "children": { - "Resource": { - "id": "Resource", - "path": "CompositeAlarmIntegrationTest/Alarm2/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::CloudWatch::Alarm", - "aws:cdk:cloudformation:props": { - "comparisonOperator": "GreaterThanOrEqualToThreshold", - "evaluationPeriods": 3, - "metricName": "Metric", - "namespace": "CDK/Test", - "period": 300, - "statistic": "Average", - "threshold": 1000 - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_cloudwatch.CfnAlarm", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_cloudwatch.Alarm", - "version": "0.0.0" - } - }, - "Alarm3": { - "id": "Alarm3", - "path": "CompositeAlarmIntegrationTest/Alarm3", - "children": { - "Resource": { - "id": "Resource", - "path": "CompositeAlarmIntegrationTest/Alarm3/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::CloudWatch::Alarm", - "aws:cdk:cloudformation:props": { - "comparisonOperator": "GreaterThanOrEqualToThreshold", - "evaluationPeriods": 3, - "metricName": "Metric", - "namespace": "CDK/Test", - "period": 300, - "statistic": "Average", - "threshold": 10000 - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_cloudwatch.CfnAlarm", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_cloudwatch.Alarm", - "version": "0.0.0" - } - }, - "Alarm4": { - "id": "Alarm4", - "path": "CompositeAlarmIntegrationTest/Alarm4", - "children": { - "Resource": { - "id": "Resource", - "path": "CompositeAlarmIntegrationTest/Alarm4/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::CloudWatch::Alarm", - "aws:cdk:cloudformation:props": { - "comparisonOperator": "GreaterThanOrEqualToThreshold", - "evaluationPeriods": 3, - "metricName": "Metric", - "namespace": "CDK/Test", - "period": 300, - "statistic": "Average", - "threshold": 100000 - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_cloudwatch.CfnAlarm", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_cloudwatch.Alarm", - "version": "0.0.0" - } - }, - "Alarm5": { - "id": "Alarm5", - "path": "CompositeAlarmIntegrationTest/Alarm5", - "children": { - "Resource": { - "id": "Resource", - "path": "CompositeAlarmIntegrationTest/Alarm5/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::CloudWatch::Alarm", - "aws:cdk:cloudformation:props": { - "comparisonOperator": "GreaterThanOrEqualToThreshold", - "evaluationPeriods": 3, - "alarmName": "Alarm with space in name", - "metricName": "Metric", - "namespace": "CDK/Test", - "period": 300, - "statistic": "Average", - "threshold": 100000 - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_cloudwatch.CfnAlarm", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_cloudwatch.Alarm", - "version": "0.0.0" - } - }, - "CompositeAlarm": { - "id": "CompositeAlarm", - "path": "CompositeAlarmIntegrationTest/CompositeAlarm", - "children": { - "Resource": { - "id": "Resource", - "path": "CompositeAlarmIntegrationTest/CompositeAlarm/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::CloudWatch::CompositeAlarm", - "aws:cdk:cloudformation:props": { - "alarmRule": { - "Fn::Join": [ - "", - [ - "(((ALARM(\"", - { - "Fn::GetAtt": [ - "Alarm1F9009D71", - "Arn" - ] - }, - "\") OR OK(\"", - { - "Fn::GetAtt": [ - "Alarm2A7122E13", - "Arn" - ] - }, - "\") OR ALARM(\"", - { - "Fn::GetAtt": [ - "Alarm32341D8D9", - "Arn" - ] - }, - "\") OR ALARM(\"", - { - "Fn::GetAtt": [ - "Alarm548383B2F", - "Arn" - ] - }, - "\")) AND (NOT (INSUFFICIENT_DATA(\"", - { - "Fn::GetAtt": [ - "Alarm4671832C8", - "Arn" - ] - }, - "\")))) OR FALSE)" - ] - ] - }, - "actionsSuppressor": { - "Fn::GetAtt": [ - "Alarm548383B2F", - "Arn" - ] - }, - "actionsSuppressorExtensionPeriod": 60, - "actionsSuppressorWaitPeriod": 60, - "alarmName": "CompositeAlarmIntegrationTestCompositeAlarm742D2FBA" - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_cloudwatch.CfnCompositeAlarm", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.aws_cloudwatch.CompositeAlarm", - "version": "0.0.0" - } - }, - "BootstrapVersion": { - "id": "BootstrapVersion", - "path": "CompositeAlarmIntegrationTest/BootstrapVersion", - "constructInfo": { - "fqn": "aws-cdk-lib.CfnParameter", - "version": "0.0.0" - } - }, - "CheckBootstrapVersion": { - "id": "CheckBootstrapVersion", - "path": "CompositeAlarmIntegrationTest/CheckBootstrapVersion", - "constructInfo": { - "fqn": "aws-cdk-lib.CfnRule", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.Stack", - "version": "0.0.0" - } - }, - "CompositeAlarmImportIntegrationTest": { - "id": "CompositeAlarmImportIntegrationTest", - "path": "CompositeAlarmImportIntegrationTest", - "children": { - "alarm": { - "id": "alarm", - "path": "CompositeAlarmImportIntegrationTest/alarm", - "constructInfo": { - "fqn": "aws-cdk-lib.aws_cloudwatch.AlarmBase", - "version": "0.0.0" - } - }, - "AlarmName": { - "id": "AlarmName", - "path": "CompositeAlarmImportIntegrationTest/AlarmName", - "constructInfo": { - "fqn": "aws-cdk-lib.CfnOutput", - "version": "0.0.0" - } - }, - "AlarmArn": { - "id": "AlarmArn", - "path": "CompositeAlarmImportIntegrationTest/AlarmArn", - "constructInfo": { - "fqn": "aws-cdk-lib.CfnOutput", - "version": "0.0.0" - } - }, - "BootstrapVersion": { - "id": "BootstrapVersion", - "path": "CompositeAlarmImportIntegrationTest/BootstrapVersion", - "constructInfo": { - "fqn": "aws-cdk-lib.CfnParameter", - "version": "0.0.0" - } - }, - "CheckBootstrapVersion": { - "id": "CheckBootstrapVersion", - "path": "CompositeAlarmImportIntegrationTest/CheckBootstrapVersion", - "constructInfo": { - "fqn": "aws-cdk-lib.CfnRule", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.Stack", - "version": "0.0.0" - } - }, - "cdk-integ-composite-alarm": { - "id": "cdk-integ-composite-alarm", - "path": "cdk-integ-composite-alarm", - "children": { - "DefaultTest": { - "id": "DefaultTest", - "path": "cdk-integ-composite-alarm/DefaultTest", - "children": { - "Default": { - "id": "Default", - "path": "cdk-integ-composite-alarm/DefaultTest/Default", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.270" - } - }, - "DeployAssert": { - "id": "DeployAssert", - "path": "cdk-integ-composite-alarm/DefaultTest/DeployAssert", - "children": { - "BootstrapVersion": { - "id": "BootstrapVersion", - "path": "cdk-integ-composite-alarm/DefaultTest/DeployAssert/BootstrapVersion", - "constructInfo": { - "fqn": "aws-cdk-lib.CfnParameter", - "version": "0.0.0" - } - }, - "CheckBootstrapVersion": { - "id": "CheckBootstrapVersion", - "path": "cdk-integ-composite-alarm/DefaultTest/DeployAssert/CheckBootstrapVersion", - "constructInfo": { - "fqn": "aws-cdk-lib.CfnRule", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.Stack", - "version": "0.0.0" - } - } - }, - "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.1.270" - } - } - }, - "constructInfo": { - "fqn": "aws-cdk-lib.App", - "version": "0.0.0" - } - } -} \ No newline at end of file +{"version":"tree-0.1","tree":{"id":"App","path":"","constructInfo":{"fqn":"aws-cdk-lib.App","version":"0.0.0"},"children":{"CompositeAlarmIntegrationTest":{"id":"CompositeAlarmIntegrationTest","path":"CompositeAlarmIntegrationTest","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"Alarm1":{"id":"Alarm1","path":"CompositeAlarmIntegrationTest/Alarm1","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.Alarm","version":"0.0.0","metadata":[{"metric":{"warnings":"*","warningsV2":"*"},"threshold":"*","evaluationPeriods":"*"}]},"children":{"Resource":{"id":"Resource","path":"CompositeAlarmIntegrationTest/Alarm1/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.CfnAlarm","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::CloudWatch::Alarm","aws:cdk:cloudformation:props":{"comparisonOperator":"GreaterThanOrEqualToThreshold","evaluationPeriods":3,"metricName":"Metric","namespace":"CDK/Test","period":300,"statistic":"Average","threshold":100}}}}},"Alarm2":{"id":"Alarm2","path":"CompositeAlarmIntegrationTest/Alarm2","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.Alarm","version":"0.0.0","metadata":[{"metric":{"warnings":"*","warningsV2":"*"},"threshold":"*","evaluationPeriods":"*"}]},"children":{"Resource":{"id":"Resource","path":"CompositeAlarmIntegrationTest/Alarm2/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.CfnAlarm","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::CloudWatch::Alarm","aws:cdk:cloudformation:props":{"comparisonOperator":"GreaterThanOrEqualToThreshold","evaluationPeriods":3,"metricName":"Metric","namespace":"CDK/Test","period":300,"statistic":"Average","threshold":1000}}}}},"Alarm3":{"id":"Alarm3","path":"CompositeAlarmIntegrationTest/Alarm3","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.Alarm","version":"0.0.0","metadata":[{"metric":{"warnings":"*","warningsV2":"*"},"threshold":"*","evaluationPeriods":"*"}]},"children":{"Resource":{"id":"Resource","path":"CompositeAlarmIntegrationTest/Alarm3/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.CfnAlarm","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::CloudWatch::Alarm","aws:cdk:cloudformation:props":{"comparisonOperator":"GreaterThanOrEqualToThreshold","evaluationPeriods":3,"metricName":"Metric","namespace":"CDK/Test","period":300,"statistic":"Average","threshold":10000}}}}},"Alarm4":{"id":"Alarm4","path":"CompositeAlarmIntegrationTest/Alarm4","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.Alarm","version":"0.0.0","metadata":[{"metric":{"warnings":"*","warningsV2":"*"},"threshold":"*","evaluationPeriods":"*"}]},"children":{"Resource":{"id":"Resource","path":"CompositeAlarmIntegrationTest/Alarm4/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.CfnAlarm","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::CloudWatch::Alarm","aws:cdk:cloudformation:props":{"comparisonOperator":"GreaterThanOrEqualToThreshold","evaluationPeriods":3,"metricName":"Metric","namespace":"CDK/Test","period":300,"statistic":"Average","threshold":100000}}}}},"Alarm5":{"id":"Alarm5","path":"CompositeAlarmIntegrationTest/Alarm5","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.Alarm","version":"0.0.0","metadata":[{"alarmName":"*","metric":{"warnings":"*","warningsV2":"*"},"threshold":"*","evaluationPeriods":"*"}]},"children":{"Resource":{"id":"Resource","path":"CompositeAlarmIntegrationTest/Alarm5/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.CfnAlarm","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::CloudWatch::Alarm","aws:cdk:cloudformation:props":{"alarmName":"Alarm with space in name","comparisonOperator":"GreaterThanOrEqualToThreshold","evaluationPeriods":3,"metricName":"Metric","namespace":"CDK/Test","period":300,"statistic":"Average","threshold":100000}}}}},"CompositeAlarm":{"id":"CompositeAlarm","path":"CompositeAlarmIntegrationTest/CompositeAlarm","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.CompositeAlarm","version":"0.0.0","metadata":[{"alarmRule":"*","actionsSuppressor":"*"}]},"children":{"Resource":{"id":"Resource","path":"CompositeAlarmIntegrationTest/CompositeAlarm/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.CfnCompositeAlarm","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::CloudWatch::CompositeAlarm","aws:cdk:cloudformation:props":{"actionsSuppressor":{"Fn::GetAtt":["Alarm548383B2F","Arn"]},"actionsSuppressorExtensionPeriod":60,"actionsSuppressorWaitPeriod":60,"alarmName":"CompositeAlarmIntegrationTestCompositeAlarm742D2FBA","alarmRule":{"Fn::Join":["",["(((ALARM(\"",{"Fn::GetAtt":["Alarm1F9009D71","Arn"]},"\") OR OK(\"",{"Fn::GetAtt":["Alarm2A7122E13","Arn"]},"\") OR ALARM(\"",{"Fn::GetAtt":["Alarm32341D8D9","Arn"]},"\") OR ALARM(\"",{"Fn::GetAtt":["Alarm548383B2F","Arn"]},"\")) AND (NOT (INSUFFICIENT_DATA(\"",{"Fn::GetAtt":["Alarm4671832C8","Arn"]},"\"))) AND AT_LEAST(2, ALARM, (",{"Fn::GetAtt":["Alarm1F9009D71","Arn"]},", ",{"Fn::GetAtt":["Alarm2A7122E13","Arn"]},", ",{"Fn::GetAtt":["Alarm32341D8D9","Arn"]},")) AND AT_LEAST(60%, NOT OK, (",{"Fn::GetAtt":["Alarm1F9009D71","Arn"]},", ",{"Fn::GetAtt":["Alarm2A7122E13","Arn"]},", ",{"Fn::GetAtt":["Alarm32341D8D9","Arn"]},"))) OR FALSE)"]]}}}}}},"BootstrapVersion":{"id":"BootstrapVersion","path":"CompositeAlarmIntegrationTest/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"CompositeAlarmIntegrationTest/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}},"CompositeAlarmImportIntegrationTest":{"id":"CompositeAlarmImportIntegrationTest","path":"CompositeAlarmImportIntegrationTest","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"alarm":{"id":"alarm","path":"CompositeAlarmImportIntegrationTest/alarm","constructInfo":{"fqn":"aws-cdk-lib.aws_cloudwatch.AlarmBase","version":"0.0.0","metadata":[]}},"AlarmName":{"id":"AlarmName","path":"CompositeAlarmImportIntegrationTest/AlarmName","constructInfo":{"fqn":"aws-cdk-lib.CfnOutput","version":"0.0.0"}},"AlarmArn":{"id":"AlarmArn","path":"CompositeAlarmImportIntegrationTest/AlarmArn","constructInfo":{"fqn":"aws-cdk-lib.CfnOutput","version":"0.0.0"}},"BootstrapVersion":{"id":"BootstrapVersion","path":"CompositeAlarmImportIntegrationTest/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"CompositeAlarmImportIntegrationTest/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}},"cdk-integ-composite-alarm":{"id":"cdk-integ-composite-alarm","path":"cdk-integ-composite-alarm","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTest","version":"0.0.0"},"children":{"DefaultTest":{"id":"DefaultTest","path":"cdk-integ-composite-alarm/DefaultTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTestCase","version":"0.0.0"},"children":{"Default":{"id":"Default","path":"cdk-integ-composite-alarm/DefaultTest/Default","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"DeployAssert":{"id":"DeployAssert","path":"cdk-integ-composite-alarm/DefaultTest/DeployAssert","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"BootstrapVersion":{"id":"BootstrapVersion","path":"cdk-integ-composite-alarm/DefaultTest/DeployAssert/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"cdk-integ-composite-alarm/DefaultTest/DeployAssert/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}}}}}},"Tree":{"id":"Tree","path":"Tree","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-cloudwatch/test/integ.composite-alarm.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.ts index 6b7a0b93647b8..7126e2d8a3509 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudwatch/test/integ.composite-alarm.ts @@ -1,7 +1,7 @@ import type { StackProps } from 'aws-cdk-lib'; import { App, CfnOutput, Stack } from 'aws-cdk-lib'; import { IntegTest } from '@aws-cdk/integ-tests-alpha'; -import { Alarm, AlarmRule, AlarmState, CompositeAlarm, Metric } from 'aws-cdk-lib/aws-cloudwatch'; +import { Alarm, AlarmRule, AlarmState, AtLeastThreshold, CompositeAlarm, Metric } from 'aws-cdk-lib/aws-cloudwatch'; class CompositeAlarmIntegrationTest extends Stack { constructor(scope: App, id: string, props?: StackProps) { @@ -52,6 +52,14 @@ class CompositeAlarmIntegrationTest extends Stack { alarm5, ), AlarmRule.not(AlarmRule.fromAlarm(alarm4, AlarmState.INSUFFICIENT_DATA)), + AlarmRule.atLeastAlarm({ + operands: [alarm1, alarm2, alarm3], + threshold: AtLeastThreshold.count(2), + }), + AlarmRule.atLeastNotOk({ + operands: [alarm1, alarm2, alarm3], + threshold: AtLeastThreshold.percentage(60), + }), ), AlarmRule.fromBoolean(false), ); diff --git a/packages/aws-cdk-lib/aws-cloudwatch/README.md b/packages/aws-cdk-lib/aws-cloudwatch/README.md index 5902054ccd3bc..197d855818ad4 100644 --- a/packages/aws-cdk-lib/aws-cloudwatch/README.md +++ b/packages/aws-cdk-lib/aws-cloudwatch/README.md @@ -399,6 +399,10 @@ const alarmRule = cloudwatch.AlarmRule.anyOf( alarm1, cloudwatch.AlarmRule.fromAlarm(alarm2, cloudwatch.AlarmState.OK), alarm3, + cloudwatch.AlarmRule.atLeastAlarm({ + operands: [alarm1, alarm2, alarm3], + threshold: cloudwatch.AtLeastThreshold.count(2), + }), ), cloudwatch.AlarmRule.not(cloudwatch.AlarmRule.fromAlarm(alarm4, cloudwatch.AlarmState.INSUFFICIENT_DATA)), ), diff --git a/packages/aws-cdk-lib/aws-cloudwatch/lib/alarm-rule.ts b/packages/aws-cdk-lib/aws-cloudwatch/lib/alarm-rule.ts index f7e1a71a77a94..a777a9b7056f8 100644 --- a/packages/aws-cdk-lib/aws-cloudwatch/lib/alarm-rule.ts +++ b/packages/aws-cdk-lib/aws-cloudwatch/lib/alarm-rule.ts @@ -1,5 +1,5 @@ -import type { IAlarmRule } from './alarm-base'; -import { UnscopedValidationError } from '../../core'; +import type { IAlarm, IAlarmRule } from './alarm-base'; +import { Token, UnscopedValidationError } from '../../core'; import type { IAlarmRef } from '../../interfaces/generated/aws-cloudwatch-interfaces.generated'; /** @@ -35,6 +35,111 @@ enum Operator { } +/** + * Options for AT_LEAST AlarmRule wrapper function + */ +export interface AtLeastOptions { + + /** + * operands for AT_LEAST expression + * + * can specify an array of CloudWatch Alarms or Alarm Rule expressions + */ + readonly operands: IAlarm[]; + + /** + * threshold for AT_LEAST expression + * + * threshold can be an absolute number or percentage + */ + readonly threshold: AtLeastThreshold; +} + +/** + * configuration for creating a threshold for AT_LEAST expression + */ +interface AtLeastThresholdConfig { + /** + * threshold of AT_LEAST expression + * + * threshold can be an absolute number or percentage + */ + readonly threshold: string; +} + +/** + * abstract base class for threshold for AT_LEAST expression + */ +export abstract class AtLeastThreshold { + /** + * Creates count threshold configration for AT_LEAST expression + */ + public static count(count: number): AtLeastThresholdCount { + return new AtLeastThresholdCount(count); + } + + /** + * Creates percentage threshold configration for AT_LEAST expression + */ + public static percentage(percentage: number): AtLeastThresholdPercentage { + return new AtLeastThresholdPercentage(percentage); + } + + /** + * Called when the threshold is initialized to allow this object to bind + * + * @internal + */ + public abstract _bind(operands: IAlarm[]): AtLeastThresholdConfig; +} + +/** + * count threshold for AT_LEAST expression + */ +export class AtLeastThresholdCount extends AtLeastThreshold { + constructor(private readonly count: number) { + super(); + } + + /** + * Called when the threshold is initialized to allow this object to bind + * + * @internal + */ + _bind(operands: IAlarm[]): AtLeastThresholdConfig { + if (this.count !== undefined && !Token.isUnresolved(this.count) + && (this.count < 1 || operands.length < this.count || !Number.isInteger(this.count))) { + throw new UnscopedValidationError(`count must be between 1 and alarm length(${operands.length}) integer, got ${this.count}`); + } + return { + threshold: `${this.count}`, + }; + } +} + +/** + * percentage threshold for AT_LEAST expression + */ +export class AtLeastThresholdPercentage extends AtLeastThreshold { + constructor(private readonly percentage: number) { + super(); + } + /** + * Called when the threshold is initialized to allow this object to bind + * + * @internal + */ + _bind(_operands: IAlarm[]): AtLeastThresholdConfig { + if (this.percentage !== undefined && !Token.isUnresolved(this.percentage) + && (this.percentage < 1 || 100 < this.percentage || !Number.isInteger(this.percentage))) { + throw new UnscopedValidationError(`percentage must be between 1 and 100, got ${this.percentage}`); + } + return { + threshold: `${this.percentage}%`, + }; + } +} + /** * Class with static functions to build AlarmRule for Composite Alarms. */ @@ -70,6 +175,67 @@ export class AlarmRule { }; } + /** + * function to wrap provided AlarmRule in AT_LEAST expression for ALARM state. + * + * @param options options for creating a new AlarmRule. + */ + public static atLeastAlarm(options: AtLeastOptions): IAlarmRule { + const alarmState = `${AlarmState.ALARM}`; + return this.atLeast(alarmState, options); + } + + /** + * function to wrap provided AlarmRule in AT_LEAST expression for OK state. + * + * @param options options for creating a new AlarmRule. + */ + public static atLeastOk(options: AtLeastOptions): IAlarmRule { + const alarmState = `${AlarmState.OK}`; + return this.atLeast(alarmState, options); + } + + /** + * function to wrap provided AlarmRule in AT_LEAST expression for INSUFFICIENT_DATA state. + * + * @param options options for creating a new AlarmRule. + */ + public static atLeastInsufficient(options: AtLeastOptions): IAlarmRule { + const alarmState = `${AlarmState.INSUFFICIENT_DATA}`; + return this.atLeast(alarmState, options); + } + + /** + * function to wrap provided AlarmRule in AT_LEAST expression for NOT ALARM state. + * + * @param options options for creating a new AlarmRule. + */ + public static atLeastNotAlarm(options: AtLeastOptions): IAlarmRule { + const alarmState = `${Operator.NOT} ${AlarmState.ALARM}`; + return this.atLeast(alarmState, options); + } + + /** + * function to wrap provided AlarmRule in AT_LEAST expression for NOT OK state. + * + * @param options options for creating a new AlarmRule. + */ + public static atLeastNotOk(options: AtLeastOptions): IAlarmRule { + options; + const alarmState = `${Operator.NOT} ${AlarmState.OK}`; + return this.atLeast(alarmState, options); + } + + /** + * function to wrap provided AlarmRule in AT_LEAST expression for NOT INSUFFICIENT_DATA state. + * + * @param options options for creating a new AlarmRule. + */ + public static atLeastNotInsufficient(options: AtLeastOptions): IAlarmRule { + const alarmState = `${Operator.NOT} ${AlarmState.INSUFFICIENT_DATA}`; + return this.atLeast(alarmState, options); + } + /** * function to build TRUE/FALSE intent for Rule Expression. * @@ -124,4 +290,21 @@ export class AlarmRule { } }; } + + private static atLeast(alarmState: string, props: AtLeastOptions): IAlarmRule { + return new class implements IAlarmRule { + public renderAlarmRule(): string { + if (props.operands.length === 0) { + throw new UnscopedValidationError(`Did not detect any operands for AT_LEAST ${alarmState}`); + } + + const thresholdConfig = props.threshold._bind(props.operands); + const concatAlarms = props.operands + .map(operand => `${operand.alarmArn}`) + .join(', '); + + return `AT_LEAST(${thresholdConfig.threshold}, ${alarmState}, (${concatAlarms}))`; + } + }; + } } diff --git a/packages/aws-cdk-lib/aws-cloudwatch/test/composite-alarm.test.ts b/packages/aws-cdk-lib/aws-cloudwatch/test/composite-alarm.test.ts index 8b4f1058fce7a..d4b52ad2234b9 100644 --- a/packages/aws-cdk-lib/aws-cloudwatch/test/composite-alarm.test.ts +++ b/packages/aws-cdk-lib/aws-cloudwatch/test/composite-alarm.test.ts @@ -1,6 +1,6 @@ import { Template } from '../../assertions'; import { Duration, Stack } from '../../core'; -import { Alarm, AlarmRule, AlarmState, CompositeAlarm, Metric } from '../lib'; +import { Alarm, AlarmRule, AlarmState, AtLeastThreshold, CompositeAlarm, Metric } from '../lib'; describe('CompositeAlarm', () => { test('test alarm rule expression builder', () => { @@ -51,6 +51,14 @@ describe('CompositeAlarm', () => { alarm5, ), AlarmRule.not(AlarmRule.fromAlarm(alarm4, AlarmState.INSUFFICIENT_DATA)), + AlarmRule.atLeastAlarm({ + operands: [alarm1, alarm2, alarm3], + threshold: AtLeastThreshold.count(2), + }), + AlarmRule.atLeastNotOk({ + operands: [alarm1, alarm2, alarm3], + threshold: AtLeastThreshold.percentage(60), + }), ), AlarmRule.fromBoolean(false), ); @@ -100,7 +108,19 @@ describe('CompositeAlarm', () => { 'Arn', ], }, - '")))) OR FALSE)', + '"))) AND AT_LEAST(2, ALARM, (', + { 'Fn::GetAtt': ['Alarm1F9009D71', 'Arn'] }, + ', ', + { 'Fn::GetAtt': ['Alarm2A7122E13', 'Arn'] }, + ', ', + { 'Fn::GetAtt': ['Alarm32341D8D9', 'Arn'] }, + ')) AND AT_LEAST(60%, NOT OK, (', + { 'Fn::GetAtt': ['Alarm1F9009D71', 'Arn'] }, + ', ', + { 'Fn::GetAtt': ['Alarm2A7122E13', 'Arn'] }, + ', ', + { 'Fn::GetAtt': ['Alarm32341D8D9', 'Arn'] }, + '))) OR FALSE)', ], ], }, @@ -216,4 +236,48 @@ describe('CompositeAlarm', () => { alarmRule: AlarmRule.allOf(), })).toThrow('Did not detect any operands for AlarmRule.allOf'); }); + + test('empty operands for atLeast', () => { + expect(() => new CompositeAlarm(new Stack(), 'alarm', { + alarmRule: AlarmRule.atLeastAlarm({ operands: [], threshold: AtLeastThreshold.count(1) }), + })).toThrow('Did not detect any operands for AT_LEAST ALARM'); + }); + + test.each([0, 3, 1.5])('count of atLeast: %s', (count: number) => { + const stack = new Stack(); + + const testMetric = new Metric({ + namespace: 'CDK/Test', + metricName: 'Metric', + }); + + const alarm = new Alarm(stack, 'Alarm1', { + metric: testMetric, + threshold: 100, + evaluationPeriods: 3, + }); + + expect(() => new CompositeAlarm(new Stack(), 'alarm', { + alarmRule: AlarmRule.atLeastOk({ operands: [alarm], threshold: AtLeastThreshold.count(count) }), + })).toThrow(`count must be between 1 and alarm length(1) integer, got ${count}`); + }); + + test.each([0, 101, 1.5])('percentage of atLeast: %s%', (percentage: number) => { + const stack = new Stack(); + + const testMetric = new Metric({ + namespace: 'CDK/Test', + metricName: 'Metric', + }); + + const alarm = new Alarm(stack, 'Alarm1', { + metric: testMetric, + threshold: 100, + evaluationPeriods: 3, + }); + + expect(() => new CompositeAlarm(new Stack(), 'alarm', { + alarmRule: AlarmRule.atLeastOk({ operands: [alarm], threshold: AtLeastThreshold.percentage(percentage) }), + })).toThrow(`percentage must be between 1 and 100, got ${percentage}`); + }); });