rds-database-auto-start-preventer 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.jsii CHANGED
@@ -8458,7 +8458,7 @@
8458
8458
  },
8459
8459
  "name": "rds-database-auto-start-preventer",
8460
8460
  "readme": {
8461
- "markdown": "# RDS Database Auto Start Preventer (AWS CDK v2)\n\n[![GitHub](https://img.shields.io/github/license/gammarers-aws-cdk-constructs/rds-database-auto-start-preventer?style=flat-square)](https://github.com/gammarers-aws-cdk-constructs/rds-database-auto-start-preventer/blob/main/LICENSE)\n[![npm](https://img.shields.io/npm/v/rds-database-auto-start-preventer?style=flat-square)](https://www.npmjs.com/package/rds-database-auto-start-preventer)\n[![GitHub Workflow Status (branch)](https://img.shields.io/github/actions/workflow/status/gammarers-aws-cdk-constructs/rds-database-auto-start-preventer/release.yml?branch=main&label=release&style=flat-square)](https://github.com/gammarers-aws-cdk-constructs/rds-database-auto-start-preventer/actions/workflows/release.yml)\n[![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/gammarers-aws-cdk-constructs/rds-database-auto-start-preventer?sort=semver&style=flat-square)](https://github.com/gammarers-aws-cdk-constructs/rds-database-auto-start-preventer/releases)\n\n[![View on Construct Hub](https://constructs.dev/badge?package=rds-database-auto-start-preventer)](https://constructs.dev/packages/rds-database-auto-start-preventer)\n\nCDK stack that stops RDS DB instances and clusters after they are auto-started by AWS (RDS-EVENT-0154 / RDS-EVENT-0153). It uses EventBridge rules and a Durable Lambda to detect auto-start events, optionally filter by tags, stop the resource if it matches, and post a notification to Slack.\n\n## Features\n\n- **EventBridge integration** – Listens for RDS DB Instance (RDS-EVENT-0154) and DB Cluster (RDS-EVENT-0153) auto-start events\n- **Tag-based targeting** – Only stops instances/clusters that match a given tag key and tag values\n- **Durable Lambda** – Uses AWS Lambda Durable Execution for reliable, long-running workflow (polling RDS until stopped)\n- **Slack notifications** – Sends a message to a Slack channel when an auto-started resource is stopped (via token and channel from AWS Secrets Manager)\n- **Optional rule toggle** – EventBridge rules can be enabled or disabled via `enableRule`\n\n## Installation\n\n**npm**\n\n```bash\nnpm install rds-database-auto-start-preventer\n```\n\n**yarn**\n\n```bash\nyarn add rds-database-auto-start-preventer\n```\n\n## Usage\n\nUse the `RDSDatabaseAutoStartPreventer` construct when you want to add auto-start prevention to an existing stack or compose it with other constructs.\n\n```typescript\nimport { Stack } from 'aws-cdk-lib';\nimport { RDSDatabaseAutoStartPreventer } from 'rds-database-auto-start-preventer';\n\nconst stack = new Stack(app, 'MyStack');\n\nnew RDSDatabaseAutoStartPreventer(stack, 'RDSDatabaseAutoStartPreventer', {\n targetResource: {\n tagKey: 'AutoStartPrevent',\n tagValues: ['YES'],\n },\n enableRule: true, // optional, defaults to true\n secrets: {\n slackSecretName: 'my-app/slack',\n },\n});\n```\n\nUse the `RDSDatabaseAutoStartPreventStack` when you want a dedicated stack that only deploys the RDS auto-start prevent resources.\n\n```typescript\nimport { RDSDatabaseAutoStartPreventStack } from 'rds-database-auto-start-preventer';\n\nnew RDSDatabaseAutoStartPreventStack(app, 'RDSDatabaseAutoStartPreventStack', {\n stackName: 'rds-database-auto-start-prevent',\n targetResource: {\n tagKey: 'AutoStartPrevent',\n tagValues: ['YES'],\n },\n enableRule: true, // optional, defaults to true\n secrets: {\n slackSecretName: 'my-app/slack',\n },\n});\n```\n\n### Slack secret (AWS Secrets Manager)\n\nStore a JSON object in AWS Secrets Manager with the Slack Bot Token and channel ID:\n\n| Key | Value |\n|-----|-------|\n| `token` | Slack Bot Token (e.g. `xoxb-...`) |\n| `channel` | Slack channel ID (e.g. `C01234ABCD`) |\n\nExample secret value:\n\n```json\n{\n \"token\": \"xoxb-...\",\n \"channel\": \"C01234ABCD\"\n}\n```\n\n## Options\n\n| Option | Type | Required | Description |\n|--------|------|----------|-------------|\n| `targetResource` | `TargetResource` | Yes | Tag-based criteria for which RDS instances/clusters to protect. |\n| `targetResource.tagKey` | `string` | Yes | Tag key to match (e.g. `AutoStartPrevent`, `Environment`). |\n| `targetResource.tagValues` | `string[]` | Yes | Tag values that indicate the resource should be protected (e.g. `['YES']`, `['production']`). |\n| `enableRule` | `boolean` | No | Whether the EventBridge rules are enabled. Defaults to `true` if omitted. |\n| `secrets` | `Secrets` | Yes | External secrets for notifications. |\n| `secrets.slackSecretName` | `string` | Yes | Name of the Secrets Manager secret containing Slack `token` and `channel`. |\n\n## Requirements\n\n- **Node.js** >= 20.0.0 (for CDK app)\n- **AWS CDK** ^2.232.0\n- **constructs** ^10.5.1\n- **AWS Lambda** runtime Node.js 24 (used by the Durable Lambda; managed by the construct)\n\n## License\n\nThis project is licensed under the Apache-2.0 License.\n"
8461
+ "markdown": "# RDS Database Auto Start Preventer (AWS CDK v2)\n\n[![GitHub](https://img.shields.io/github/license/gammarers-aws-cdk-constructs/rds-database-auto-start-preventer?style=flat-square)](https://github.com/gammarers-aws-cdk-constructs/rds-database-auto-start-preventer/blob/main/LICENSE)\n[![npm](https://img.shields.io/npm/v/rds-database-auto-start-preventer?style=flat-square)](https://www.npmjs.com/package/rds-database-auto-start-preventer)\n[![GitHub Workflow Status (branch)](https://img.shields.io/github/actions/workflow/status/gammarers-aws-cdk-constructs/rds-database-auto-start-preventer/release.yml?branch=main&label=release&style=flat-square)](https://github.com/gammarers-aws-cdk-constructs/rds-database-auto-start-preventer/actions/workflows/release.yml)\n[![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/gammarers-aws-cdk-constructs/rds-database-auto-start-preventer?sort=semver&style=flat-square)](https://github.com/gammarers-aws-cdk-constructs/rds-database-auto-start-preventer/releases)\n\n[![View on Construct Hub](https://constructs.dev/badge?package=rds-database-auto-start-preventer)](https://constructs.dev/packages/rds-database-auto-start-preventer)\n\nCDK construct library that stops RDS DB instances and clusters after they are auto-started by AWS (RDS-EVENT-0154 / RDS-EVENT-0153). It uses EventBridge rules and a Durable Lambda to detect auto-start events, filter resources by tags in the handler, stop matching resources when they are `available`, and post a Slack notification only when this Lambda invoked the stop API successfully.\n\n## Features\n\n- **EventBridge integration** – Listens for RDS DB Instance (RDS-EVENT-0154) and DB Cluster (RDS-EVENT-0153) auto-start events\n- **Handler-side tag filtering** – EventBridge rules match all auto-start events; the Lambda evaluates `TagList` from `rds:DescribeDBInstances` / `rds:DescribeDBClusters` and skips resources that do not match `tagKey` / `tagValues`\n- **Durable Lambda** – Uses AWS Lambda Durable Execution for reliable, long-running workflow (initial wait, status polling, stop, and post-stop polling)\n- **Least-privilege IAM** – Grants RDS describe and stop actions only (no Resource Groups Tagging API)\n- **Slack notifications** – Sends a message when this invocation called `StopDBInstance` / `StopDBCluster` and the resource reached `stopped` (no notification when the resource was already stopped or tags did not match)\n- **Optional rule toggle** – EventBridge rules can be enabled or disabled via `enableRule`\n\n## Installation\n\n**npm**\n\n```bash\nnpm install rds-database-auto-start-preventer\n```\n\n**yarn**\n\n```bash\nyarn add rds-database-auto-start-preventer\n```\n\n## Usage\n\n### How it works\n\n1. EventBridge invokes the Durable Lambda with the RDS auto-start event and tag filter parameters (`tagKey`, `tagValues`).\n2. The handler waits 1 minute, then polls DescribeDB* until the resource leaves transitional statuses.\n3. If the resource tag does not match, the handler exits with no stop action.\n4. If the resource is `available` and tags match, the handler calls StopDB* and polls until `stopped`.\n5. If the resource is already `stopped` (for example, stopped by another process), the handler exits without calling StopDB* and without posting to Slack.\n6. Slack is notified only when StopDB* was invoked by this invocation and the resource reached `stopped`.\n\nTag the RDS instances or clusters you want to protect (for example, `AutoStartPrevent=YES`). Resources without a matching tag are left running.\n\n### Construct\n\nUse `RDSDatabaseAutoStartPreventer` when you want to add auto-start prevention to an existing stack or compose it with other constructs.\n\n```typescript\nimport { Stack } from 'aws-cdk-lib';\nimport { RDSDatabaseAutoStartPreventer } from 'rds-database-auto-start-preventer';\n\nconst stack = new Stack(app, 'MyStack');\n\nnew RDSDatabaseAutoStartPreventer(stack, 'RDSDatabaseAutoStartPreventer', {\n targetResource: {\n tagKey: 'AutoStartPrevent',\n tagValues: ['YES'],\n },\n enableRule: true, // optional, defaults to true\n secrets: {\n slackSecretName: 'my-app/slack',\n },\n});\n```\n\n### Stack\n\nUse `RDSDatabaseAutoStartPreventStack` when you want a dedicated stack that only deploys the RDS auto-start prevent resources.\n\n```typescript\nimport { RDSDatabaseAutoStartPreventStack } from 'rds-database-auto-start-preventer';\n\nnew RDSDatabaseAutoStartPreventStack(app, 'RDSDatabaseAutoStartPreventStack', {\n stackName: 'rds-database-auto-start-prevent',\n targetResource: {\n tagKey: 'AutoStartPrevent',\n tagValues: ['YES'],\n },\n enableRule: true, // optional, defaults to true\n secrets: {\n slackSecretName: 'my-app/slack',\n },\n});\n```\n\n### Slack secret (AWS Secrets Manager)\n\nStore a JSON object in AWS Secrets Manager with the Slack Bot Token and channel ID:\n\n| Key | Value |\n|-----|-------|\n| `token` | Slack Bot Token (e.g. `xoxb-...`) |\n| `channel` | Slack channel ID (e.g. `C01234ABCD`) |\n\nExample secret value:\n\n```json\n{\n \"token\": \"xoxb-...\",\n \"channel\": \"C01234ABCD\"\n}\n```\n\n## Options\n\n| Option | Type | Required | Description |\n|--------|------|----------|-------------|\n| `targetResource` | `TargetResource` | Yes | Tag-based criteria evaluated in the Lambda handler. |\n| `targetResource.tagKey` | `string` | Yes | Tag key to match (e.g. `AutoStartPrevent`, `Environment`). |\n| `targetResource.tagValues` | `string[]` | Yes | Tag values that indicate the resource should be stopped (e.g. `['YES']`, `['production']`). |\n| `enableRule` | `boolean` | No | Whether the EventBridge rules are enabled. Defaults to `true` if omitted. |\n| `secrets` | `Secrets` | Yes | External secrets for notifications. |\n| `secrets.slackSecretName` | `string` | Yes | Name of the Secrets Manager secret containing Slack `token` and `channel`. |\n\n## Requirements\n\n- **Node.js** >= 20.0.0 (for your CDK app)\n- **AWS CDK** ^2.232.0\n- **constructs** ^10.5.1\n- **AWS Lambda** runtime Node.js 24.x with Durable Execution (deployed by the construct)\n\n## License\n\nThis project is licensed under the Apache-2.0 License.\n"
8462
8462
  },
