Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a25b2b2
docs: add ADR-001 warm pool with stop/hibernate for idle runners
Brend-Smits Jul 9, 2026
c617a86
feat(warm-pool): add Terraform foundation - DynamoDB table, variables…
Brend-Smits Jul 9, 2026
996abcc
feat(warm-pool): add DynamoDB client and EC2 stop/start functions
Brend-Smits Jul 9, 2026
cd63be5
feat(warm-pool): implement scale-down stop logic and warm pool eviction
Brend-Smits Jul 9, 2026
2a79683
feat(warm-pool): implement scale-up warm instance restart
Brend-Smits Jul 9, 2026
f411c77
feat(warm-pool): implement pool lambda warm strategy
Brend-Smits Jul 9, 2026
423e4e6
test(warm-pool): add unit tests for findAndStartWarmRunners
Brend-Smits Jul 9, 2026
aa61edb
test(warm-pool): add scale-down eviction and pool warm strategy tests
Brend-Smits Jul 9, 2026
80a8eba
feat(warm-pool): add AMI staleness eviction and DynamoDB dependency
Brend-Smits Jul 9, 2026
36085c0
test(pool): fix existing pool tests for warm pool imports
Brend-Smits Jul 9, 2026
7057b29
test(warm-pool): add Terraform tests for warm pool infrastructure
Brend-Smits Jul 9, 2026
fc97a6b
feat(warm-pool): add WarmPoolStartLatency and WarmPoolEvicted metrics
Brend-Smits Jul 9, 2026
cf2dc4a
feat(warm-pool): implement pool lambda warm strategy grace period
Brend-Smits Jul 9, 2026
de6799f
docs: auto update terraform docs
github-actions[bot] Jul 9, 2026
bb6f8c7
docs: add warm pool to mkdocs navigation
Brend-Smits Jul 9, 2026
f535ed5
fix(warm-pool): address PR review feedback
Brend-Smits Jul 9, 2026
7d91870
fix(warm-pool): remove cross-variable validation for TF 1.3 compat
Brend-Smits Jul 9, 2026
6c3e235
style: fix prettier and terraform formatting
Brend-Smits Jul 9, 2026
3b3be59
fix: replace no-explicit-any with RunnerList type in warm pool tests
Brend-Smits Jul 9, 2026
3cbd134
Merge remote-tracking branch 'origin/main' into feature/warm-pool-hib…
invalid-email-address Aug 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ Join our discord community via [this invite link](https://discord.gg/bxgXW8jJGh)
| <a name="input_logging_kms_key_id"></a> [logging\_kms\_key\_id](#input\_logging\_kms\_key\_id) | Specifies the kms key id to encrypt the logs with. | `string` | `null` | no |
| <a name="input_logging_retention_in_days"></a> [logging\_retention\_in\_days](#input\_logging\_retention\_in\_days) | Specifies the number of days you want to retain log events for the lambda log group. Possible values are: 0, 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653. | `number` | `180` | no |
| <a name="input_matcher_config_parameter_store_tier"></a> [matcher\_config\_parameter\_store\_tier](#input\_matcher\_config\_parameter\_store\_tier) | The tier of the parameter store for the matcher configuration. Valid values are `Standard`, and `Advanced`. | `string` | `"Standard"` | no |
| <a name="input_metrics"></a> [metrics](#input\_metrics) | Configuration for metrics created by the module, by default disabled to avoid additional costs. When metrics are enable all metrics are created unless explicit configured otherwise. | <pre>object({<br/> enable = optional(bool, false)<br/> namespace = optional(string, "GitHub Runners")<br/> metric = optional(object({<br/> enable_github_app_rate_limit = optional(bool, true)<br/> enable_job_retry = optional(bool, true)<br/> enable_spot_termination_warning = optional(bool, true)<br/> }), {})<br/> })</pre> | `{}` | no |
| <a name="input_metrics"></a> [metrics](#input\_metrics) | Configuration for metrics created by the module, by default disabled to avoid additional costs. When metrics are enable all metrics are created unless explicit configured otherwise. | <pre>object({<br/> enable = optional(bool, false)<br/> namespace = optional(string, "GitHub Runners")<br/> metric = optional(object({<br/> enable_github_app_rate_limit = optional(bool, true)<br/> enable_job_retry = optional(bool, true)<br/> enable_spot_termination_warning = optional(bool, true)<br/> enable_warm_pool = optional(bool, true)<br/> }), {})<br/> })</pre> | `{}` | no |
| <a name="input_minimum_running_time_in_minutes"></a> [minimum\_running\_time\_in\_minutes](#input\_minimum\_running\_time\_in\_minutes) | The time an ec2 action runner should be running at minimum before terminated, if not busy. | `number` | `null` | no |
| <a name="input_parameter_store_tags"></a> [parameter\_store\_tags](#input\_parameter\_store\_tags) | Map of tags that will be added to all the SSM Parameter Store parameters created by the Lambda function. | `map(string)` | `{}` | no |
| <a name="input_pool_config"></a> [pool\_config](#input\_pool\_config) | The configuration for updating the pool. The `pool_size` to adjust to by the events triggered by the `schedule_expression`. For example you can configure a cron expression for weekdays to adjust the pool to 10 and another expression for the weekend to adjust the pool to 1. Use `schedule_expression_timezone` to override the schedule time zone (defaults to UTC). | <pre>list(object({<br/> schedule_expression = string<br/> schedule_expression_timezone = optional(string)<br/> size = number<br/> }))</pre> | `[]` | no |
Expand All @@ -176,6 +176,7 @@ Join our discord community via [this invite link](https://discord.gg/bxgXW8jJGh)
| <a name="input_pool_lambda_reserved_concurrent_executions"></a> [pool\_lambda\_reserved\_concurrent\_executions](#input\_pool\_lambda\_reserved\_concurrent\_executions) | Amount of reserved concurrent executions for the scale-up lambda function. A value of 0 disables lambda from being triggered and -1 removes any concurrency limitations. | `number` | `1` | no |
| <a name="input_pool_lambda_timeout"></a> [pool\_lambda\_timeout](#input\_pool\_lambda\_timeout) | Time out for the pool lambda in seconds. | `number` | `60` | no |
| <a name="input_pool_runner_owner"></a> [pool\_runner\_owner](#input\_pool\_runner\_owner) | The pool will deploy runners to the GitHub org ID, set this value to the org to which you want the runners deployed. Repo level is not supported. | `string` | `null` | no |
| <a name="input_pool_strategy"></a> [pool\_strategy](#input\_pool\_strategy) | Strategy for maintaining idle runners: `hot` (default, traditional) or `warm` (stop instead of terminate). Requires `warm_pool_config.enabled = true` when set to `warm`. | `string` | `"hot"` | no |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | The prefix used for naming resources | `string` | `"github-actions"` | no |
| <a name="input_queue_encryption"></a> [queue\_encryption](#input\_queue\_encryption) | Configure how data on queues managed by the modules is encrypted at REST. Options are encrypted via SSE, non encrypted and via KMS. By default encrypted via SSE is enabled. See for more details the Terraform `aws_sqs_queue` resource https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue. | <pre>object({<br/> kms_data_key_reuse_period_seconds = number<br/> kms_master_key_id = string<br/> sqs_managed_sse_enabled = bool<br/> })</pre> | <pre>{<br/> "kms_data_key_reuse_period_seconds": null,<br/> "kms_master_key_id": null,<br/> "sqs_managed_sse_enabled": true<br/>}</pre> | no |
| <a name="input_queue_selection_strategy"></a> [queue\_selection\_strategy](#input\_queue\_selection\_strategy) | Strategy used to pick a queue when multiple runner configurations match a job equally well. `first` keeps the historical deterministic behaviour (the first matching queue by priority). `random` spreads jobs across the matching queues to avoid concentrating load on a single one. `all` scales up one runner per matching queue and lets the first to become available take the job (favouring speed over cost; this multiplies instance launches and runner registrations per job). | `string` | `"first"` | no |
Expand Down Expand Up @@ -239,6 +240,7 @@ Join our discord community via [this invite link](https://discord.gg/bxgXW8jJGh)
| <a name="input_userdata_pre_install"></a> [userdata\_pre\_install](#input\_userdata\_pre\_install) | Script to be ran before the GitHub Actions runner is installed on the EC2 instances | `string` | `""` | no |
| <a name="input_userdata_template"></a> [userdata\_template](#input\_userdata\_template) | Alternative user-data template file path, replacing the default template. By providing your own user\_data you have to take care of installing all required software, including the action runner. Variables userdata\_pre/post\_install are ignored. | `string` | `null` | no |
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | The VPC for security groups of the action runners. | `string` | n/a | yes |
| <a name="input_warm_pool_config"></a> [warm\_pool\_config](#input\_warm\_pool\_config) | Configuration for the warm pool feature. When enabled, idle runners are stopped instead of terminated, allowing 10-30s restart times instead of 2-5 minute cold starts. | <pre>object({<br/> enabled = optional(bool, false)<br/> max_warm_instances = optional(number, 3)<br/> max_warm_age_hours = optional(number, 168)<br/> warm_pool_ready_delay_seconds = optional(number, 30)<br/> })</pre> | `{}` | no |
| <a name="input_webhook_lambda_apigateway_access_log_settings"></a> [webhook\_lambda\_apigateway\_access\_log\_settings](#input\_webhook\_lambda\_apigateway\_access\_log\_settings) | Access log settings for webhook API gateway. | <pre>object({<br/> destination_arn = string<br/> format = string<br/> })</pre> | `null` | no |
| <a name="input_webhook_lambda_memory_size"></a> [webhook\_lambda\_memory\_size](#input\_webhook\_lambda\_memory\_size) | Memory size limit in MB for webhook lambda in. | `number` | `256` | no |
| <a name="input_webhook_lambda_s3_key"></a> [webhook\_lambda\_s3\_key](#input\_webhook\_lambda\_s3\_key) | S3 key for webhook lambda function. Required if using S3 bucket to specify lambdas. | `string` | `null` | no |
Expand Down
Loading