From cdf8bd04003e51f3497dc60dd16a7a88842a6b8e Mon Sep 17 00:00:00 2001
From: zqumei0 <92476851+zqumei0@users.noreply.github.com>
Date: Thu, 6 Jul 2023 15:23:57 -0400
Subject: [PATCH] feat(SecretsManager): Add support for secrets count metric
(#333)
Added new Secrets Manager Monitor to support Account-Level Secrets Count. This includes a new SecretsManagerMonitor, a new SecretsManagerMetricsFactory, and a new SecretsManagerAlarmFactory. There is alarm support for Min/Max Secrets count and change in secrets count.
Closes #137
---
_By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license_
---
API.md | 1568 ++++++++++++++++-
README.md | 3 +-
.../alarms/SecretsManagerAlarmFactory.ts | 118 ++
lib/common/monitoring/alarms/index.ts | 1 +
lib/facade/MonitoringFacade.ts | 8 +
.../SecretsManagerMetricFactory.ts | 37 +
.../SecretsManagerMonitoring.ts | 139 ++
lib/monitoring/aws-secretsmanager/index.ts | 2 +
.../SecretsManagerMonitoring.test.ts | 57 +
.../SecretsManagerMonitoring.test.ts.snap | 341 ++++
10 files changed, 2271 insertions(+), 3 deletions(-)
create mode 100644 lib/common/monitoring/alarms/SecretsManagerAlarmFactory.ts
create mode 100644 lib/monitoring/aws-secretsmanager/SecretsManagerMetricFactory.ts
create mode 100644 lib/monitoring/aws-secretsmanager/SecretsManagerMonitoring.ts
create mode 100644 test/monitoring/aws-secretsmanager/SecretsManagerMonitoring.test.ts
create mode 100644 test/monitoring/aws-secretsmanager/__snapshots__/SecretsManagerMonitoring.test.ts.snap
diff --git a/API.md b/API.md
index bd712755..776f2c76 100644
--- a/API.md
+++ b/API.md
@@ -1061,6 +1061,7 @@ new MonitoringFacade(scope: Construct, id: string, props?: MonitoringFacadeProps
| monitorRedshiftCluster
| *No description.* |
| monitorS3Bucket
| *No description.* |
| monitorScope
| Uses an aspect to automatically monitor all resources in the given scope. |
+| monitorSecretsManager
| *No description.* |
| monitorSecretsManagerSecret
| *No description.* |
| monitorSimpleEc2Service
| *No description.* |
| monitorSimpleFargateService
| *No description.* |
@@ -1812,6 +1813,18 @@ Optional configuration.
---
+##### `monitorSecretsManager`
+
+```typescript
+public monitorSecretsManager(props: SecretsManagerMonitoringProps): MonitoringFacade
+```
+
+###### `props`Required
+
+- *Type:* SecretsManagerMonitoringProps
+
+---
+
##### `monitorSecretsManagerSecret`
```typescript
@@ -8655,6 +8668,319 @@ public readonly certificate: ICertificate;
---
+### ChangeInSecretCountThreshold
+
+#### Initializer
+
+```typescript
+import { ChangeInSecretCountThreshold } from 'cdk-monitoring-constructs'
+
+const changeInSecretCountThreshold: ChangeInSecretCountThreshold = { ... }
+```
+
+#### Properties
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| actionOverride
| IAlarmActionStrategy
| Allows to override the default alarm action. |
+| actionsEnabled
| boolean
| Enables the configured CloudWatch alarm ticketing actions. |
+| alarmDescriptionOverride
| string
| A text included in the generated ticket description body, which fully replaces the generated text. |
+| alarmNameOverride
| string
| If this is defined, the alarm name is set to this exact value. |
+| comparisonOperatorOverride
| aws-cdk-lib.aws_cloudwatch.ComparisonOperator
| Comparison operator used to compare actual value against the threshold. |
+| customParams
| {[ key: string ]: any}
| This allows user to attach custom parameters to this alarm, which can later be accessed from the "useCreatedAlarms" method. |
+| customTags
| string[]
| This allows user to attach custom values to this alarm, which can later be accessed from the "useCreatedAlarms" method. |
+| datapointsToAlarm
| number
| Number of breaches required to transition into an ALARM state. |
+| dedupeStringOverride
| string
| If this is defined, the alarm dedupe string is set to this exact value. |
+| documentationLink
| string
| An optional link included in the generated ticket description body. |
+| evaluateLowSampleCountPercentile
| boolean
| Used only for alarms based on percentiles. |
+| evaluationPeriods
| number
| Number of periods to consider when checking the number of breaching datapoints. |
+| fillAlarmRange
| boolean
| Indicates whether the alarming range of values should be highlighted in the widget. |
+| minMetricSamplesToAlarm
| number
| Specifies how many samples (N) of the metric is needed to trigger the alarm. |
+| period
| aws-cdk-lib.Duration
| Period override for the metric to alarm on. |
+| runbookLink
| string
| An optional link included in the generated ticket description body. |
+| treatMissingDataOverride
| aws-cdk-lib.aws_cloudwatch.TreatMissingData
| Behaviour in case the metric data is missing. |
+| alarmWhenDecreased
| boolean
| *No description.* |
+| alarmWhenIncreased
| boolean
| *No description.* |
+| requiredSecretCount
| number
| *No description.* |
+| additionalDescription
| string
| *No description.* |
+
+---
+
+##### `actionOverride`Optional
+
+```typescript
+public readonly actionOverride: IAlarmActionStrategy;
+```
+
+- *Type:* IAlarmActionStrategy
+- *Default:* undefined (default action will be used, if any)
+
+Allows to override the default alarm action.
+
+---
+
+##### `actionsEnabled`Optional
+
+```typescript
+public readonly actionsEnabled: boolean;
+```
+
+- *Type:* boolean
+- *Default:* the same as monitoring facade default
+
+Enables the configured CloudWatch alarm ticketing actions.
+
+---
+
+##### `alarmDescriptionOverride`Optional
+
+```typescript
+public readonly alarmDescriptionOverride: string;
+```
+
+- *Type:* string
+- *Default:* default auto-generated content only
+
+A text included in the generated ticket description body, which fully replaces the generated text.
+
+---
+
+##### `alarmNameOverride`Optional
+
+```typescript
+public readonly alarmNameOverride: string;
+```
+
+- *Type:* string
+
+If this is defined, the alarm name is set to this exact value.
+
+Please be aware that you need to specify prefix for different stages (Beta, Prod...) and realms (EU, NA...) manually.
+
+---
+
+##### `comparisonOperatorOverride`Optional
+
+```typescript
+public readonly comparisonOperatorOverride: ComparisonOperator;
+```
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.ComparisonOperator
+- *Default:* alarm-specific default
+
+Comparison operator used to compare actual value against the threshold.
+
+---
+
+##### `customParams`Optional
+
+```typescript
+public readonly customParams: {[ key: string ]: any};
+```
+
+- *Type:* {[ key: string ]: any}
+- *Default:* no parameters
+
+This allows user to attach custom parameters to this alarm, which can later be accessed from the "useCreatedAlarms" method.
+
+---
+
+##### `customTags`Optional
+
+```typescript
+public readonly customTags: string[];
+```
+
+- *Type:* string[]
+- *Default:* no tags
+
+This allows user to attach custom values to this alarm, which can later be accessed from the "useCreatedAlarms" method.
+
+---
+
+##### `datapointsToAlarm`Optional
+
+```typescript
+public readonly datapointsToAlarm: number;
+```
+
+- *Type:* number
+- *Default:* the same as monitoring facade default
+
+Number of breaches required to transition into an ALARM state.
+
+---
+
+##### `dedupeStringOverride`Optional
+
+```typescript
+public readonly dedupeStringOverride: string;
+```
+
+- *Type:* string
+- *Default:* undefined (no override)
+
+If this is defined, the alarm dedupe string is set to this exact value.
+
+Please be aware that you need to handle deduping for different stages (Beta, Prod...) and realms (EU, NA...) manually.
+Dedupe strings are global and not unique per CTI.
+
+---
+
+##### `documentationLink`Optional
+
+```typescript
+public readonly documentationLink: string;
+```
+
+- *Type:* string
+- *Default:* no additional link will be added
+
+An optional link included in the generated ticket description body.
+
+---
+
+##### `evaluateLowSampleCountPercentile`Optional
+
+```typescript
+public readonly evaluateLowSampleCountPercentile: boolean;
+```
+
+- *Type:* boolean
+- *Default:* true
+
+Used only for alarms based on percentiles.
+
+If you specify false
, the alarm state does not change during periods with too few data points to be statistically significant.
+If you specify true
, the alarm is always evaluated and possibly changes state no matter how many data points are available.
+
+---
+
+##### `evaluationPeriods`Optional
+
+```typescript
+public readonly evaluationPeriods: number;
+```
+
+- *Type:* number
+- *Default:* the same as monitoring facade default
+
+Number of periods to consider when checking the number of breaching datapoints.
+
+---
+
+##### `fillAlarmRange`Optional
+
+```typescript
+public readonly fillAlarmRange: boolean;
+```
+
+- *Type:* boolean
+- *Default:* false
+
+Indicates whether the alarming range of values should be highlighted in the widget.
+
+---
+
+##### `minMetricSamplesToAlarm`Optional
+
+```typescript
+public readonly minMetricSamplesToAlarm: number;
+```
+
+- *Type:* number
+- *Default:* default behaviour - no condition on sample count will be added to the alarm
+
+Specifies how many samples (N) of the metric is needed to trigger the alarm.
+
+If this property is specified, a composite alarm is created of the following:
+
actionOverride
| IAlarmActionStrategy
| Allows to override the default alarm action. |
+| actionsEnabled
| boolean
| Enables the configured CloudWatch alarm ticketing actions. |
+| alarmDescriptionOverride
| string
| A text included in the generated ticket description body, which fully replaces the generated text. |
+| alarmNameOverride
| string
| If this is defined, the alarm name is set to this exact value. |
+| comparisonOperatorOverride
| aws-cdk-lib.aws_cloudwatch.ComparisonOperator
| Comparison operator used to compare actual value against the threshold. |
+| customParams
| {[ key: string ]: any}
| This allows user to attach custom parameters to this alarm, which can later be accessed from the "useCreatedAlarms" method. |
+| customTags
| string[]
| This allows user to attach custom values to this alarm, which can later be accessed from the "useCreatedAlarms" method. |
+| datapointsToAlarm
| number
| Number of breaches required to transition into an ALARM state. |
+| dedupeStringOverride
| string
| If this is defined, the alarm dedupe string is set to this exact value. |
+| documentationLink
| string
| An optional link included in the generated ticket description body. |
+| evaluateLowSampleCountPercentile
| boolean
| Used only for alarms based on percentiles. |
+| evaluationPeriods
| number
| Number of periods to consider when checking the number of breaching datapoints. |
+| fillAlarmRange
| boolean
| Indicates whether the alarming range of values should be highlighted in the widget. |
+| minMetricSamplesToAlarm
| number
| Specifies how many samples (N) of the metric is needed to trigger the alarm. |
+| period
| aws-cdk-lib.Duration
| Period override for the metric to alarm on. |
+| runbookLink
| string
| An optional link included in the generated ticket description body. |
+| treatMissingDataOverride
| aws-cdk-lib.aws_cloudwatch.TreatMissingData
| Behaviour in case the metric data is missing. |
+| maxSecretCount
| number
| *No description.* |
+
+---
+
+##### `actionOverride`Optional
+
+```typescript
+public readonly actionOverride: IAlarmActionStrategy;
+```
+
+- *Type:* IAlarmActionStrategy
+- *Default:* undefined (default action will be used, if any)
+
+Allows to override the default alarm action.
+
+---
+
+##### `actionsEnabled`Optional
+
+```typescript
+public readonly actionsEnabled: boolean;
+```
+
+- *Type:* boolean
+- *Default:* the same as monitoring facade default
+
+Enables the configured CloudWatch alarm ticketing actions.
+
+---
+
+##### `alarmDescriptionOverride`Optional
+
+```typescript
+public readonly alarmDescriptionOverride: string;
+```
+
+- *Type:* string
+- *Default:* default auto-generated content only
+
+A text included in the generated ticket description body, which fully replaces the generated text.
+
+---
+
+##### `alarmNameOverride`Optional
+
+```typescript
+public readonly alarmNameOverride: string;
+```
+
+- *Type:* string
+
+If this is defined, the alarm name is set to this exact value.
+
+Please be aware that you need to specify prefix for different stages (Beta, Prod...) and realms (EU, NA...) manually.
+
+---
+
+##### `comparisonOperatorOverride`Optional
+
+```typescript
+public readonly comparisonOperatorOverride: ComparisonOperator;
+```
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.ComparisonOperator
+- *Default:* alarm-specific default
+
+Comparison operator used to compare actual value against the threshold.
+
+---
+
+##### `customParams`Optional
+
+```typescript
+public readonly customParams: {[ key: string ]: any};
+```
+
+- *Type:* {[ key: string ]: any}
+- *Default:* no parameters
+
+This allows user to attach custom parameters to this alarm, which can later be accessed from the "useCreatedAlarms" method.
+
+---
+
+##### `customTags`Optional
+
+```typescript
+public readonly customTags: string[];
+```
+
+- *Type:* string[]
+- *Default:* no tags
+
+This allows user to attach custom values to this alarm, which can later be accessed from the "useCreatedAlarms" method.
+
+---
+
+##### `datapointsToAlarm`Optional
+
+```typescript
+public readonly datapointsToAlarm: number;
+```
+
+- *Type:* number
+- *Default:* the same as monitoring facade default
+
+Number of breaches required to transition into an ALARM state.
+
+---
+
+##### `dedupeStringOverride`Optional
+
+```typescript
+public readonly dedupeStringOverride: string;
+```
+
+- *Type:* string
+- *Default:* undefined (no override)
+
+If this is defined, the alarm dedupe string is set to this exact value.
+
+Please be aware that you need to handle deduping for different stages (Beta, Prod...) and realms (EU, NA...) manually.
+Dedupe strings are global and not unique per CTI.
+
+---
+
+##### `documentationLink`Optional
+
+```typescript
+public readonly documentationLink: string;
+```
+
+- *Type:* string
+- *Default:* no additional link will be added
+
+An optional link included in the generated ticket description body.
+
+---
+
+##### `evaluateLowSampleCountPercentile`Optional
+
+```typescript
+public readonly evaluateLowSampleCountPercentile: boolean;
+```
+
+- *Type:* boolean
+- *Default:* true
+
+Used only for alarms based on percentiles.
+
+If you specify false
, the alarm state does not change during periods with too few data points to be statistically significant.
+If you specify true
, the alarm is always evaluated and possibly changes state no matter how many data points are available.
+
+---
+
+##### `evaluationPeriods`Optional
+
+```typescript
+public readonly evaluationPeriods: number;
+```
+
+- *Type:* number
+- *Default:* the same as monitoring facade default
+
+Number of periods to consider when checking the number of breaching datapoints.
+
+---
+
+##### `fillAlarmRange`Optional
+
+```typescript
+public readonly fillAlarmRange: boolean;
+```
+
+- *Type:* boolean
+- *Default:* false
+
+Indicates whether the alarming range of values should be highlighted in the widget.
+
+---
+
+##### `minMetricSamplesToAlarm`Optional
+
+```typescript
+public readonly minMetricSamplesToAlarm: number;
+```
+
+- *Type:* number
+- *Default:* default behaviour - no condition on sample count will be added to the alarm
+
+Specifies how many samples (N) of the metric is needed to trigger the alarm.
+
+If this property is specified, a composite alarm is created of the following:
+actionOverride
| IAlarmActionStrategy
| Allows to override the default alarm action. |
+| actionsEnabled
| boolean
| Enables the configured CloudWatch alarm ticketing actions. |
+| alarmDescriptionOverride
| string
| A text included in the generated ticket description body, which fully replaces the generated text. |
+| alarmNameOverride
| string
| If this is defined, the alarm name is set to this exact value. |
+| comparisonOperatorOverride
| aws-cdk-lib.aws_cloudwatch.ComparisonOperator
| Comparison operator used to compare actual value against the threshold. |
+| customParams
| {[ key: string ]: any}
| This allows user to attach custom parameters to this alarm, which can later be accessed from the "useCreatedAlarms" method. |
+| customTags
| string[]
| This allows user to attach custom values to this alarm, which can later be accessed from the "useCreatedAlarms" method. |
+| datapointsToAlarm
| number
| Number of breaches required to transition into an ALARM state. |
+| dedupeStringOverride
| string
| If this is defined, the alarm dedupe string is set to this exact value. |
+| documentationLink
| string
| An optional link included in the generated ticket description body. |
+| evaluateLowSampleCountPercentile
| boolean
| Used only for alarms based on percentiles. |
+| evaluationPeriods
| number
| Number of periods to consider when checking the number of breaching datapoints. |
+| fillAlarmRange
| boolean
| Indicates whether the alarming range of values should be highlighted in the widget. |
+| minMetricSamplesToAlarm
| number
| Specifies how many samples (N) of the metric is needed to trigger the alarm. |
+| period
| aws-cdk-lib.Duration
| Period override for the metric to alarm on. |
+| runbookLink
| string
| An optional link included in the generated ticket description body. |
+| treatMissingDataOverride
| aws-cdk-lib.aws_cloudwatch.TreatMissingData
| Behaviour in case the metric data is missing. |
+| minSecretCount
| number
| *No description.* |
+
+---
+
+##### `actionOverride`Optional
+
+```typescript
+public readonly actionOverride: IAlarmActionStrategy;
+```
+
+- *Type:* IAlarmActionStrategy
+- *Default:* undefined (default action will be used, if any)
+
+Allows to override the default alarm action.
+
+---
+
+##### `actionsEnabled`Optional
+
+```typescript
+public readonly actionsEnabled: boolean;
+```
+
+- *Type:* boolean
+- *Default:* the same as monitoring facade default
+
+Enables the configured CloudWatch alarm ticketing actions.
+
+---
+
+##### `alarmDescriptionOverride`Optional
+
+```typescript
+public readonly alarmDescriptionOverride: string;
+```
+
+- *Type:* string
+- *Default:* default auto-generated content only
+
+A text included in the generated ticket description body, which fully replaces the generated text.
+
+---
+
+##### `alarmNameOverride`Optional
+
+```typescript
+public readonly alarmNameOverride: string;
+```
+
+- *Type:* string
+
+If this is defined, the alarm name is set to this exact value.
+
+Please be aware that you need to specify prefix for different stages (Beta, Prod...) and realms (EU, NA...) manually.
+
+---
+
+##### `comparisonOperatorOverride`Optional
+
+```typescript
+public readonly comparisonOperatorOverride: ComparisonOperator;
+```
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.ComparisonOperator
+- *Default:* alarm-specific default
+
+Comparison operator used to compare actual value against the threshold.
+
+---
+
+##### `customParams`Optional
+
+```typescript
+public readonly customParams: {[ key: string ]: any};
+```
+
+- *Type:* {[ key: string ]: any}
+- *Default:* no parameters
+
+This allows user to attach custom parameters to this alarm, which can later be accessed from the "useCreatedAlarms" method.
+
+---
+
+##### `customTags`Optional
+
+```typescript
+public readonly customTags: string[];
+```
+
+- *Type:* string[]
+- *Default:* no tags
+
+This allows user to attach custom values to this alarm, which can later be accessed from the "useCreatedAlarms" method.
+
+---
+
+##### `datapointsToAlarm`Optional
+
+```typescript
+public readonly datapointsToAlarm: number;
+```
+
+- *Type:* number
+- *Default:* the same as monitoring facade default
+
+Number of breaches required to transition into an ALARM state.
+
+---
+
+##### `dedupeStringOverride`Optional
+
+```typescript
+public readonly dedupeStringOverride: string;
+```
+
+- *Type:* string
+- *Default:* undefined (no override)
+
+If this is defined, the alarm dedupe string is set to this exact value.
+
+Please be aware that you need to handle deduping for different stages (Beta, Prod...) and realms (EU, NA...) manually.
+Dedupe strings are global and not unique per CTI.
+
+---
+
+##### `documentationLink`Optional
+
+```typescript
+public readonly documentationLink: string;
+```
+
+- *Type:* string
+- *Default:* no additional link will be added
+
+An optional link included in the generated ticket description body.
+
+---
+
+##### `evaluateLowSampleCountPercentile`Optional
+
+```typescript
+public readonly evaluateLowSampleCountPercentile: boolean;
+```
+
+- *Type:* boolean
+- *Default:* true
+
+Used only for alarms based on percentiles.
+
+If you specify false
, the alarm state does not change during periods with too few data points to be statistically significant.
+If you specify true
, the alarm is always evaluated and possibly changes state no matter how many data points are available.
+
+---
+
+##### `evaluationPeriods`Optional
+
+```typescript
+public readonly evaluationPeriods: number;
+```
+
+- *Type:* number
+- *Default:* the same as monitoring facade default
+
+Number of periods to consider when checking the number of breaching datapoints.
+
+---
+
+##### `fillAlarmRange`Optional
+
+```typescript
+public readonly fillAlarmRange: boolean;
+```
+
+- *Type:* boolean
+- *Default:* false
+
+Indicates whether the alarming range of values should be highlighted in the widget.
+
+---
+
+##### `minMetricSamplesToAlarm`Optional
+
+```typescript
+public readonly minMetricSamplesToAlarm: number;
+```
+
+- *Type:* number
+- *Default:* default behaviour - no condition on sample count will be added to the alarm
+
+Specifies how many samples (N) of the metric is needed to trigger the alarm.
+
+If this property is specified, a composite alarm is created of the following:
+alarmFriendlyName
| string
| Plain name, used in naming alarms. |
+| humanReadableName
| string
| Human-readable name is a freeform string, used as a caption or description. |
+| localAlarmNamePrefixOverride
| string
| If this is defined, the local alarm name prefix used in naming alarms for the construct will be set to this value. |
+| addToAlarmDashboard
| boolean
| Flag indicating if the widgets should be added to alarm dashboard. |
+| addToDetailDashboard
| boolean
| Flag indicating if the widgets should be added to detailed dashboard. |
+| addToSummaryDashboard
| boolean
| Flag indicating if the widgets should be added to summary dashboard. |
+| useCreatedAlarms
| IAlarmConsumer
| Calls provided function to process all alarms created. |
+| addChangeInSecretsAlarm
| {[ key: string ]: ChangeInSecretCountThreshold}
| *No description.* |
+| addMaxNumberSecretsAlarm
| {[ key: string ]: MaxSecretCountThreshold}
| *No description.* |
+| addMinNumberSecretsAlarm
| {[ key: string ]: MinSecretCountThreshold}
| *No description.* |
+
+---
+
+##### `alarmFriendlyName`Optional
+
+```typescript
+public readonly alarmFriendlyName: string;
+```
+
+- *Type:* string
+- *Default:* derives name from the construct itself
+
+Plain name, used in naming alarms.
+
+This unique among other resources, and respect the AWS CDK restriction posed on alarm names.
+The length must be 1 - 255 characters and although the validation rules are undocumented, we recommend using ASCII and hyphens.
+
+---
+
+##### `humanReadableName`Optional
+
+```typescript
+public readonly humanReadableName: string;
+```
+
+- *Type:* string
+- *Default:* use alarmFriendlyName
+
+Human-readable name is a freeform string, used as a caption or description.
+
+There are no limitations on what it can be.
+
+---
+
+##### `localAlarmNamePrefixOverride`Optional
+
+```typescript
+public readonly localAlarmNamePrefixOverride: string;
+```
+
+- *Type:* string
+
+If this is defined, the local alarm name prefix used in naming alarms for the construct will be set to this value.
+
+The length must be 1 - 255 characters and although the validation rules are undocumented, we recommend using ASCII and hyphens.
+
+> [AlarmNamingStrategy for more details on alarm name prefixes](AlarmNamingStrategy for more details on alarm name prefixes)
+
+---
+
+##### `addToAlarmDashboard`Optional
+
+```typescript
+public readonly addToAlarmDashboard: boolean;
+```
+
+- *Type:* boolean
+- *Default:* true
+
+Flag indicating if the widgets should be added to alarm dashboard.
+
+---
+
+##### `addToDetailDashboard`Optional
+
+```typescript
+public readonly addToDetailDashboard: boolean;
+```
+
+- *Type:* boolean
+- *Default:* true
+
+Flag indicating if the widgets should be added to detailed dashboard.
+
+---
+
+##### `addToSummaryDashboard`Optional
+
+```typescript
+public readonly addToSummaryDashboard: boolean;
+```
+
+- *Type:* boolean
+- *Default:* true
+
+Flag indicating if the widgets should be added to summary dashboard.
+
+---
+
+##### `useCreatedAlarms`Optional
+
+```typescript
+public readonly useCreatedAlarms: IAlarmConsumer;
+```
+
+- *Type:* IAlarmConsumer
+
+Calls provided function to process all alarms created.
+
+---
+
+##### `addChangeInSecretsAlarm`Optional
+
+```typescript
+public readonly addChangeInSecretsAlarm: {[ key: string ]: ChangeInSecretCountThreshold};
+```
+
+- *Type:* {[ key: string ]: ChangeInSecretCountThreshold}
+
+---
+
+##### `addMaxNumberSecretsAlarm`Optional
+
+```typescript
+public readonly addMaxNumberSecretsAlarm: {[ key: string ]: MaxSecretCountThreshold};
+```
+
+- *Type:* {[ key: string ]: MaxSecretCountThreshold}
+
+---
+
+##### `addMinNumberSecretsAlarm`Optional
+
+```typescript
+public readonly addMinNumberSecretsAlarm: {[ key: string ]: MinSecretCountThreshold};
+```
+
+- *Type:* {[ key: string ]: MinSecretCountThreshold}
+
+---
+
+### SecretsManagerMonitoringProps
+
+#### Initializer
+
+```typescript
+import { SecretsManagerMonitoringProps } from 'cdk-monitoring-constructs'
+
+const secretsManagerMonitoringProps: SecretsManagerMonitoringProps = { ... }
+```
+
+#### Properties
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| alarmFriendlyName
| string
| Plain name, used in naming alarms. |
+| humanReadableName
| string
| Human-readable name is a freeform string, used as a caption or description. |
+| localAlarmNamePrefixOverride
| string
| If this is defined, the local alarm name prefix used in naming alarms for the construct will be set to this value. |
+| addToAlarmDashboard
| boolean
| Flag indicating if the widgets should be added to alarm dashboard. |
+| addToDetailDashboard
| boolean
| Flag indicating if the widgets should be added to detailed dashboard. |
+| addToSummaryDashboard
| boolean
| Flag indicating if the widgets should be added to summary dashboard. |
+| useCreatedAlarms
| IAlarmConsumer
| Calls provided function to process all alarms created. |
+| addChangeInSecretsAlarm
| {[ key: string ]: ChangeInSecretCountThreshold}
| *No description.* |
+| addMaxNumberSecretsAlarm
| {[ key: string ]: MaxSecretCountThreshold}
| *No description.* |
+| addMinNumberSecretsAlarm
| {[ key: string ]: MinSecretCountThreshold}
| *No description.* |
+
+---
+
+##### `alarmFriendlyName`Optional
+
+```typescript
+public readonly alarmFriendlyName: string;
+```
+
+- *Type:* string
+- *Default:* derives name from the construct itself
+
+Plain name, used in naming alarms.
+
+This unique among other resources, and respect the AWS CDK restriction posed on alarm names.
+The length must be 1 - 255 characters and although the validation rules are undocumented, we recommend using ASCII and hyphens.
+
+---
+
+##### `humanReadableName`Optional
+
+```typescript
+public readonly humanReadableName: string;
+```
+
+- *Type:* string
+- *Default:* use alarmFriendlyName
+
+Human-readable name is a freeform string, used as a caption or description.
+
+There are no limitations on what it can be.
+
+---
+
+##### `localAlarmNamePrefixOverride`Optional
+
+```typescript
+public readonly localAlarmNamePrefixOverride: string;
+```
+
+- *Type:* string
+
+If this is defined, the local alarm name prefix used in naming alarms for the construct will be set to this value.
+
+The length must be 1 - 255 characters and although the validation rules are undocumented, we recommend using ASCII and hyphens.
+
+> [AlarmNamingStrategy for more details on alarm name prefixes](AlarmNamingStrategy for more details on alarm name prefixes)
+
+---
+
+##### `addToAlarmDashboard`Optional
+
+```typescript
+public readonly addToAlarmDashboard: boolean;
+```
+
+- *Type:* boolean
+- *Default:* true
+
+Flag indicating if the widgets should be added to alarm dashboard.
+
+---
+
+##### `addToDetailDashboard`Optional
+
+```typescript
+public readonly addToDetailDashboard: boolean;
+```
+
+- *Type:* boolean
+- *Default:* true
+
+Flag indicating if the widgets should be added to detailed dashboard.
+
+---
+
+##### `addToSummaryDashboard`Optional
+
+```typescript
+public readonly addToSummaryDashboard: boolean;
+```
+
+- *Type:* boolean
+- *Default:* true
+
+Flag indicating if the widgets should be added to summary dashboard.
+
+---
+
+##### `useCreatedAlarms`Optional
+
+```typescript
+public readonly useCreatedAlarms: IAlarmConsumer;
+```
+
+- *Type:* IAlarmConsumer
+
+Calls provided function to process all alarms created.
+
+---
+
+##### `addChangeInSecretsAlarm`Optional
+
+```typescript
+public readonly addChangeInSecretsAlarm: {[ key: string ]: ChangeInSecretCountThreshold};
+```
+
+- *Type:* {[ key: string ]: ChangeInSecretCountThreshold}
+
+---
+
+##### `addMaxNumberSecretsAlarm`Optional
+
+```typescript
+public readonly addMaxNumberSecretsAlarm: {[ key: string ]: MaxSecretCountThreshold};
+```
+
+- *Type:* {[ key: string ]: MaxSecretCountThreshold}
+
+---
+
+##### `addMinNumberSecretsAlarm`Optional
+
+```typescript
+public readonly addMinNumberSecretsAlarm: {[ key: string ]: MinSecretCountThreshold};
+```
+
+- *Type:* {[ key: string ]: MinSecretCountThreshold}
+
+---
+
### SecretsManagerSecretMetricFactoryProps
#### Initializer
@@ -56353,6 +57549,374 @@ Returns widgets for the requested dashboard type.
+### SecretsManagerAlarmFactory
+
+#### Initializers
+
+```typescript
+import { SecretsManagerAlarmFactory } from 'cdk-monitoring-constructs'
+
+new SecretsManagerAlarmFactory(alarmFactory: AlarmFactory)
+```
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| alarmFactory
| AlarmFactory
| *No description.* |
+
+---
+
+##### `alarmFactory`Required
+
+- *Type:* AlarmFactory
+
+---
+
+#### Methods
+
+| **Name** | **Description** |
+| --- | --- |
+| addChangeInSecretCountAlarm
| *No description.* |
+| addMaxSecretCountAlarm
| *No description.* |
+| addMinSecretCountAlarm
| *No description.* |
+
+---
+
+##### `addChangeInSecretCountAlarm`
+
+```typescript
+public addChangeInSecretCountAlarm(metric: Metric | MathExpression, props: ChangeInSecretCountThreshold, disambiguator?: string): AlarmWithAnnotation
+```
+
+###### `metric`Required
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.Metric | aws-cdk-lib.aws_cloudwatch.MathExpression
+
+---
+
+###### `props`Required
+
+- *Type:* ChangeInSecretCountThreshold
+
+---
+
+###### `disambiguator`Optional
+
+- *Type:* string
+
+---
+
+##### `addMaxSecretCountAlarm`
+
+```typescript
+public addMaxSecretCountAlarm(metric: Metric | MathExpression, props: MaxSecretCountThreshold, disambiguator?: string): AlarmWithAnnotation
+```
+
+###### `metric`Required
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.Metric | aws-cdk-lib.aws_cloudwatch.MathExpression
+
+---
+
+###### `props`Required
+
+- *Type:* MaxSecretCountThreshold
+
+---
+
+###### `disambiguator`Optional
+
+- *Type:* string
+
+---
+
+##### `addMinSecretCountAlarm`
+
+```typescript
+public addMinSecretCountAlarm(metric: Metric | MathExpression, props: MinSecretCountThreshold, disambiguator?: string): AlarmWithAnnotation
+```
+
+###### `metric`Required
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.Metric | aws-cdk-lib.aws_cloudwatch.MathExpression
+
+---
+
+###### `props`Required
+
+- *Type:* MinSecretCountThreshold
+
+---
+
+###### `disambiguator`Optional
+
+- *Type:* string
+
+---
+
+
+
+
+### SecretsManagerMetricFactory
+
+#### Initializers
+
+```typescript
+import { SecretsManagerMetricFactory } from 'cdk-monitoring-constructs'
+
+new SecretsManagerMetricFactory(metricFactory: MetricFactory)
+```
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| metricFactory
| MetricFactory
| *No description.* |
+
+---
+
+##### `metricFactory`Required
+
+- *Type:* MetricFactory
+
+---
+
+#### Methods
+
+| **Name** | **Description** |
+| --- | --- |
+| metricSecretCount
| *No description.* |
+
+---
+
+##### `metricSecretCount`
+
+```typescript
+public metricSecretCount(): Metric | MathExpression
+```
+
+
+
+
+### SecretsManagerMonitoring
+
+#### Initializers
+
+```typescript
+import { SecretsManagerMonitoring } from 'cdk-monitoring-constructs'
+
+new SecretsManagerMonitoring(scope: MonitoringScope, props: SecretsManagerMonitoringProps)
+```
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| scope
| MonitoringScope
| *No description.* |
+| props
| SecretsManagerMonitoringProps
| *No description.* |
+
+---
+
+##### `scope`Required
+
+- *Type:* MonitoringScope
+
+---
+
+##### `props`Required
+
+- *Type:* SecretsManagerMonitoringProps
+
+---
+
+#### Methods
+
+| **Name** | **Description** |
+| --- | --- |
+| addAlarm
| Adds an alarm. |
+| alarmWidgets
| Returns widgets for all alarms. |
+| createAlarmFactory
| Creates a new alarm factory. |
+| createdAlarms
| Returns all the alarms created. |
+| createMetricFactory
| Creates a new metric factory. |
+| createWidgetFactory
| Creates a new widget factory. |
+| summaryWidgets
| Returns widgets to be placed on the summary dashboard. |
+| widgets
| Returns widgets to be placed on the main dashboard. |
+| widgetsForDashboard
| Returns widgets for the requested dashboard type. |
+| createSecretsCountWidget
| *No description.* |
+| createTitleWidget
| *No description.* |
+
+---
+
+##### `addAlarm`
+
+```typescript
+public addAlarm(alarm: AlarmWithAnnotation): void
+```
+
+Adds an alarm.
+
+###### `alarm`Required
+
+- *Type:* AlarmWithAnnotation
+
+alarm to add.
+
+---
+
+##### `alarmWidgets`
+
+```typescript
+public alarmWidgets(): IWidget[]
+```
+
+Returns widgets for all alarms.
+
+These can go to runbook or to service dashboard.
+
+##### `createAlarmFactory`
+
+```typescript
+public createAlarmFactory(alarmNamePrefix: string): AlarmFactory
+```
+
+Creates a new alarm factory.
+
+Alarms created will be named with the given prefix, unless a local name override is present.
+
+###### `alarmNamePrefix`Required
+
+- *Type:* string
+
+alarm name prefix.
+
+---
+
+##### `createdAlarms`
+
+```typescript
+public createdAlarms(): AlarmWithAnnotation[]
+```
+
+Returns all the alarms created.
+
+##### `createMetricFactory`
+
+```typescript
+public createMetricFactory(): MetricFactory
+```
+
+Creates a new metric factory.
+
+##### `createWidgetFactory`
+
+```typescript
+public createWidgetFactory(): IWidgetFactory
+```
+
+Creates a new widget factory.
+
+##### `summaryWidgets`
+
+```typescript
+public summaryWidgets(): IWidget[]
+```
+
+Returns widgets to be placed on the summary dashboard.
+
+##### `widgets`
+
+```typescript
+public widgets(): IWidget[]
+```
+
+Returns widgets to be placed on the main dashboard.
+
+##### `widgetsForDashboard`
+
+```typescript
+public widgetsForDashboard(name: string): IWidget[]
+```
+
+Returns widgets for the requested dashboard type.
+
+###### `name`Required
+
+- *Type:* string
+
+---
+
+##### `createSecretsCountWidget`
+
+```typescript
+public createSecretsCountWidget(width: number, height: number): GraphWidget
+```
+
+###### `width`Required
+
+- *Type:* number
+
+---
+
+###### `height`Required
+
+- *Type:* number
+
+---
+
+##### `createTitleWidget`
+
+```typescript
+public createTitleWidget(): MonitoringHeaderWidget
+```
+
+
+#### Properties
+
+| **Name** | **Type** | **Description** |
+| --- | --- | --- |
+| secretsCountAnnotation
| aws-cdk-lib.aws_cloudwatch.HorizontalAnnotation[]
| *No description.* |
+| secretsCountMetric
| aws-cdk-lib.aws_cloudwatch.Metric \| aws-cdk-lib.aws_cloudwatch.MathExpression
| *No description.* |
+| secretsManagerAlarmFactory
| SecretsManagerAlarmFactory
| *No description.* |
+| title
| string
| *No description.* |
+
+---
+
+##### `secretsCountAnnotation`Required
+
+```typescript
+public readonly secretsCountAnnotation: HorizontalAnnotation[];
+```
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.HorizontalAnnotation[]
+
+---
+
+##### `secretsCountMetric`Required
+
+```typescript
+public readonly secretsCountMetric: Metric | MathExpression;
+```
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.Metric | aws-cdk-lib.aws_cloudwatch.MathExpression
+
+---
+
+##### `secretsManagerAlarmFactory`Required
+
+```typescript
+public readonly secretsManagerAlarmFactory: SecretsManagerAlarmFactory;
+```
+
+- *Type:* SecretsManagerAlarmFactory
+
+---
+
+##### `title`Required
+
+```typescript
+public readonly title: string;
+```
+
+- *Type:* string
+
+---
+
+
### SecretsManagerSecretMetricFactory
#### Initializers
@@ -62087,7 +63651,7 @@ Dashboard placement override props.
### IDashboardSegment
-- *Implemented By:* ApiGatewayMonitoring, ApiGatewayV2HttpApiMonitoring, AppSyncMonitoring, AutoScalingGroupMonitoring, BillingMonitoring, CertificateManagerMonitoring, CloudFrontDistributionMonitoring, CodeBuildProjectMonitoring, CustomMonitoring, DocumentDbMonitoring, DynamoTableGlobalSecondaryIndexMonitoring, DynamoTableMonitoring, EC2Monitoring, Ec2ServiceMonitoring, ElastiCacheClusterMonitoring, FargateServiceMonitoring, GlueJobMonitoring, KinesisDataAnalyticsMonitoring, KinesisDataStreamMonitoring, KinesisFirehoseMonitoring, LambdaFunctionMonitoring, LogMonitoring, Monitoring, NetworkLoadBalancerMonitoring, OpenSearchClusterMonitoring, RdsClusterMonitoring, RedshiftClusterMonitoring, S3BucketMonitoring, SecretsManagerSecretMonitoring, SingleWidgetDashboardSegment, SnsTopicMonitoring, SqsQueueMonitoring, SqsQueueMonitoringWithDlq, StepFunctionActivityMonitoring, StepFunctionLambdaIntegrationMonitoring, StepFunctionMonitoring, StepFunctionServiceIntegrationMonitoring, SyntheticsCanaryMonitoring, WafV2Monitoring, IDashboardSegment
+- *Implemented By:* ApiGatewayMonitoring, ApiGatewayV2HttpApiMonitoring, AppSyncMonitoring, AutoScalingGroupMonitoring, BillingMonitoring, CertificateManagerMonitoring, CloudFrontDistributionMonitoring, CodeBuildProjectMonitoring, CustomMonitoring, DocumentDbMonitoring, DynamoTableGlobalSecondaryIndexMonitoring, DynamoTableMonitoring, EC2Monitoring, Ec2ServiceMonitoring, ElastiCacheClusterMonitoring, FargateServiceMonitoring, GlueJobMonitoring, KinesisDataAnalyticsMonitoring, KinesisDataStreamMonitoring, KinesisFirehoseMonitoring, LambdaFunctionMonitoring, LogMonitoring, Monitoring, NetworkLoadBalancerMonitoring, OpenSearchClusterMonitoring, RdsClusterMonitoring, RedshiftClusterMonitoring, S3BucketMonitoring, SecretsManagerMonitoring, SecretsManagerSecretMonitoring, SingleWidgetDashboardSegment, SnsTopicMonitoring, SqsQueueMonitoring, SqsQueueMonitoringWithDlq, StepFunctionActivityMonitoring, StepFunctionLambdaIntegrationMonitoring, StepFunctionMonitoring, StepFunctionServiceIntegrationMonitoring, SyntheticsCanaryMonitoring, WafV2Monitoring, IDashboardSegment
#### Methods
@@ -62178,7 +63742,7 @@ Gets the dashboard for the requested dashboard type.
### IDynamicDashboardSegment
-- *Implemented By:* ApiGatewayMonitoring, ApiGatewayV2HttpApiMonitoring, AppSyncMonitoring, AutoScalingGroupMonitoring, BillingMonitoring, CertificateManagerMonitoring, CloudFrontDistributionMonitoring, CodeBuildProjectMonitoring, CustomMonitoring, DocumentDbMonitoring, DynamoTableGlobalSecondaryIndexMonitoring, DynamoTableMonitoring, EC2Monitoring, Ec2ServiceMonitoring, ElastiCacheClusterMonitoring, FargateServiceMonitoring, GlueJobMonitoring, KinesisDataAnalyticsMonitoring, KinesisDataStreamMonitoring, KinesisFirehoseMonitoring, LambdaFunctionMonitoring, LogMonitoring, Monitoring, NetworkLoadBalancerMonitoring, OpenSearchClusterMonitoring, RdsClusterMonitoring, RedshiftClusterMonitoring, S3BucketMonitoring, SecretsManagerSecretMonitoring, SingleWidgetDashboardSegment, SnsTopicMonitoring, SqsQueueMonitoring, SqsQueueMonitoringWithDlq, StaticSegmentDynamicAdapter, StepFunctionActivityMonitoring, StepFunctionLambdaIntegrationMonitoring, StepFunctionMonitoring, StepFunctionServiceIntegrationMonitoring, SyntheticsCanaryMonitoring, WafV2Monitoring, IDynamicDashboardSegment
+- *Implemented By:* ApiGatewayMonitoring, ApiGatewayV2HttpApiMonitoring, AppSyncMonitoring, AutoScalingGroupMonitoring, BillingMonitoring, CertificateManagerMonitoring, CloudFrontDistributionMonitoring, CodeBuildProjectMonitoring, CustomMonitoring, DocumentDbMonitoring, DynamoTableGlobalSecondaryIndexMonitoring, DynamoTableMonitoring, EC2Monitoring, Ec2ServiceMonitoring, ElastiCacheClusterMonitoring, FargateServiceMonitoring, GlueJobMonitoring, KinesisDataAnalyticsMonitoring, KinesisDataStreamMonitoring, KinesisFirehoseMonitoring, LambdaFunctionMonitoring, LogMonitoring, Monitoring, NetworkLoadBalancerMonitoring, OpenSearchClusterMonitoring, RdsClusterMonitoring, RedshiftClusterMonitoring, S3BucketMonitoring, SecretsManagerMonitoring, SecretsManagerSecretMonitoring, SingleWidgetDashboardSegment, SnsTopicMonitoring, SqsQueueMonitoring, SqsQueueMonitoringWithDlq, StaticSegmentDynamicAdapter, StepFunctionActivityMonitoring, StepFunctionLambdaIntegrationMonitoring, StepFunctionMonitoring, StepFunctionServiceIntegrationMonitoring, SyntheticsCanaryMonitoring, WafV2Monitoring, IDynamicDashboardSegment
#### Methods
diff --git a/README.md b/README.md
index f3d5f4a2..dde7d0f9 100644
--- a/README.md
+++ b/README.md
@@ -89,7 +89,8 @@ You can browse the documentation at https://constructs.dev/packages/cdk-monitori
| AWS RDS (`.monitorRdsCluster()`) | Query duration, connections, latency, disk/CPU usage | Connections, disk and CPU usage | |
| AWS Redshift (`.monitorRedshiftCluster()`) | Query duration, connections, latency, disk/CPU usage | Query duration, connections, disk and CPU usage | |
| AWS S3 Bucket (`.monitorS3Bucket()`) | Bucket size and number of objects | | |
-| AWS SecretsManager (`.monitorSecretsManagerSecret()`) | Days since last rotation | Days since last change or rotation | |
+| AWS SecretsManager (`.monitorSecretsManager()`) | Max secret count, min secret sount, secret count change | Min/max secret count or change in secret count | |
+| AWS SecretsManager Secret (`.monitorSecretsManagerSecret()`) | Days since last rotation | Days since last change or rotation | |
| AWS SNS Topic (`.monitorSnsTopic()`) | Message count, size, failed notifications | Failed notifications, min/max published messages | |
| AWS SQS Queue (`.monitorSqsQueue()`, `.monitorSqsQueueWithDlq()`) | Message count, age, size | Message count, age, DLQ incoming messages | |
| AWS Step Functions (`.monitorStepFunction()`, `.monitorStepFunctionActivity()`, `monitorStepFunctionLambdaIntegration()`, `.monitorStepFunctionServiceIntegration()`) | Execution count and breakdown per state | Duration, failed, failed rate, aborted, throttled, timed out executions | |
diff --git a/lib/common/monitoring/alarms/SecretsManagerAlarmFactory.ts b/lib/common/monitoring/alarms/SecretsManagerAlarmFactory.ts
new file mode 100644
index 00000000..87990591
--- /dev/null
+++ b/lib/common/monitoring/alarms/SecretsManagerAlarmFactory.ts
@@ -0,0 +1,118 @@
+import {
+ ComparisonOperator,
+ TreatMissingData,
+} from "aws-cdk-lib/aws-cloudwatch";
+
+import { AlarmFactory, CustomAlarmThreshold } from "../../alarm";
+import { MetricWithAlarmSupport } from "../../metric";
+
+const NUMBER_OF_DATAPOINTS = 1;
+
+export interface MinSecretCountThreshold extends CustomAlarmThreshold {
+ readonly minSecretCount: number;
+}
+
+export interface MaxSecretCountThreshold extends CustomAlarmThreshold {
+ readonly maxSecretCount: number;
+}
+
+export interface ChangeInSecretCountThreshold extends CustomAlarmThreshold {
+ readonly requiredSecretCount: number;
+ readonly alarmWhenIncreased: boolean;
+ readonly alarmWhenDecreased: boolean;
+ readonly additionalDescription?: string;
+}
+
+export class SecretsManagerAlarmFactory {
+ protected readonly alarmFactory: AlarmFactory;
+
+ constructor(alarmFactory: AlarmFactory) {
+ this.alarmFactory = alarmFactory;
+ }
+
+ addMinSecretCountAlarm(
+ metric: MetricWithAlarmSupport,
+ props: MinSecretCountThreshold,
+ disambiguator?: string
+ ) {
+ return this.alarmFactory.addAlarm(metric, {
+ treatMissingData:
+ props.treatMissingDataOverride ?? TreatMissingData.MISSING,
+ datapointsToAlarm: props.datapointsToAlarm ?? NUMBER_OF_DATAPOINTS,
+ comparisonOperator:
+ props.comparisonOperatorOverride ??
+ ComparisonOperator.LESS_THAN_THRESHOLD,
+ ...props,
+ disambiguator,
+ threshold: props.minSecretCount,
+ alarmNameSuffix: "Secrets-Count-Min",
+ alarmDescription: "Number of secrets is too low.",
+ });
+ }
+
+ addMaxSecretCountAlarm(
+ metric: MetricWithAlarmSupport,
+ props: MaxSecretCountThreshold,
+ disambiguator?: string
+ ) {
+ return this.alarmFactory.addAlarm(metric, {
+ treatMissingData:
+ props.treatMissingDataOverride ?? TreatMissingData.MISSING,
+ comparisonOperator:
+ props.comparisonOperatorOverride ??
+ ComparisonOperator.GREATER_THAN_THRESHOLD,
+ datapointsToAlarm: props.datapointsToAlarm ?? NUMBER_OF_DATAPOINTS,
+ ...props,
+ disambiguator,
+ threshold: props.maxSecretCount,
+ alarmNameSuffix: "Secrets-Count-Max",
+ alarmDescription: "Number of secrets is too high.",
+ });
+ }
+
+ addChangeInSecretCountAlarm(
+ metric: MetricWithAlarmSupport,
+ props: ChangeInSecretCountThreshold,
+ disambiguator?: string
+ ) {
+ return this.alarmFactory.addAlarm(metric, {
+ ...props,
+ disambiguator,
+ treatMissingData:
+ props.treatMissingDataOverride ?? TreatMissingData.MISSING,
+ threshold: props.requiredSecretCount,
+ comparisonOperator: this.getComparisonOperator(props),
+ datapointsToAlarm: props.datapointsToAlarm ?? NUMBER_OF_DATAPOINTS,
+ alarmNameSuffix: "Secrets-Count-Change",
+ alarmDescription: this.getDefaultDescription(props),
+ });
+ }
+
+ private getDefaultDescription(props: ChangeInSecretCountThreshold) {
+ if (props.alarmWhenIncreased && props.alarmWhenDecreased) {
+ return "Secret count: Secret count has changed.";
+ } else if (props.alarmWhenIncreased) {
+ return "Secret count: Secret count has increased.";
+ } else if (props.alarmWhenDecreased) {
+ return "Secret count: Secret count has decreased.";
+ } else {
+ throw new Error(
+ "You need to alarm when the value has increased, decreased, or both."
+ );
+ }
+ }
+
+ private getComparisonOperator(props: ChangeInSecretCountThreshold) {
+ if (props.alarmWhenIncreased && props.alarmWhenDecreased) {
+ return ComparisonOperator.LESS_THAN_LOWER_OR_GREATER_THAN_UPPER_THRESHOLD;
+ } else if (props.alarmWhenDecreased) {
+ return ComparisonOperator.LESS_THAN_THRESHOLD;
+ } else if (props.alarmWhenIncreased) {
+ return ComparisonOperator.GREATER_THAN_THRESHOLD;
+ } else {
+ throw new Error(
+ "You need to alarm when the value has increased, decreased, or both."
+ );
+ }
+ }
+}
diff --git a/lib/common/monitoring/alarms/index.ts b/lib/common/monitoring/alarms/index.ts
index 2759785f..fb7cc70f 100644
--- a/lib/common/monitoring/alarms/index.ts
+++ b/lib/common/monitoring/alarms/index.ts
@@ -11,6 +11,7 @@ export * from "./LatencyAlarmFactory";
export * from "./LogLevelAlarmFactory";
export * from "./OpenSearchClusterAlarmFactory";
export * from "./QueueAlarmFactory";
+export * from "./SecretsManagerAlarmFactory";
export * from "./TaskHealthAlarmFactory";
export * from "./ThroughputAlarmFactory";
export * from "./TopicAlarmFactory";
diff --git a/lib/facade/MonitoringFacade.ts b/lib/facade/MonitoringFacade.ts
index 98e44a6f..d49b4946 100644
--- a/lib/facade/MonitoringFacade.ts
+++ b/lib/facade/MonitoringFacade.ts
@@ -94,6 +94,8 @@ import {
RedshiftClusterMonitoringProps,
S3BucketMonitoring,
S3BucketMonitoringProps,
+ SecretsManagerMonitoring,
+ SecretsManagerMonitoringProps,
SecretsManagerSecretMonitoring,
SecretsManagerSecretMonitoringProps,
SimpleEc2ServiceMonitoringProps,
@@ -637,6 +639,12 @@ export class MonitoringFacade extends MonitoringScope {
return this;
}
+ monitorSecretsManager(props: SecretsManagerMonitoringProps) {
+ const segment = new SecretsManagerMonitoring(this, props);
+ this.addSegment(segment, props);
+ return this;
+ }
+
monitorSecretsManagerSecret(props: SecretsManagerSecretMonitoringProps) {
const segment = new SecretsManagerSecretMonitoring(this, props);
this.addSegment(segment, props);
diff --git a/lib/monitoring/aws-secretsmanager/SecretsManagerMetricFactory.ts b/lib/monitoring/aws-secretsmanager/SecretsManagerMetricFactory.ts
new file mode 100644
index 00000000..c2dbc73b
--- /dev/null
+++ b/lib/monitoring/aws-secretsmanager/SecretsManagerMetricFactory.ts
@@ -0,0 +1,37 @@
+import { Duration } from "aws-cdk-lib";
+import { MetricFactory, MetricStatistic } from "../../common";
+
+const CLASS = "None";
+const DEFAULT_METRIC_PERIOD = Duration.hours(1);
+const METRICNAMESECRETCOUNT = "ResourceCount";
+const NAMESPACE = "AWS/SecretsManager";
+const RESOURCE = "SecretCount";
+const SERVICE = "Secrets Manager";
+const TYPE = "Resource";
+
+export class SecretsManagerMetricFactory {
+ protected readonly metricFactory: MetricFactory;
+
+ constructor(metricFactory: MetricFactory) {
+ this.metricFactory = metricFactory;
+ }
+
+ metricSecretCount() {
+ const dimensionsMap = {
+ Class: CLASS,
+ Resource: RESOURCE,
+ Service: SERVICE,
+ Type: TYPE,
+ };
+
+ return this.metricFactory.createMetric(
+ METRICNAMESECRETCOUNT,
+ MetricStatistic.AVERAGE,
+ "Count",
+ dimensionsMap,
+ undefined,
+ NAMESPACE,
+ DEFAULT_METRIC_PERIOD
+ );
+ }
+}
diff --git a/lib/monitoring/aws-secretsmanager/SecretsManagerMonitoring.ts b/lib/monitoring/aws-secretsmanager/SecretsManagerMonitoring.ts
new file mode 100644
index 00000000..1801b655
--- /dev/null
+++ b/lib/monitoring/aws-secretsmanager/SecretsManagerMonitoring.ts
@@ -0,0 +1,139 @@
+import {
+ GraphWidget,
+ HorizontalAnnotation,
+ IWidget,
+} from "aws-cdk-lib/aws-cloudwatch";
+import { SecretsManagerMetricFactory } from "./SecretsManagerMetricFactory";
+import {
+ BaseMonitoringProps,
+ ChangeInSecretCountThreshold,
+ CountAxisFromZero,
+ DefaultGraphWidgetHeight,
+ DefaultSummaryWidgetHeight,
+ HalfWidth,
+ MaxSecretCountThreshold,
+ MetricWithAlarmSupport,
+ MinSecretCountThreshold,
+ Monitoring,
+ MonitoringScope,
+ SecretsManagerAlarmFactory,
+ ThirdWidth,
+} from "../../common";
+import {
+ MonitoringHeaderWidget,
+ MonitoringNamingStrategy,
+} from "../../dashboard";
+
+export interface SecretsManagerMonitoringOptions extends BaseMonitoringProps {
+ readonly addMinNumberSecretsAlarm?: Record