Commit 1a26b61
authored
Fix orphan EBS volumes on runner termination (#7930)
**Impact:** AWS cost — eliminates ~1,000 orphaned 150 GiB gp3
volumes/day in us-east-1
**Risk:** low
## What
Before terminating a runner instance, verify that all attached EBS
volumes have `DeleteOnTermination=true` and fix any that don't. This
prevents replacement root volumes (created by
`createReplaceRootVolumeTask` during runner reuse) from persisting after
instance termination.
## Why
The runner reuse flow calls `createReplaceRootVolumeTask` to reset the
root volume from the AMI snapshot. While the old volume is deleted
(`DeleteReplacedRootVolume: true`), the new replacement volume does not
reliably inherit `DeleteOnTermination=true`. When the instance is later
terminated, the replacement volume survives — untagged and unattached.
At the time of discovery: **10,436 orphaned volumes totaling 1.8 TiB**
in us-east-1 alone, growing at ~1,000 volumes/day.
## How
- The fix is **best-effort and non-blocking**:
`ensureDeleteOnTermination` is wrapped in a try/catch that logs a
warning on failure, so termination always proceeds. A subsequent
scale-down run or cleanup script can catch any misses.
- Runs **before every termination**, not just after reuse, because the
cost of the extra `DescribeInstanceAttribute` call is negligible and it
defends against any future code path that might also produce volumes
without the flag.
- IAM permissions are scoped with the existing
`ec2:ResourceTag/Application: github-action-runner` condition, so the
lambda can only modify runner instances.
## Changes
- **`runners.ts`**: Added `ensureDeleteOnTermination(ec2, instanceId,
awsRegion)` — queries `blockDeviceMapping` attribute, filters volumes
where `DeleteOnTermination === false`, and calls
`modifyInstanceAttribute` to fix them. Called at the top of
`terminateRunner` before the terminate API call.
- **`runners.test.ts`**: Added 5 unit tests for
`ensureDeleteOnTermination` (all-good, needs-fix, mixed, empty,
API-error) and 2 integration tests verifying `terminateRunner` calls it
and still terminates on failure.
- **`lambda-scale-down.json`**: Added `ec2:DescribeInstanceAttribute`
and `ec2:ModifyInstanceAttribute` to the IAM policy, under the same
tag-based condition as `ec2:TerminateInstances`.
## Testing
- Unit tests cover all branches: all volumes OK, some need fixing,
mixed, empty response, and API failure.
- Integration tests confirm `terminateRunner` invokes the fix before
termination and still terminates even if the fix fails.
- Run `cd terraform-aws-github-runner/modules/runners/lambdas/runners &&
yarn test` to execute the test suite.
---------
Signed-off-by: Jean Schmidt <contato@jschmidt.me>1 parent 980d560 commit 1a26b61
4 files changed
Lines changed: 217 additions & 2 deletions
File tree
- terraform-aws-github-runner/modules/runners
- lambdas/runners/src/scale-runners
- policies
Lines changed: 64 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
896 | 896 | | |
897 | 897 | | |
898 | 898 | | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
| 916 | + | |
| 917 | + | |
| 918 | + | |
| 919 | + | |
| 920 | + | |
| 921 | + | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
| 927 | + | |
| 928 | + | |
| 929 | + | |
| 930 | + | |
| 931 | + | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
| 948 | + | |
| 949 | + | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
| 961 | + | |
| 962 | + | |
899 | 963 | | |
900 | 964 | | |
901 | 965 | | |
| |||
Lines changed: 95 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
26 | 27 | | |
27 | 28 | | |
28 | 29 | | |
| 30 | + | |
| 31 | + | |
29 | 32 | | |
30 | 33 | | |
31 | 34 | | |
| |||
328 | 331 | | |
329 | 332 | | |
330 | 333 | | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
331 | 403 | | |
332 | 404 | | |
333 | 405 | | |
334 | 406 | | |
| 407 | + | |
| 408 | + | |
335 | 409 | | |
336 | 410 | | |
337 | 411 | | |
| |||
341 | 415 | | |
342 | 416 | | |
343 | 417 | | |
344 | | - | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
345 | 437 | | |
346 | 438 | | |
347 | 439 | | |
348 | 440 | | |
349 | 441 | | |
| 442 | + | |
| 443 | + | |
350 | 444 | | |
351 | 445 | | |
352 | 446 | | |
| |||
Lines changed: 55 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
332 | 332 | | |
333 | 333 | | |
334 | 334 | | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
335 | 388 | | |
336 | 389 | | |
337 | 390 | | |
338 | 391 | | |
| 392 | + | |
| 393 | + | |
339 | 394 | | |
340 | 395 | | |
341 | 396 | | |
| |||
Lines changed: 3 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
30 | 32 | | |
31 | 33 | | |
32 | 34 | | |
| |||
0 commit comments