Skip to content
This repository was archived by the owner on Jan 16, 2025. It is now read-only.

Commit c2a834f

Browse files
authored
feat(runner): Add option to disable auto update (#1791)
* feat: Add option to disable auto update * Add junit test * Add disable_update_runners to Terraform * Add disable_update_runners to Terraform * set default to false * review * Add option to disable auto update to the pool * revert example
1 parent c55d273 commit c2a834f

File tree

13 files changed

+65
-26
lines changed

13 files changed

+65
-26
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -400,9 +400,10 @@ In case the setup does not work as intended follow the trace of events:
400400
| <a name="input_cloudwatch_config"></a> [cloudwatch\_config](#input\_cloudwatch\_config) | (optional) Replaces the module default cloudwatch log config. See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html for details. | `string` | `null` | no |
401401
| <a name="input_create_service_linked_role_spot"></a> [create\_service\_linked\_role\_spot](#input\_create\_service\_linked\_role\_spot) | (optional) create the serviced linked role for spot instances that is required by the scale-up lambda. | `bool` | `false` | no |
402402
| <a name="input_delay_webhook_event"></a> [delay\_webhook\_event](#input\_delay\_webhook\_event) | The number of seconds the event accepted by the webhook is invisible on the queue before the scale up lambda will receive the event. | `number` | `30` | no |
403+
| <a name="input_disable_runner_autoupdate"></a> [disable\_runner\_autoupdate](#input\_disable\_runner\_autoupdate) | Disable the auto update of the github runner agent. Be-aware there is a grace period of 30 days, see also the [GitHub article](https://github.blog/changelog/2022-02-01-github-actions-self-hosted-runners-can-now-disable-automatic-updates/) | `bool` | `false` | no |
403404
| <a name="input_enable_cloudwatch_agent"></a> [enable\_cloudwatch\_agent](#input\_enable\_cloudwatch\_agent) | Enabling the cloudwatch agent on the ec2 runner instances, the runner contains default config. Configuration can be overridden via `cloudwatch_config`. | `bool` | `true` | no |
404405
| <a name="input_enable_ephemeral_runners"></a> [enable\_ephemeral\_runners](#input\_enable\_ephemeral\_runners) | Enable ephemeral runners, runners will only be used once. | `bool` | `false` | no |
405-
| <a name="input_enable_managed_runner_security_group"></a> [enable\_managed\_runner\_security\_group](#inputenable\_managed\_runner\_security\_group) | Enabling the default managed security group creation. Unmanaged security groups can be specified via `runner_additional_security_group_ids`. | `bool` | `true` | no |
406+
| <a name="input_enable_managed_runner_security_group"></a> [enable\_managed\_runner\_security\_group](#input\_enable\_managed\_runner\_security\_group) | Enabling the default managed security group creation. Unmanaged security groups can be specified via `runner_additional_security_group_ids`. | `bool` | `true` | no |
406407
| <a name="input_enable_organization_runners"></a> [enable\_organization\_runners](#input\_enable\_organization\_runners) | Register runners to organization, instead of repo level | `bool` | `false` | no |
407408
| <a name="input_enable_ssm_on_runners"></a> [enable\_ssm\_on\_runners](#input\_enable\_ssm\_on\_runners) | Enable to allow access the runner instances for debugging purposes via SSM. Note that this adds additional permissions to the runner instances. | `bool` | `false` | no |
408409
| <a name="input_enabled_userdata"></a> [enabled\_userdata](#input\_enabled\_userdata) | Should the userdata script be enabled for the runner. Set this to false if you are using your own prebuilt AMI | `bool` | `true` | no |
@@ -454,7 +455,7 @@ In case the setup does not work as intended follow the trace of events:
454455
| <a name="input_runner_iam_role_managed_policy_arns"></a> [runner\_iam\_role\_managed\_policy\_arns](#input\_runner\_iam\_role\_managed\_policy\_arns) | Attach AWS or customer-managed IAM policies (by ARN) to the runner IAM role | `list(string)` | `[]` | no |
455456
| <a name="input_runner_log_files"></a> [runner\_log\_files](#input\_runner\_log\_files) | (optional) Replaces the module default cloudwatch log config. See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html for details. | <pre>list(object({<br> log_group_name = string<br> prefix_log_group = bool<br> file_path = string<br> log_stream_name = string<br> }))</pre> | `null` | no |
456457
| <a name="input_runner_metadata_options"></a> [runner\_metadata\_options](#input\_runner\_metadata\_options) | Metadata options for the ec2 runner instances. | `map(any)` | <pre>{<br> "http_endpoint": "enabled",<br> "http_put_response_hop_limit": 1,<br> "http_tokens": "optional"<br>}</pre> | no |
457-
| <a name="input_runner_os"></a> [runner\_os](#input\_runner\_os) | The Operating System to use for GitHub Actions Runners (linux,win) | `string` | `"linux"` | no |
458+
| <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 |
458459
| <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 |
459460
| <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. | `any` | `null` | no |
460461
| <a name="input_runners_lambda_s3_object_version"></a> [runners\_lambda\_s3\_object\_version](#input\_runners\_lambda\_s3\_object\_version) | S3 object version for runners lambda function. Useful if S3 versioning is enabled on source bucket. | `any` | `null` | no |

main.tf

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ module "runners" {
107107
github_app_parameters = local.github_app_parameters
108108
enable_organization_runners = var.enable_organization_runners
109109
enable_ephemeral_runners = var.enable_ephemeral_runners
110+
disable_runner_autoupdate = var.disable_runner_autoupdate
110111
enable_managed_runner_security_group = var.enable_managed_runner_security_group
111112
scale_down_schedule_expression = var.scale_down_schedule_expression
112113
minimum_running_time_in_minutes = var.minimum_running_time_in_minutes

modules/runner-binaries-syncer/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ No modules.
9292
| <a name="input_role_permissions_boundary"></a> [role\_permissions\_boundary](#input\_role\_permissions\_boundary) | Permissions boundary that will be added to the created role for the lambda. | `string` | `null` | no |
9393
| <a name="input_runner_allow_prerelease_binaries"></a> [runner\_allow\_prerelease\_binaries](#input\_runner\_allow\_prerelease\_binaries) | Allow the runners to update to prerelease binaries. | `bool` | `false` | no |
9494
| <a name="input_runner_architecture"></a> [runner\_architecture](#input\_runner\_architecture) | The platform architecture of the runner instance\_type. | `string` | `"x64"` | no |
95-
| <a name="input_runner_os"></a> [runner\_os](#input\_runner\_os) | The operating system for the runner instance (linux, win), defaults to 'linux' | `string` | `"linux"` | no |
95+
| <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 |
9696
| <a name="input_server_side_encryption_configuration"></a> [server\_side\_encryption\_configuration](#input\_server\_side\_encryption\_configuration) | Map containing server-side encryption configuration. | `any` | `{}` | no |
9797
| <a name="input_syncer_lambda_s3_key"></a> [syncer\_lambda\_s3\_key](#input\_syncer\_lambda\_s3\_key) | S3 key for syncer lambda function. Required if using S3 bucket to specify lambdas. | `any` | `null` | no |
9898
| <a name="input_syncer_lambda_s3_object_version"></a> [syncer\_lambda\_s3\_object\_version](#input\_syncer\_lambda\_s3\_object\_version) | S3 object version for syncer lambda function. Useful if S3 versioning is enabled on source bucket. | `any` | `null` | no |

modules/runners/README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,11 @@ yarn run dist
119119
| <a name="input_block_device_mappings"></a> [block\_device\_mappings](#input\_block\_device\_mappings) | The EC2 instance block device configuration. Takes the following keys: `device_name`, `delete_on_termination`, `volume_type`, `volume_size`, `encrypted`, `iops` | `map(string)` | `{}` | no |
120120
| <a name="input_cloudwatch_config"></a> [cloudwatch\_config](#input\_cloudwatch\_config) | (optional) Replaces the module default cloudwatch log config. See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html for details. | `string` | `null` | no |
121121
| <a name="input_create_service_linked_role_spot"></a> [create\_service\_linked\_role\_spot](#input\_create\_service\_linked\_role\_spot) | (optional) create the service linked role for spot instances that is required by the scale-up lambda. | `bool` | `false` | no |
122+
| <a name="input_disable_runner_autoupdate"></a> [disable\_runner\_autoupdate](#input\_disable\_runner\_autoupdate) | Disable the auto update of the github runner agent. Be-aware there is a grace period of 30 days, see also the [GitHub article](https://github.blog/changelog/2022-02-01-github-actions-self-hosted-runners-can-now-disable-automatic-updates/) | `bool` | `true` | no |
122123
| <a name="input_egress_rules"></a> [egress\_rules](#input\_egress\_rules) | List of egress rules for the GitHub runner instances. | <pre>list(object({<br> cidr_blocks = list(string)<br> ipv6_cidr_blocks = list(string)<br> prefix_list_ids = list(string)<br> from_port = number<br> protocol = string<br> security_groups = list(string)<br> self = bool<br> to_port = number<br> description = string<br> }))</pre> | <pre>[<br> {<br> "cidr_blocks": [<br> "0.0.0.0/0"<br> ],<br> "description": null,<br> "from_port": 0,<br> "ipv6_cidr_blocks": [<br> "::/0"<br> ],<br> "prefix_list_ids": null,<br> "protocol": "-1",<br> "security_groups": null,<br> "self": null,<br> "to_port": 0<br> }<br>]</pre> | no |
123124
| <a name="input_enable_cloudwatch_agent"></a> [enable\_cloudwatch\_agent](#input\_enable\_cloudwatch\_agent) | Enabling the cloudwatch agent on the ec2 runner instances, the runner contains default config. Configuration can be overridden via `cloudwatch_config`. | `bool` | `true` | no |
124125
| <a name="input_enable_ephemeral_runners"></a> [enable\_ephemeral\_runners](#input\_enable\_ephemeral\_runners) | Enable ephemeral runners, runners will only be used once. | `bool` | `false` | no |
125-
| <a name="input_enable_managed_runner_security_group"></a> [enable\_managed\_runner\_security\_group](#inputenable\_managed\_runner\_security\_group) | Enabling the default managed security group creation. Unmanaged security groups can be specified via `runner_additional_security_group_ids`. | `bool` | `true` | no |
126+
| <a name="input_enable_managed_runner_security_group"></a> [enable\_managed\_runner\_security\_group](#input\_enable\_managed\_runner\_security\_group) | Enabling the default managed security group creation. Unmanaged security groups can be specified via `runner_additional_security_group_ids`. | `bool` | `true` | no |
126127
| <a name="input_enable_organization_runners"></a> [enable\_organization\_runners](#input\_enable\_organization\_runners) | n/a | `bool` | n/a | yes |
127128
| <a name="input_enable_ssm_on_runners"></a> [enable\_ssm\_on\_runners](#input\_enable\_ssm\_on\_runners) | Enable to allow access to the runner instances for debugging purposes via SSM. Note that this adds additional permissions to the runner instances. | `bool` | n/a | yes |
128129
| <a name="input_enabled_userdata"></a> [enabled\_userdata](#input\_enabled\_userdata) | Should the userdata script be enabled for the runner. Set this to false if you are using your own prebuilt AMI | `bool` | `true` | no |
@@ -167,7 +168,7 @@ yarn run dist
167168
| <a name="input_runner_group_name"></a> [runner\_group\_name](#input\_runner\_group\_name) | Name of the runner group. | `string` | `"Default"` | no |
168169
| <a name="input_runner_iam_role_managed_policy_arns"></a> [runner\_iam\_role\_managed\_policy\_arns](#input\_runner\_iam\_role\_managed\_policy\_arns) | Attach AWS or customer-managed IAM policies (by ARN) to the runner IAM role | `list(string)` | `[]` | no |
169170
| <a name="input_runner_log_files"></a> [runner\_log\_files](#input\_runner\_log\_files) | (optional) List of logfiles to send to CloudWatch, will only be used if `enable_cloudwatch_agent` is set to true. Object description: `log_group_name`: Name of the log group, `prefix_log_group`: If true, the log group name will be prefixed with `/github-self-hosted-runners/<var.environment>`, `file_path`: path to the log file, `log_stream_name`: name of the log stream. | <pre>list(object({<br> log_group_name = string<br> prefix_log_group = bool<br> file_path = string<br> log_stream_name = string<br> }))</pre> | `null` | no |
170-
| <a name="input_runner_os"></a> [runner\_os](#input\_runner\_os) | The EC2 Operating System type to use for action runner instances (linux,win). | `string` | `"linux"` | no |
171+
| <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 |
171172
| <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 |
172173
| <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. | `any` | `null` | no |
173174
| <a name="input_runners_lambda_s3_object_version"></a> [runners\_lambda\_s3\_object\_version](#input\_runners\_lambda\_s3\_object\_version) | S3 object version for runners lambda function. Useful if S3 versioning is enabled on source bucket. | `any` | `null` | no |

modules/runners/lambdas/runners/src/pool/pool.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export async function adjust(event: PoolEvent): Promise<void> {
2121
const instanceTypes = process.env.INSTANCE_TYPES.split(',');
2222
const instanceTargetTargetCapacityType = process.env.INSTANCE_TARGET_CAPACITY_TYPE;
2323
const ephemeral = yn(process.env.ENABLE_EPHEMERAL_RUNNERS, { default: false });
24+
const disableAutoUpdate = yn(process.env.DISABLE_RUNNER_AUTOUPDATE, { default: false });
2425
const launchTemplateName = process.env.LAUNCH_TEMPLATE_NAME;
2526
const instanceMaxSpotPrice = process.env.INSTANCE_MAX_SPOT_PRICE;
2627
const instanceAllocationStrategy = process.env.INSTANCE_ALLOCATION_STRATEGY || 'lowest-price'; // same as AWS default
@@ -60,7 +61,15 @@ export async function adjust(event: PoolEvent): Promise<void> {
6061
if (topUp > 0) {
6162
logger.info(`The pool will be topped up with ${topUp} runners.`);
6263
await createRunners(
63-
{ ephemeral, ghesBaseUrl, runnerExtraLabels, runnerGroup, runnerOwner, runnerType: 'Org' },
64+
{
65+
ephemeral,
66+
ghesBaseUrl,
67+
runnerExtraLabels,
68+
runnerGroup,
69+
runnerOwner,
70+
runnerType: 'Org',
71+
disableAutoUpdate: disableAutoUpdate,
72+
},
6473
{
6574
ec2instanceCriteria: {
6675
instanceTypes,

modules/runners/lambdas/runners/src/scale-runners/scale-up.test.ts

+7
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,13 @@ describe('scaleUp with public GH', () => {
528528
expect(createRunner).toBeCalledWith(expectedRunnerParams);
529529
});
530530

531+
it('disable auto update on the runner.', async () => {
532+
process.env.DISABLE_RUNNER_AUTOUPDATE = 'true';
533+
await scaleUpModule.scaleUp('aws:sqs', TEST_DATA);
534+
expectedRunnerParams.runnerServiceConfig = expectedRunnerParams.runnerServiceConfig + ` --disableupdate`;
535+
expect(createRunner).toBeCalledWith(expectedRunnerParams);
536+
});
537+
531538
it('Scaling error should cause reject so retry can be triggered.', async () => {
532539
process.env.RUNNERS_MAXIMUM_COUNT = '1';
533540
process.env.ENABLE_EPHEMERAL_RUNNERS = 'true';

modules/runners/lambdas/runners/src/scale-runners/scale-up.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ interface CreateGitHubRunnerConfig {
2323
runnerGroup: string | undefined;
2424
runnerOwner: string;
2525
runnerType: 'Org' | 'Repo';
26+
disableAutoUpdate: boolean;
2627
}
2728

2829
interface CreateEC2RunnerConfig {
@@ -40,7 +41,8 @@ function generateRunnerServiceConfig(githubRunnerConfig: CreateGitHubRunnerConfi
4041
githubRunnerConfig.runnerGroup !== undefined ? `--runnergroup ${githubRunnerConfig.runnerGroup} ` : '';
4142
const configBaseUrl = githubRunnerConfig.ghesBaseUrl ? githubRunnerConfig.ghesBaseUrl : 'https://github.com';
4243
const ephemeralArgument = githubRunnerConfig.ephemeral ? '--ephemeral ' : '';
43-
const runnerArgs = `--token ${token} ${labelsArgument}${ephemeralArgument}`;
44+
const disableUpdateArgument = githubRunnerConfig.disableAutoUpdate ? '--disableupdate ' : '';
45+
const runnerArgs = `--token ${token} ${labelsArgument}${ephemeralArgument}${disableUpdateArgument}`;
4446
return githubRunnerConfig.runnerType === 'Org'
4547
? `--url ${configBaseUrl}/${githubRunnerConfig.runnerOwner} ${runnerArgs}${runnerGroupArgument}`.trim()
4648
: `--url ${configBaseUrl}/${githubRunnerConfig.runnerOwner} ${runnerArgs}`.trim();
@@ -141,6 +143,7 @@ export async function scaleUp(eventSource: string, payload: ActionRequestMessage
141143
const instanceTypes = process.env.INSTANCE_TYPES.split(',');
142144
const instanceTargetTargetCapacityType = process.env.INSTANCE_TARGET_CAPACITY_TYPE;
143145
const ephemeralEnabled = yn(process.env.ENABLE_EPHEMERAL_RUNNERS, { default: false });
146+
const disableAutoUpdate = yn(process.env.DISABLE_RUNNER_AUTOUPDATE, { default: false });
144147
const launchTemplateName = process.env.LAUNCH_TEMPLATE_NAME;
145148
const instanceMaxSpotPrice = process.env.INSTANCE_MAX_SPOT_PRICE;
146149
const instanceAllocationStrategy = process.env.INSTANCE_ALLOCATION_STRATEGY || 'lowest-price'; // same as AWS default
@@ -195,6 +198,7 @@ export async function scaleUp(eventSource: string, payload: ActionRequestMessage
195198
runnerGroup,
196199
runnerOwner,
197200
runnerType,
201+
disableAutoUpdate,
198202
},
199203
{
200204
ec2instanceCriteria: {

modules/runners/pool.tf

+7-6
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,13 @@ module "pool" {
3232
role_path = local.role_path
3333
role_permissions_boundary = var.role_permissions_boundary
3434
runner = {
35-
ephemeral = var.enable_ephemeral_runners
36-
extra_labels = var.runner_extra_labels
37-
launch_template = aws_launch_template.runner
38-
group_name = var.runner_group_name
39-
pool_owner = var.pool_runner_owner
40-
role = aws_iam_role.runner
35+
disable_runner_autoupdate = var.disable_runner_autoupdate
36+
ephemeral = var.enable_ephemeral_runners
37+
extra_labels = var.runner_extra_labels
38+
launch_template = aws_launch_template.runner
39+
group_name = var.runner_group_name
40+
pool_owner = var.pool_runner_owner
41+
role = aws_iam_role.runner
4142
}
4243
subnet_ids = var.subnet_ids
4344
tags = local.tags

modules/runners/pool/main.tf

+7-6
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,14 @@ resource "aws_lambda_function" "pool" {
1616

1717
environment {
1818
variables = {
19-
RUNNER_OWNER = var.config.runner.pool_owner
19+
DISABLE_RUNNER_AUTOUPDATE = var.config.runner.disable_runner_autoupdate
20+
ENABLE_EPHEMERAL_RUNNERS = var.config.runner.ephemeral
2021
ENVIRONMENT = var.config.environment
2122
GHES_URL = var.config.ghes.url
23+
INSTANCE_ALLOCATION_STRATEGY = var.config.instance_allocation_strategy
24+
INSTANCE_MAX_SPOT_PRICE = var.config.instance_max_spot_price
25+
INSTANCE_TARGET_CAPACITY_TYPE = var.config.instance_target_capacity_type
26+
INSTANCE_TYPES = join(",", var.config.instance_types)
2227
LAUNCH_TEMPLATE_NAME = var.config.runner.launch_template.name
2328
LOG_LEVEL = var.config.lambda.log_level
2429
LOG_TYPE = var.config.lambda.log_type
@@ -27,12 +32,8 @@ resource "aws_lambda_function" "pool" {
2732
PARAMETER_GITHUB_APP_KEY_BASE64_NAME = var.config.github_app_parameters.key_base64.name
2833
RUNNER_EXTRA_LABELS = var.config.runner.extra_labels
2934
RUNNER_GROUP_NAME = var.config.runner.group_name
35+
RUNNER_OWNER = var.config.runner.pool_owner
3036
SUBNET_IDS = join(",", var.config.subnet_ids)
31-
ENABLE_EPHEMERAL_RUNNERS = var.config.runner.ephemeral
32-
INSTANCE_TYPES = join(",", var.config.instance_types)
33-
INSTANCE_TARGET_CAPACITY_TYPE = var.config.instance_target_capacity_type
34-
INSTANCE_MAX_SPOT_PRICE = var.config.instance_max_spot_price
35-
INSTANCE_ALLOCATION_STRATEGY = var.config.instance_allocation_strategy
3637
}
3738
}
3839

0 commit comments

Comments
 (0)