Skip to content

feat(runners): warm pool support for Windows runners - #5500

Open
Brend-Smits wants to merge 2 commits into
feat/warm-pool-09-v2-boot-modesfrom
feat/warm-pool-10-windows
Open

Brend-Smits wants to merge 2 commits into
feat/warm-pool-09-v2-boot-modesfrom
feat/warm-pool-10-windows

Conversation

@Brend-Smits

@Brend-Smits Brend-Smits commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Warm pool stack (review in order; each PR is based on the previous one):

  1. feat(compute-providers): add EC2 standby primitives for warm pools #5491 feat(compute-providers): add EC2 standby primitives for warm pools
  2. feat(pool): keep a warm pool of stopped instances #5492 feat(pool): keep a warm pool of stopped instances
  3. feat(scale-up): start warm instances before launching cold runners #5493 feat(scale-up): start warm instances before launching cold runners
  4. feat(scale-down): sweep stopped warm instances #5494 feat(scale-down): sweep stopped warm instances
  5. feat(runners): boot modes for warm pool instances #5495 feat(runners): boot modes for warm pool instances
  6. feat(runners): add warm_pool option to the root module #5496 feat(runners): add warm_pool option to the root module
  7. feat(multi-runner): support warm_pool in runner configs #5497 feat(multi-runner): support warm_pool in runner configs
  8. docs(warm-pool): add warm pool guide, ADR and examples #5498 docs(warm-pool): add warm pool guide, ADR and examples
  9. fix(compute-providers): add warm pool boot modes to the EC2 template #5499 fix(compute-providers): add warm pool boot modes to the EC2 template
  10. feat(runners): warm pool support for Windows runners #5500 feat(runners): warm pool support for Windows runners (this PR)
  11. fix(scale-down): do not sweep warm instances that are being activated #5501 fix(scale-down): do not sweep warm instances that are being activated

Description

Windows runners get the same RUN, PRIME and WAIT boot modes as Linux.

  • EC2Launch runs user data only on the first boot, so a priming instance copies the start logic between the ghr:start-runner markers out of its user data (read from instance metadata) to C:\ProgramData\ghr\start-runner.ps1 and registers a ghr-start-runner scheduled task that runs it as SYSTEM at startup.
  • The priming shutdown is delayed by 60 seconds so EC2Launch records the user data as completed and does not run it again.
  • An activated instance disables the task, so later reboots do not rerun the start logic, and logs the time from activation to runner start.
  • Both Terraform stacks now accept warm pools for linux and windows runners and still reject osx. Docs and the ADR are updated.

Test Plan

  • New pwsh harness modules/runners/templates/tests/start-runner.test.ps1 (37 checks: RUN, WAIT, PRIME, activated boot from the startup task, missing markers, and a check that both template copies match).
  • terraform test for the warm pool tests in modules/runners and modules/compute-providers/aws/ec2 (Windows plans, macOS is rejected), modules/multi-runner and modules/runner-config.
  • Sandbox deployment of examples/multi-runner with warm mode on the Windows Server 2022 config: the instance primed and stopped itself about 10 minutes after launch; a job later activated it, the startup task ran it in RUN mode, and the job started 95 s after dispatch (activation to runner start 64 s) instead of a full Windows cold boot.
  • Same round: the existing Amazon Linux arm64, Ubuntu 24.04 and Ubuntu 22.04 (custom user data template) example configs primed and served jobs from their warm instance in 46-63 s; the x64 config with instance metadata tags disabled is rejected by validation. The v2 example configs (including Windows) plan with warm mode.

Related Issues

Supersedes #5204.

@github-actions

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Boot-hook installation failures can currently be ignored, allowing unusable Windows instances to enter the warm pool.

Review effort: Balanced
Findings: 2 Medium severity

Open (2)
What changed in this PR

Adds Windows runner support to the existing EC2 warm-pool lifecycle.

Changes:

  • Adds Windows RUN, PRIME, and WAIT boot modes using a startup scheduled task.
  • Allows Windows warm pools while continuing to reject macOS.
  • Adds PowerShell tests and updates documentation.
