ec2-instance-running-scheduler 0.4.6 → 0.5.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/.editorconfig +12 -0
- package/.jsii +561 -117
- package/API.md +613 -54
- package/README.md +46 -64
- package/assets/funcs/running-scheduler.lambda/index.js +668 -335
- package/assets/funcs/running-scheduler.lambda/index.js.map +4 -4
- package/lib/constructs/ec2-instance-running-scheduler.d.ts +5 -4
- package/lib/constructs/ec2-instance-running-scheduler.js +8 -4
- package/lib/constructs/lambda-failure-detector/lambda-failure-detection.d.ts +26 -0
- package/lib/constructs/lambda-failure-detector/lambda-failure-detection.js +9 -0
- package/lib/constructs/lambda-failure-detector/lambda-failure-detector.d.ts +99 -0
- package/lib/constructs/lambda-failure-detector/lambda-failure-detector.js +172 -0
- package/lib/constructs/lambda-failure-detector/log-failure-filter.d.ts +22 -0
- package/lib/constructs/lambda-failure-detector/log-failure-filter.js +3 -0
- package/lib/constructs/running-scheduler-failure-detection.d.ts +21 -36
- package/lib/constructs/running-scheduler-failure-detection.js +54 -132
- package/lib/funcs/running-scheduler-wait-env.js +5 -5
- package/lib/funcs/running-scheduler.lambda.js +4 -3
- package/lib/index.d.ts +2 -1
- package/lib/index.js +3 -2
- package/lib/stacks/ec2-instance-running-schedule-stack.d.ts +3 -3
- package/lib/stacks/ec2-instance-running-schedule-stack.js +3 -3
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -1,46 +1,59 @@
|
|
|
1
|
-
# EC2 Instance Running Scheduler (
|
|
1
|
+
# EC2 Instance Running Scheduler (CDK v2)
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/ec2-instance-running-scheduler)
|
|
4
|
+
[](https://www.npmjs.com/package/ec2-instance-running-scheduler)
|
|
5
|
+
[](https://www.npmjs.com/package/ec2-instance-running-scheduler)
|
|
6
|
+
[](https://github.com/gammarers-aws-cdk-constructs/ec2-instance-running-scheduler/actions/workflows/build.yml)
|
|
7
7
|
|
|
8
8
|
[](https://constructs.dev/packages/ec2-instance-running-scheduler)
|
|
9
9
|
|
|
10
|
-
AWS CDK construct library that starts and stops EC2 instances on a cron schedule using
|
|
10
|
+
AWS CDK construct library that starts and stops EC2 instances on a cron schedule using EventBridge Scheduler and a Durable Execution Lambda. Tagged instances are discovered account-wide, started or stopped in parallel, waited until stable, and reported to Slack via Secrets Manager.
|
|
11
11
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
14
|
- **Tag-based targeting** – Select EC2 instances by tag key and values (e.g. `Schedule` / `YES`) via `tag:GetResources`.
|
|
15
15
|
- **EventBridge Scheduler** – Separate cron rules for start and stop, with per-rule timezone (`aws-cdk-lib` `TimeZone`).
|
|
16
16
|
- **Durable Lambda** – One Lambda with AWS Lambda Durable Execution (`step`, `wait`, `map`, child contexts per instance) for long-running workflows without Step Functions.
|
|
17
|
-
- **Stable-state waiting** – After start/stop,
|
|
18
|
-
- **Configurable
|
|
19
|
-
- **
|
|
20
|
-
- **
|
|
21
|
-
- **Validated environment variables** – The bundled handler parses env vars with **strict-env-resolver** (`StrictEnvResolver`). `SLACK_SECRET_NAME` is required; wait limits and `maxConcurrency` must be **positive integers** (`>= 1`).
|
|
22
|
-
- **Slack notifications** – Parent message plus threaded updates per instance; credentials from Secrets Manager JSON (`token`, `channel`). The construct sets **`SLACK_SECRET_NAME`** on the function.
|
|
23
|
-
- **Structured logging** – Durable execution **`ctx.logger`** for traceable JSON application logs (invocation, describe/start/stop/wait loops, wait limit errors, Slack steps, completion).
|
|
24
|
-
- **Optional failure detection** – CloudWatch alarms and log-based metrics for Lambda errors, instance wait failures (`ResourceWaitFailed`), Slack post failures, and other handler `ERROR` logs. Optional SNS notifications via a caller-supplied topic (`failureDetection.alarmTopic`).
|
|
17
|
+
- **Stable-state waiting** – After start/stop, waits and re-describes until `running` or `stopped`, with configurable wait limits (`resourceWait`).
|
|
18
|
+
- **Configurable Lambda runtime** – Memory, invoke timeout, and bounded concurrency via `runtime`; Durable timeout and retention via `durable`.
|
|
19
|
+
- **Slack notifications** – Parent message plus threaded updates per instance; credentials from Secrets Manager JSON (`token`, `channel`).
|
|
20
|
+
- **Optional failure detection** – Opt-in CloudWatch alarms via `failureDetection` (`enabled` / optional `alarmTopic`). Uses `LambdaFailureDetector` for platform Lambda `Errors` plus scheduler-specific log filters (`ResourceWaitFailed`, Slack post failures, other handler `ERROR` logs). The construct never creates an SNS topic.
|
|
25
21
|
- **Scheduling toggle** – Enable or disable both schedules without removing the stack (`enableScheduling`).
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
|
|
23
|
+
## How it works
|
|
24
|
+
|
|
25
|
+
1. Tag EC2 instances in the same account and region with the `targetResource` tag key and one of the tag values **before** enabling schedules.
|
|
26
|
+
2. EventBridge Scheduler invokes the Lambda alias on the start/stop cron with `Params.TagKey`, `Params.TagValues`, and `Params.Mode` (`Start` or `Stop`).
|
|
27
|
+
3. The Durable handler discovers matching instances via the Resource Groups Tagging API, then starts or stops them in parallel (bounded by `runtime.maxConcurrency`).
|
|
28
|
+
4. For each instance it waits (`resourceWait`) until the desired stable state, or fails with a `ResourceWaitFailed:*` error.
|
|
29
|
+
5. Slack receives a summary and per-instance thread updates when the secret is configured.
|
|
30
|
+
6. When `failureDetection.enabled` is `true`, CloudWatch alarms cover Lambda platform errors and the scheduler log filters above. Pass `failureDetection.alarmTopic` to attach SNS actions to an existing topic.
|
|
31
|
+
|
|
32
|
+
**Tag an instance (AWS CLI)**
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
aws ec2 create-tags \
|
|
36
|
+
--resources i-0123456789abcdef0 \
|
|
37
|
+
--tags Key=Schedule,Value=YES
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Start/stop IAM is limited to instance ARNs in the stack account and region whose `aws:ResourceTag/<tagKey>` matches `tagValues`. `tag:GetResources` and `ec2:DescribeInstances` still use `Resource: *` because those APIs do not support resource-level permissions or resource-tag conditions.
|
|
28
41
|
|
|
29
42
|
## Installation
|
|
30
43
|
|
|
31
|
-
|
|
44
|
+
### npm
|
|
32
45
|
|
|
33
46
|
```bash
|
|
34
47
|
npm install ec2-instance-running-scheduler
|
|
35
48
|
```
|
|
36
49
|
|
|
37
|
-
|
|
50
|
+
### yarn
|
|
38
51
|
|
|
39
52
|
```bash
|
|
40
53
|
yarn add ec2-instance-running-scheduler
|
|
41
54
|
```
|
|
42
55
|
|
|
43
|
-
|
|
56
|
+
### pnpm
|
|
44
57
|
|
|
45
58
|
```bash
|
|
46
59
|
pnpm add ec2-instance-running-scheduler
|
|
@@ -108,7 +121,7 @@ new EC2InstanceRunningScheduler(stack, 'EC2InstanceRunningScheduler', {
|
|
|
108
121
|
});
|
|
109
122
|
```
|
|
110
123
|
|
|
111
|
-
Use the **stack** `EC2InstanceRunningScheduleStack` when deploying the scheduler as its own stack. It accepts the same
|
|
124
|
+
Use the **stack** `EC2InstanceRunningScheduleStack` when deploying the scheduler as its own stack. It accepts the same targeting, schedules, secrets, enable flag, and failure detection as the construct (plus standard `StackProps`). For `resourceWait`, `runtime`, `durable`, and `logGroup`, use the construct directly.
|
|
112
125
|
|
|
113
126
|
```typescript
|
|
114
127
|
import * as cdk from 'aws-cdk-lib';
|
|
@@ -152,39 +165,6 @@ new EC2InstanceRunningScheduleStack(app, 'EC2InstanceRunningScheduleStack', {
|
|
|
152
165
|
});
|
|
153
166
|
```
|
|
154
167
|
|
|
155
|
-
## Tag instances before scheduling
|
|
156
|
-
|
|
157
|
-
The scheduler only starts and stops EC2 instances that **already** have the tag key and one of the tag values in `targetResource`. Tag instances in the same account and region as the stack **before** enabling schedules.
|
|
158
|
-
|
|
159
|
-
**AWS CLI**
|
|
160
|
-
|
|
161
|
-
```bash
|
|
162
|
-
aws ec2 create-tags \
|
|
163
|
-
--resources i-0123456789abcdef0 \
|
|
164
|
-
--tags Key=Schedule,Value=YES
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
**Console** – EC2 → Instances → select the instance → Tags → Add `Schedule` = `YES` (or your `tagKey` / `tagValues`).
|
|
168
|
-
|
|
169
|
-
IAM for `ec2:StartInstances` and `ec2:StopInstances` is limited to:
|
|
170
|
-
|
|
171
|
-
- instance ARNs in the stack **account** and **region** (`arn:...:ec2:<region>:<account>:instance/*`)
|
|
172
|
-
- instances whose `aws:ResourceTag/<tagKey>` matches one of `tagValues`
|
|
173
|
-
|
|
174
|
-
An instance without the tag is not discovered by `tag:GetResources`, and start/stop is denied even if an instance ID is known. `tag:GetResources` and `ec2:DescribeInstances` still use `Resource: *` because those APIs do not support resource-level permissions or resource-tag conditions.
|
|
175
|
-
|
|
176
|
-
EventBridge Scheduler invokes the Lambda with `Params.TagKey`, `Params.TagValues`, and `Params.Mode` (`Start` or `Stop`); the construct wires this for you. The function environment includes:
|
|
177
|
-
|
|
178
|
-
| Variable | Source | Purpose |
|
|
179
|
-
|----------|--------|---------|
|
|
180
|
-
| `SLACK_SECRET_NAME` | `secrets.slackSecretName` | Secrets Manager secret for Slack (required) |
|
|
181
|
-
| `PROCESS_RESOURCE_MAX_LOOP_COUNT` | `resourceWait.maxLoopCount` (default `90`) | Max describe/wait iterations per instance |
|
|
182
|
-
| `PROCESS_RESOURCE_MAX_ELAPSED_SECONDS` | `resourceWait.maxElapsedSeconds` (default `1800`) | Max wall-clock seconds waiting for one instance |
|
|
183
|
-
| `PROCESS_RESOURCE_STATUS_CHANGE_WAIT_SECONDS` | `resourceWait.statusChangeWaitSeconds` (default `20`) | Seconds between describe/wait iterations |
|
|
184
|
-
| `PROCESS_RESOURCES_MAX_CONCURRENCY` | `runtime.maxConcurrency` (default `10`) | Max instances processed in parallel |
|
|
185
|
-
|
|
186
|
-
When you set wait limits via `resourceWait` or concurrency via `runtime.maxConcurrency`, the construct writes them as decimal integer strings. At invocation the handler parses them with **strict-env-resolver**; each value must be a **positive integer** (`>= 1`). Missing `SLACK_SECRET_NAME` or invalid env values cause `StrictEnvValidationError` at the start of an invocation.
|
|
187
|
-
|
|
188
168
|
## Options
|
|
189
169
|
|
|
190
170
|
### EC2InstanceRunningScheduler
|
|
@@ -200,7 +180,7 @@ When you set wait limits via `resourceWait` or concurrency via `runtime.maxConcu
|
|
|
200
180
|
| `runtime` | `RunningSchedulerRuntimeProps` | No | Lambda memory, invoke timeout, and map concurrency. |
|
|
201
181
|
| `durable` | `RunningSchedulerDurableProps` | No | Durable execution timeout and history retention. |
|
|
202
182
|
| `logGroup` | `RunningSchedulerLogGroupProps` | No | Function log group retention and removal policy. |
|
|
203
|
-
| `failureDetection` | `
|
|
183
|
+
| `failureDetection` | `RunningSchedulerFailureDetectionProps` | No | Optional CloudWatch alarms and log-based metrics (see below). |
|
|
204
184
|
|
|
205
185
|
### EC2InstanceRunningScheduleStack
|
|
206
186
|
|
|
@@ -211,8 +191,6 @@ Includes `targetResource`, `secrets`, `startSchedule`, `stopSchedule`, `enableSc
|
|
|
211
191
|
- `tagKey` – Tag key used to select instances (e.g. `Schedule`). Required on each target instance before schedules run.
|
|
212
192
|
- `tagValues` – Tag values that must match (e.g. `['YES']`). At least one value is required.
|
|
213
193
|
|
|
214
|
-
See [Tag instances before scheduling](#tag-instances-before-scheduling).
|
|
215
|
-
|
|
216
194
|
### Schedule
|
|
217
195
|
|
|
218
196
|
- `timezone` – `TimeZone` from `aws-cdk-lib` (e.g. `TimeZone.ASIA_TOKYO`, `TimeZone.ETC_UTC`).
|
|
@@ -252,30 +230,34 @@ Lambda invoke settings. Written `maxConcurrency` to `PROCESS_RESOURCES_MAX_CONCU
|
|
|
252
230
|
- `retention` – CloudWatch Logs retention (default: **`RetentionDays.THREE_MONTHS`**).
|
|
253
231
|
- `removalPolicy` – Log group removal policy (default: **`RemovalPolicy.DESTROY`**).
|
|
254
232
|
|
|
255
|
-
###
|
|
233
|
+
### RunningSchedulerFailureDetectionProps
|
|
256
234
|
|
|
257
|
-
|
|
235
|
+
Extends `LambdaFailureDetection` (`enabled` / `alarmTopic`). Alarms are created only when `enabled` is `true`. Internally uses `LambdaFailureDetector` with scheduler-specific log filters. The construct does **not** create an SNS topic.
|
|
258
236
|
|
|
259
237
|
- `enabled` – When `true`, creates four CloudWatch alarms and three log metric filters (default: disabled when omitted).
|
|
260
|
-
- `alarmTopic` – Optional `sns.ITopic` for alarm actions.
|
|
238
|
+
- `alarmTopic` – Optional `sns.ITopic` for alarm actions. When omitted, alarms are created without SNS actions.
|
|
261
239
|
|
|
262
|
-
When enabled
|
|
240
|
+
When enabled:
|
|
263
241
|
|
|
264
242
|
| Alarm | Trigger |
|
|
265
243
|
|-------|---------|
|
|
266
|
-
| Lambda errors | `AWS/Lambda` `Errors` metric |
|
|
244
|
+
| Lambda errors | `AWS/Lambda` `Errors` metric (platform) |
|
|
267
245
|
| Instance status failure | Log filter: `ResourceWaitFailed` |
|
|
268
246
|
| Slack post failure | Log filter: `running-scheduler: Slack post failed` |
|
|
269
247
|
| Durable execution failure | Other handler `ERROR` logs (excluding the above) |
|
|
270
248
|
|
|
271
|
-
Custom metrics
|
|
249
|
+
Custom metrics use the `EC2InstanceRunningScheduler` namespace. Access created alarms via `EC2InstanceRunningScheduler.failureDetection` when enabled.
|
|
250
|
+
|
|
251
|
+
## API
|
|
252
|
+
|
|
253
|
+
See [API.md](./API.md).
|
|
272
254
|
|
|
273
255
|
## Requirements
|
|
274
256
|
|
|
275
257
|
- **Node.js** ≥ 20.0.0 (for developing or synthesizing CDK apps that depend on this package).
|
|
276
258
|
- **aws-cdk-lib** ^2.232.0 and **constructs** ^10.5.1 (peer dependencies).
|
|
277
|
-
- **AWS** – EventBridge Scheduler; Lambda with
|
|
259
|
+
- **AWS** – EventBridge Scheduler; Lambda with Durable Execution (Node.js **24.x** runtime in the construct); Parameters and Secrets Lambda Extension; EC2 (`DescribeInstances`, `StartInstances`, `StopInstances`); Resource Groups Tagging API (`tag:GetResources`); Secrets Manager.
|
|
278
260
|
|
|
279
261
|
## License
|
|
280
262
|
|
|
281
|
-
This project is licensed under the Apache-2.0 License.
|
|
263
|
+
This project is licensed under the (Apache-2.0) License.
|