8463
8463
  "repository": {
8464
8464
  "type": "git",
@@ -8476,7 +8476,7 @@
8476
8476
  "base": "aws-cdk-lib.Stack",
8477
8477
  "docs": {
8478
8478
  "stability": "stable",
8479
- "summary": "CDK Stack that deploys the RDS database auto start prevent (EventBridge Rule + Durable Lambda)."
8479
+ "summary": "CDK stack that deploys {@link RDSDatabaseAutoStartPreventer}."
8480
8480
  },
8481
8481
  "fqn": "rds-database-auto-start-preventer.RDSDatabaseAutoStartPreventStack",
8482
8482
  "initializer": {
@@ -8601,18 +8601,20 @@
8601
8601
  "assembly": "rds-database-auto-start-preventer",
8602
8602
  "base": "constructs.Construct",
8603
8603
  "docs": {
8604
+ "remarks": "EventBridge rules match all auto-start events; tag filtering runs in the handler\nusing `TagList` from `rds:DescribeDBInstances` / `rds:DescribeDBClusters`.\nIAM grants RDS describe and stop actions only (no Resource Groups Tagging API).",
8604
8605
  "stability": "stable",
8605
- "summary": "Construct that deploys EventBridge rules and a Durable Lambda to prevent RDS DB instances and clusters from staying running after an auto-start event (RDS-EVENT-0154 / RDS-EVENT-0153)."
8606
+ "summary": "Deploys EventBridge rules and a Durable Lambda to stop matching RDS resources after auto-start events (RDS-EVENT-0154 / RDS-EVENT-0153)."
8606
8607
  },
8607
8608
  "fqn": "rds-database-auto-start-preventer.RDSDatabaseAutoStartPreventer",
8608
8609
  "initializer": {
8609
8610
  "docs": {
8611
+ "remarks": "The Lambda receives `{ event, params }` where `params` carries `tagKey` and `tagValues`\nfrom {@link RDSDatabaseAutoStartPreventerProps.targetResource}.",
8610
8612
  "stability": "stable",
8611
- "summary": "Creates the construct: Lambda (with Params and Secrets), EventBridge rules, and IAM."
8613
+ "summary": "Creates the Durable Lambda, EventBridge rules, and IAM policies."
8612
8614
  },
8613
8615
  "locationInModule": {
8614
8616
  "filename": "src/constructs/rds-database-auto-start-preventer.ts",
8615
- "line": 54
8617
+ "line": 63
8616
8618
  },
8617
8619
  "parameters": [
8618
8620
  {
@@ -8647,7 +8649,7 @@
8647
8649
  "kind": "class",
8648
8650
  "locationInModule": {
8649
8651
  "filename": "src/constructs/rds-database-auto-start-preventer.ts",
8650
- "line": 45
8652
+ "line": 51
8651
8653
  },
8652
8654
  "name": "RDSDatabaseAutoStartPreventer",
8653
8655
  "symbolId": "src/constructs/rds-database-auto-start-preventer:RDSDatabaseAutoStartPreventer"
@@ -8663,7 +8665,7 @@
8663
8665
  "kind": "interface",
8664
8666
  "locationInModule": {
8665
8667
  "filename": "src/constructs/rds-database-auto-start-preventer.ts",
8666
- "line": 32
8668
+ "line": 34
8667
8669
  },
8668
8670
  "name": "RDSDatabaseAutoStartPreventerProps",
8669
8671
  "properties": [
@@ -8676,7 +8678,7 @@
8676
8678
  "immutable": true,
8677
8679
  "locationInModule": {
8678
8680
  "filename": "src/constructs/rds-database-auto-start-preventer.ts",
8679
- "line": 38
8681
+ "line": 40
8680
8682
  },
8681
8683
  "name": "secrets",
8682
8684
  "type": {
@@ -8692,7 +8694,7 @@
8692
8694
  "immutable": true,
8693
8695
  "locationInModule": {
8694
8696
  "filename": "src/constructs/rds-database-auto-start-preventer.ts",
8695
- "line": 34
8697
+ "line": 36
8696
8698
  },
8697
8699
  "name": "targetResource",
8698
8700
  "type": {
@@ -8709,7 +8711,7 @@
8709
8711
  "immutable": true,
8710
8712
  "locationInModule": {
8711
8713
  "filename": "src/constructs/rds-database-auto-start-preventer.ts",
8712
- "line": 36
8714
+ "line": 38
8713
8715
  },
8714
8716
  "name": "enableRule",
8715
8717
  "optional": true,
@@ -8731,7 +8733,7 @@
8731
8733
  "kind": "interface",
8732
8734
  "locationInModule": {
8733
8735
  "filename": "src/constructs/rds-database-auto-start-preventer.ts",
8734
- "line": 24
8736
+ "line": 26
8735
8737
  },
8736
8738
  "name": "Secrets",
8737
8739
  "properties": [
@@ -8744,7 +8746,7 @@
8744
8746
  "immutable": true,
8745
8747
  "locationInModule": {
8746
8748
  "filename": "src/constructs/rds-database-auto-start-preventer.ts",
8747
- "line": 26
8749
+ "line": 28
8748
8750
  },
8749
8751
  "name": "slackSecretName",
8750
8752
  "type": {
@@ -8758,14 +8760,15 @@
8758
8760
  "assembly": "rds-database-auto-start-preventer",
8759
8761
  "datatype": true,
8760
8762
  "docs": {
8763
+ "remarks": "Resources whose tag value for {@link TargetResource.tagKey} is not in\n{@link TargetResource.tagValues} are skipped without calling StopDB*.",
8761
8764
  "stability": "stable",
8762
- "summary": "Tag-based criteria to select which RDS instances or clusters are subject to auto-start prevention."
8765
+ "summary": "Tag-based criteria evaluated in the Lambda handler (not on the EventBridge rule)."
8763
8766
  },
8764
8767
  "fqn": "rds-database-auto-start-preventer.TargetResource",
8765
8768
  "kind": "interface",
8766
8769
  "locationInModule": {
8767
8770
  "filename": "src/constructs/rds-database-auto-start-preventer.ts",
8768
- "line": 14
8771
+ "line": 16
8769
8772
  },
8770
8773
  "name": "TargetResource",
8771
8774
  "properties": [
@@ -8778,7 +8781,7 @@
8778
8781
  "immutable": true,
8779
8782
  "locationInModule": {
8780
8783
  "filename": "src/constructs/rds-database-auto-start-preventer.ts",
8781
- "line": 16
8784
+ "line": 18
8782
8785
  },
8783
8786
  "name": "tagKey",
8784
8787
  "type": {
@@ -8794,7 +8797,7 @@
8794
8797
  "immutable": true,
8795
8798
  "locationInModule": {
8796
8799
  "filename": "src/constructs/rds-database-auto-start-preventer.ts",
8797
- "line": 18
8800
+ "line": 20
8798
8801
  },
8799
8802
  "name": "tagValues",
8800
8803
  "type": {
@@ -8810,6 +8813,6 @@
8810
8813
  "symbolId": "src/constructs/rds-database-auto-start-preventer:TargetResource"
8811
8814
  }
8812
8815
  },
8813
- "version": "0.1.8",
8814
- "fingerprint": "itJ9joCM32nuvL2km0nU/OhJ6g1dO6kWKARoiWRQFmQ="
8816
+ "version": "0.2.0",
8817
+ "fingerprint": "c1Y/5r1LHRhdiZFEZUuD3xo5+txRZlX8LOGSdHkcGZ8="
8815
8818
  }
package/API.md CHANGED
@@ -4,7 +4,11 @@
4
4
 
5
5
  ### RDSDatabaseAutoStartPreventer <a name="RDSDatabaseAutoStartPreventer" id="rds-database-auto-start-preventer.RDSDatabaseAutoStartPreventer"></a>
6
6
 
7
- Construct that deploys EventBridge rules and a Durable Lambda to prevent RDS DB instances and clusters from staying running after an auto-start event (RDS-EVENT-0154 / RDS-EVENT-0153).
7
+ Deploys EventBridge rules and a Durable Lambda to stop matching RDS resources after auto-start events (RDS-EVENT-0154 / RDS-EVENT-0153).
8
+
9
+ EventBridge rules match all auto-start events; tag filtering runs in the handler
10
+ using `TagList` from `rds:DescribeDBInstances` / `rds:DescribeDBClusters`.
11
+ IAM grants RDS describe and stop actions only (no Resource Groups Tagging API).
8
12
 
9
13
  #### Initializers <a name="Initializers" id="rds-database-auto-start-preventer.RDSDatabaseAutoStartPreventer.Initializer"></a>
10
14
 
@@ -147,7 +151,7 @@ The tree node.
147
151
 
148
152
  ### RDSDatabaseAutoStartPreventStack <a name="RDSDatabaseAutoStartPreventStack" id="rds-database-auto-start-preventer.RDSDatabaseAutoStartPreventStack"></a>
149
153
 
150
- CDK Stack that deploys the RDS database auto start prevent (EventBridge Rule + Durable Lambda).
154
+ CDK stack that deploys {@link RDSDatabaseAutoStartPreventer}.
151
155
 
152
156
  #### Initializers <a name="Initializers" id="rds-database-auto-start-preventer.RDSDatabaseAutoStartPreventStack.Initializer"></a>
153
157
 
@@ -1514,7 +1518,10 @@ Name of the Secrets Manager secret containing Slack token and channel.
1514
1518
 
1515
1519
  ### TargetResource <a name="TargetResource" id="rds-database-auto-start-preventer.TargetResource"></a>
1516
1520
 
1517
- Tag-based criteria to select which RDS instances or clusters are subject to auto-start prevention.
1521
+ Tag-based criteria evaluated in the Lambda handler (not on the EventBridge rule).
1522
+
1523
+ Resources whose tag value for {@link TargetResource.tagKey} is not in
1524
+ {@link TargetResource.tagValues} are skipped without calling StopDB*.
1518
1525
 
1519
1526
  #### Initializer <a name="Initializer" id="rds-database-auto-start-preventer.TargetResource.Initializer"></a>
1520
1527
 
package/README.md CHANGED
@@ -7,14 +7,15 @@
7
7
 
8
8
  [![View on Construct Hub](https://constructs.dev/badge?package=rds-database-auto-start-preventer)](https://constructs.dev/packages/rds-database-auto-start-preventer)
9
9
 
10
- CDK stack that stops RDS DB instances and clusters after they are auto-started by AWS (RDS-EVENT-0154 / RDS-EVENT-0153). It uses EventBridge rules and a Durable Lambda to detect auto-start events, optionally filter by tags, stop the resource if it matches, and post a notification to Slack.
10
+ CDK construct library that stops RDS DB instances and clusters after they are auto-started by AWS (RDS-EVENT-0154 / RDS-EVENT-0153). It uses EventBridge rules and a Durable Lambda to detect auto-start events, filter resources by tags in the handler, stop matching resources when they are `available`, and post a Slack notification only when this Lambda invoked the stop API successfully.
11
11
 
12
12
  ## Features
13
13
 
14
14
  - **EventBridge integration** – Listens for RDS DB Instance (RDS-EVENT-0154) and DB Cluster (RDS-EVENT-0153) auto-start events
15
- - **Tag-based targeting** – Only stops instances/clusters that match a given tag key and tag values
16
- - **Durable Lambda** – Uses AWS Lambda Durable Execution for reliable, long-running workflow (polling RDS until stopped)
17
- - **Slack notifications** – Sends a message to a Slack channel when an auto-started resource is stopped (via token and channel from AWS Secrets Manager)
15
+ - **Handler-side tag filtering** – EventBridge rules match all auto-start events; the Lambda evaluates `TagList` from `rds:DescribeDBInstances` / `rds:DescribeDBClusters` and skips resources that do not match `tagKey` / `tagValues`
16
+ - **Durable Lambda** – Uses AWS Lambda Durable Execution for reliable, long-running workflow (initial wait, status polling, stop, and post-stop polling)
17
+ - **Least-privilege IAM** – Grants RDS describe and stop actions only (no Resource Groups Tagging API)
18
+ - **Slack notifications** – Sends a message when this invocation called `StopDBInstance` / `StopDBCluster` and the resource reached `stopped` (no notification when the resource was already stopped or tags did not match)
18
19
  - **Optional rule toggle** – EventBridge rules can be enabled or disabled via `enableRule`
19
20
 
20
21
  ## Installation
@@ -33,7 +34,20 @@ yarn add rds-database-auto-start-preventer
33
34
 
34
35
  ## Usage
35
36
 
36
- Use the `RDSDatabaseAutoStartPreventer` construct when you want to add auto-start prevention to an existing stack or compose it with other constructs.
37
+ ### How it works
38
+
39
+ 1. EventBridge invokes the Durable Lambda with the RDS auto-start event and tag filter parameters (`tagKey`, `tagValues`).
40
+ 2. The handler waits 1 minute, then polls DescribeDB* until the resource leaves transitional statuses.
41
+ 3. If the resource tag does not match, the handler exits with no stop action.
42
+ 4. If the resource is `available` and tags match, the handler calls StopDB* and polls until `stopped`.
43
+ 5. If the resource is already `stopped` (for example, stopped by another process), the handler exits without calling StopDB* and without posting to Slack.
44
+ 6. Slack is notified only when StopDB* was invoked by this invocation and the resource reached `stopped`.
45
+
46
+ Tag the RDS instances or clusters you want to protect (for example, `AutoStartPrevent=YES`). Resources without a matching tag are left running.
47
+
48
+ ### Construct
49
+
50
+ Use `RDSDatabaseAutoStartPreventer` when you want to add auto-start prevention to an existing stack or compose it with other constructs.
37
51
 
38
52
  ```typescript
39
53
  import { Stack } from 'aws-cdk-lib';
@@ -53,7 +67,9 @@ new RDSDatabaseAutoStartPreventer(stack, 'RDSDatabaseAutoStartPreventer', {
53
67
  });
54
68
  ```
55
69
 
56
- Use the `RDSDatabaseAutoStartPreventStack` when you want a dedicated stack that only deploys the RDS auto-start prevent resources.
70
+ ### Stack
71
+
72
+ Use `RDSDatabaseAutoStartPreventStack` when you want a dedicated stack that only deploys the RDS auto-start prevent resources.
57
73
 
58
74
  ```typescript
59
75
  import { RDSDatabaseAutoStartPreventStack } from 'rds-database-auto-start-preventer';
@@ -93,19 +109,19 @@ Example secret value:
93
109
 
94
110
  | Option | Type | Required | Description |
95
111
  |--------|------|----------|-------------|
96
- | `targetResource` | `TargetResource` | Yes | Tag-based criteria for which RDS instances/clusters to protect. |
112
+ | `targetResource` | `TargetResource` | Yes | Tag-based criteria evaluated in the Lambda handler. |
97
113
  | `targetResource.tagKey` | `string` | Yes | Tag key to match (e.g. `AutoStartPrevent`, `Environment`). |
98
- | `targetResource.tagValues` | `string[]` | Yes | Tag values that indicate the resource should be protected (e.g. `['YES']`, `['production']`). |
114
+ | `targetResource.tagValues` | `string[]` | Yes | Tag values that indicate the resource should be stopped (e.g. `['YES']`, `['production']`). |
99
115
  | `enableRule` | `boolean` | No | Whether the EventBridge rules are enabled. Defaults to `true` if omitted. |
100
116
  | `secrets` | `Secrets` | Yes | External secrets for notifications. |
101
117
  | `secrets.slackSecretName` | `string` | Yes | Name of the Secrets Manager secret containing Slack `token` and `channel`. |
102
118
 
103
119
  ## Requirements
104
120
 
105
- - **Node.js** >= 20.0.0 (for CDK app)
121
+ - **Node.js** >= 20.0.0 (for your CDK app)
106
122
  - **AWS CDK** ^2.232.0
107
123
  - **constructs** ^10.5.1
108
- - **AWS Lambda** runtime Node.js 24 (used by the Durable Lambda; managed by the construct)
124
+ - **AWS Lambda** runtime Node.js 24.x with Durable Execution (deployed by the construct)
109
125
 
110
126
  ## License
111
127
 
@@ -24141,6 +24141,7 @@ var handler = withDurableExecution(
24141
24141
  status: firstDescribe.status
24142
24142
  };
24143
24143
  }
24144
+ let didStop = false;
24144
24145
  let finalStatus = firstDescribe.status;
24145
24146
  if (firstDescribe.status === "available") {
24146
24147
  if (isInstance) {
@@ -24201,8 +24202,19 @@ var handler = withDurableExecution(
24201
24202
  }
24202
24203
  }
24203
24204
  );
24205
+ didStop = true;
24204
24206
  finalStatus = stopped.status;
24205
24207
  }
24208
+ if (!didStop) {
24209
+ if (finalStatus === "stopped") {
24210
+ return {
24211
+ action: "no-op",
24212
+ reason: "already stopped",
24213
+ status: finalStatus
24214
+ };
24215
+ }
24216
+ throw new Error(`DB status is not stopped after processing: ${finalStatus}`);
24217
+ }
24206
24218
  if (finalStatus !== "stopped") {
24207
24219
  throw new Error(`DB status is not stopped after processing: ${finalStatus}`);
24208
24220
  }