File Description
variables.tf Documents Windows support.
README.md Updates root module documentation.
modules/​runners/​warm-pool.tf Allows Windows runners.
modules/​runners/​variables.tf Updates warm-pool description.
modules/​runners/​tests/​warm-pool.tftest.hcl Tests Windows and macOS validation.
modules/​runners/​templates/​tests/​start-runner.test.ps1 Tests Windows boot modes.
modules/​runners/​templates/​start-runner.ps1 Implements the Windows boot hook.
modules/​runners/​README.md Documents Windows support.
modules/​runner-config/​variables.orchestration-provider.tf Updates provider documentation.
modules/​runner-config/​README.md Regenerates provider documentation.
modules/​multi-runner/​variables.tf Updates multi-runner documentation.
modules/​multi-runner/​README.md Regenerates multi-runner documentation.
modules/​compute-providers/​aws/​ec2/​validations.tf Allows Windows warm pools.
modules/​compute-providers/​aws/​ec2/​tests/​warm-pool.tftest.hcl Tests provider validation.
modules/​compute-providers/​aws/​ec2/​templates/​start-runner.ps1 Adds the v2 Windows boot hook.
docs/​warm-pool.md Documents Windows behavior.
docs/​configuration.md Explains Windows scheduled-task boot hooks.
docs/​adr/​0004-warm-pool-standby.md Records expanded OS support.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread modules/compute-providers/aws/ec2/templates/start-runner.ps1 Outdated
Comment thread modules/runners/templates/start-runner.ps1 Outdated
@Brend-Smits
Brend-Smits force-pushed the feat/warm-pool-09-v2-boot-modes branch from 2826d9a to e96c4d8 Compare October 1, 2026 12:27
@Brend-Smits
Brend-Smits force-pushed the feat/warm-pool-10-windows branch from 49c44f1 to 4f938c4 Compare October 1, 2026 12:27
@Brend-Smits
Brend-Smits force-pushed the feat/warm-pool-09-v2-boot-modes branch from e96c4d8 to 1b09c78 Compare October 1, 2026 12:34
@Brend-Smits
Brend-Smits force-pushed the feat/warm-pool-10-windows branch from 4f938c4 to 07f4766 Compare October 1, 2026 12:34
@Brend-Smits
Brend-Smits force-pushed the feat/warm-pool-09-v2-boot-modes branch from 1b09c78 to e4e05cb Compare October 1, 2026 12:35
@Brend-Smits
Brend-Smits force-pushed the feat/warm-pool-10-windows branch 2 times, most recently from 8213258 to c78bdee Compare October 1, 2026 13:43
@Brend-Smits
Brend-Smits force-pushed the feat/warm-pool-09-v2-boot-modes branch from e4e05cb to 6ff50e8 Compare October 1, 2026 13:43
@Brend-Smits
Brend-Smits marked this pull request as ready for review October 1, 2026 13:59
@Brend-Smits
Brend-Smits requested review from a team as code owners October 1, 2026 13:59
Windows runners get the same RUN, PRIME and WAIT boot modes as Linux.
EC2Launch runs user data only on the first boot, so a priming
instance copies the start logic between the start-runner markers out
of its user data (read from instance metadata) and registers a
`ghr-start-runner` scheduled task that runs it as SYSTEM at startup.
The priming shutdown is delayed by 60 seconds so EC2Launch records
the user data as completed and does not run it again. An activated
instance disables the task, so later reboots do not rerun the start
logic, and logs the time from activation to runner start.

Both Terraform stacks now accept warm pools for linux and windows
runners and still reject macOS. Adds a pwsh harness for the Windows
boot modes that also checks both template copies stay identical.

Signed-off-by: Brend Smits <brend.smits@philips.com>
User data runs with ErrorActionPreference Continue, so a failure to
write the hook script or register the startup task was ignored and the
instance parked without a working hook. Hook persistence and task
registration now stop on errors, and priming only shuts down once the
task exists. Otherwise the instance keeps running and the pool evicts
it as stuck priming.

Signed-off-by: Brend Smits <brend.smits@philips.com>
@Brend-Smits
Brend-Smits force-pushed the feat/warm-pool-10-windows branch from c78bdee to 52b02df Compare October 1, 2026 14:26
@Brend-Smits
Brend-Smits force-pushed the feat/warm-pool-09-v2-boot-modes branch from 6ff50e8 to 0d16875 Compare October 1, 2026 14:27

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants