Skip to content

Commit 621cf5d

Browse files
edersonbrilhantegithub-actions[bot]npalm
authored
feat: add support to use placement group in launch template (#4929)
## Description This PR adds support for configuring EC2 placement groups for GitHub Actions runners in the multi-runner module. It plumbs a new placement option from the runner configuration through to the underlying EC2 runner module. ## Details Updated modules/multi-runner/runners.tf to pass placement = each.value.runner_config.placement into the runners module. This allows specifying AWS placement groups for EC2 runners, enabling tighter control over instance placement. The change is backwards compatible: if placement is unset in runner_config, behavior remains unchanged. ## Motivation / Future work Placement groups are a prerequisite for supporting macOS runners, which require a host_id. A follow-up PR will add explicit macOS support leveraging this new placement wiring. --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Niek Palm <npalm@users.noreply.github.com>
1 parent ce198bf commit 621cf5d

File tree

9 files changed

+63
-1
lines changed

9 files changed

+63
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ Join our discord community via [this invite link](https://discord.gg/bxgXW8jJGh)
202202
| <a name="input_runner_metadata_options"></a> [runner\_metadata\_options](#input\_runner\_metadata\_options) | Metadata options for the ec2 runner instances. By default, the module uses metadata tags for bootstrapping the runner, only disable `instance_metadata_tags` when using custom scripts for starting the runner. | `map(any)` | <pre>{<br/> "http_endpoint": "enabled",<br/> "http_put_response_hop_limit": 1,<br/> "http_tokens": "required",<br/> "instance_metadata_tags": "enabled"<br/>}</pre> | no |
203203
| <a name="input_runner_name_prefix"></a> [runner\_name\_prefix](#input\_runner\_name\_prefix) | The prefix used for the GitHub runner name. The prefix will be used in the default start script to prefix the instance name when register the runner in GitHub. The value is available via an EC2 tag 'ghr:runner\_name\_prefix'. | `string` | `""` | no |
204204
| <a name="input_runner_os"></a> [runner\_os](#input\_runner\_os) | The EC2 Operating System type to use for action runner instances (linux,windows). | `string` | `"linux"` | no |
205+
| <a name="input_runner_placement"></a> [runner\_placement](#input\_runner\_placement) | The placement options for the instance. See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template#placement for details. | <pre>object({<br/> affinity = optional(string)<br/> availability_zone = optional(string)<br/> group_id = optional(string)<br/> group_name = optional(string)<br/> host_id = optional(string)<br/> host_resource_group_arn = optional(number)<br/> spread_domain = optional(string)<br/> tenancy = optional(string)<br/> partition_number = optional(number)<br/> })</pre> | `null` | no |
205206
| <a name="input_runner_run_as"></a> [runner\_run\_as](#input\_runner\_run\_as) | Run the GitHub actions agent as user. | `string` | `"ec2-user"` | no |
206207
| <a name="input_runners_ebs_optimized"></a> [runners\_ebs\_optimized](#input\_runners\_ebs\_optimized) | Enable EBS optimization for the runner instances. | `bool` | `false` | no |
207208
| <a name="input_runners_lambda_s3_key"></a> [runners\_lambda\_s3\_key](#input\_runners\_lambda\_s3\_key) | S3 key for runners lambda function. Required if using S3 bucket to specify lambdas. | `string` | `null` | no |

main.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ module "runners" {
205205
metadata_options = var.runner_metadata_options
206206
credit_specification = var.runner_credit_specification
207207
cpu_options = var.runner_cpu_options
208+
placement = var.runner_placement
208209

209210
enable_runner_binaries_syncer = var.enable_runner_binaries_syncer
210211
lambda_s3_bucket = var.lambda_s3_bucket

modules/multi-runner/README.md

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

modules/multi-runner/runners.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ module "runners" {
5454
metadata_options = each.value.runner_config.runner_metadata_options
5555
credit_specification = each.value.runner_config.credit_specification
5656
cpu_options = each.value.runner_config.cpu_options
57+
placement = each.value.runner_config.placement
5758

5859
enable_runner_binaries_syncer = each.value.runner_config.enable_runner_binaries_syncer
5960
lambda_s3_bucket = var.lambda_s3_bucket

modules/multi-runner/variables.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,17 @@ variable "multi_runner_config" {
125125
core_count = number
126126
threads_per_core = number
127127
}), null)
128+
placement = optional(object({
129+
affinity = optional(string)
130+
availability_zone = optional(string)
131+
group_id = optional(string)
132+
group_name = optional(string)
133+
host_id = optional(string)
134+
host_resource_group_arn = optional(number)
135+
spread_domain = optional(string)
136+
tenancy = optional(string)
137+
partition_number = optional(number)
138+
}), null)
128139
runner_log_files = optional(list(object({
129140
log_group_name = string
130141
prefix_log_group = bool

modules/runners/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ yarn run dist
192192
| <a name="input_metrics"></a> [metrics](#input\_metrics) | Configuration for metrics created by the module, by default metrics are 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 |
193193
| <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 non busy. If not set the default is calculated based on the OS. | `number` | `null` | no |
194194
| <a name="input_overrides"></a> [overrides](#input\_overrides) | This map provides the possibility to override some defaults. The following attributes are supported: `name_sg` overrides the `Name` tag for all security groups created by this module. `name_runner_agent_instance` overrides the `Name` tag for the ec2 instance defined in the auto launch configuration. `name_docker_machine_runners` overrides the `Name` tag spot instances created by the runner agent. | `map(string)` | <pre>{<br/> "name_runner": "",<br/> "name_sg": ""<br/>}</pre> | no |
195+
| <a name="input_placement"></a> [placement](#input\_placement) | The placement options for the instance. See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template#placement for details. | <pre>object({<br/> affinity = optional(string)<br/> availability_zone = optional(string)<br/> group_id = optional(string)<br/> group_name = optional(string)<br/> host_id = optional(string)<br/> host_resource_group_arn = optional(number)<br/> spread_domain = optional(string)<br/> tenancy = optional(string)<br/> partition_number = optional(number)<br/> })</pre> | `null` | no |
195196
| <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 week days 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 |
196197
| <a name="input_pool_lambda_memory_size"></a> [pool\_lambda\_memory\_size](#input\_pool\_lambda\_memory\_size) | Lambda Memory size limit in MB for pool lambda | `number` | `512` | no |
197198
| <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 |

modules/runners/main.tf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,21 @@ resource "aws_launch_template" "runner" {
171171
}
172172
}
173173

174+
dynamic "placement" {
175+
for_each = var.placement != null ? [var.placement] : []
176+
content {
177+
affinity = try(placement.value.affinity, null)
178+
availability_zone = try(placement.value.availability_zone, null)
179+
group_id = try(placement.value.group_id, null)
180+
group_name = try(placement.value.group_name, null)
181+
host_id = try(placement.value.host_id, null)
182+
host_resource_group_arn = try(placement.value.host_resource_group_arn, null)
183+
spread_domain = try(placement.value.spread_domain, null)
184+
tenancy = try(placement.value.tenancy, null)
185+
partition_number = try(placement.value.partition_number, null)
186+
}
187+
}
188+
174189
monitoring {
175190
enabled = var.enable_runner_detailed_monitoring
176191
}

modules/runners/variables.tf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,22 @@ variable "cpu_options" {
643643
default = null
644644
}
645645

646+
variable "placement" {
647+
description = "The placement options for the instance. See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template#placement for details."
648+
type = object({
649+
affinity = optional(string)
650+
availability_zone = optional(string)
651+
group_id = optional(string)
652+
group_name = optional(string)
653+
host_id = optional(string)
654+
host_resource_group_arn = optional(number)
655+
spread_domain = optional(string)
656+
tenancy = optional(string)
657+
partition_number = optional(number)
658+
})
659+
default = null
660+
}
661+
646662
variable "enable_jit_config" {
647663
description = "Overwrite the default behavior for JIT configuration. By default JIT configuration is enabled for ephemeral runners and disabled for non-ephemeral runners. In case of GHES check first if the JIT config API is available. In case you are upgrading from 3.x to 4.x you can set `enable_jit_config` to `false` to avoid a breaking change when having your own AMI."
648664
type = bool

variables.tf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,22 @@ variable "runner_cpu_options" {
858858
default = null
859859
}
860860

861+
variable "runner_placement" {
862+
description = "The placement options for the instance. See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template#placement for details."
863+
type = object({
864+
affinity = optional(string)
865+
availability_zone = optional(string)
866+
group_id = optional(string)
867+
group_name = optional(string)
868+
host_id = optional(string)
869+
host_resource_group_arn = optional(number)
870+
spread_domain = optional(string)
871+
tenancy = optional(string)
872+
partition_number = optional(number)
873+
})
874+
default = null
875+
}
876+
861877
variable "enable_jit_config" {
862878
description = "Overwrite the default behavior for JIT configuration. By default JIT configuration is enabled for ephemeral runners and disabled for non-ephemeral runners. In case of GHES check first if the JIT config API is available. In case you are upgrading from 3.x to 4.x you can set `enable_jit_config` to `false` to avoid a breaking change when having your own AMI."
863879
type = bool

0 commit comments

Comments
 (0)