Skip to content

Commit b82ffea

Browse files
authored
Upstream eks/actions-runner-controller with var.auto_update_enabled (cloudposse/terraform-aws-components#1095)
1 parent f68021e commit b82ffea

File tree

5 files changed

+49
-25
lines changed

5 files changed

+49
-25
lines changed

src/README.md

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -384,15 +384,13 @@ scale down to zero before finishing all the jobs, leaving some waiting indefinit
384384
the `max_duration` to a time long enough to cover the full time a job may have to wait between the time it is queued and
385385
the time it finishes, assuming that the HRA scales up the pool by 1 and runs the job on the new runner.
386386

387-
:::info
388-
389-
If there are more jobs queued than there are runners allowed by `maxReplicas`, the timeout timer does not start on the
390-
capacity reservation until enough reservations ahead of it are removed for it to be considered as representing and
391-
active job. Although there are some edge cases regarding `max_duration` that seem not to be covered properly (see
392-
[actions-runner-controller issue #2466](https://github.com/actions/actions-runner-controller/issues/2466)), they only
393-
merit adding a few extra minutes to the timeout.
394-
395-
:::
387+
> [!TIP]
388+
>
389+
> If there are more jobs queued than there are runners allowed by `maxReplicas`, the timeout timer does not start on the
390+
> capacity reservation until enough reservations ahead of it are removed for it to be considered as representing and
391+
> active job. Although there are some edge cases regarding `max_duration` that seem not to be covered properly (see
392+
> [actions-runner-controller issue #2466](https://github.com/actions/actions-runner-controller/issues/2466)), they only
393+
> merit adding a few extra minutes to the timeout.
396394

397395
### Recommended `max_duration` Duration
398396

@@ -570,7 +568,7 @@ documentation for further details.
570568
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.<br>Characters matching the regex will be removed from the ID elements.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
571569
| <a name="input_region"></a> [region](#input\_region) | AWS Region. | `string` | n/a | yes |
572570
| <a name="input_resources"></a> [resources](#input\_resources) | The cpu and memory of the deployment's limits and requests. | <pre>object({<br> limits = object({<br> cpu = string<br> memory = string<br> })<br> requests = object({<br> cpu = string<br> memory = string<br> })<br> })</pre> | n/a | yes |
573-
| <a name="input_runners"></a> [runners](#input\_runners) | Map of Action Runner configurations, with the key being the name of the runner. Please note that the name must be in<br>kebab-case.<br><br>For example:<pre>hcl<br>organization_runner = {<br> type = "organization" # can be either 'organization' or 'repository'<br> dind_enabled: true # A Docker daemon will be started in the runner Pod<br> image: summerwind/actions-runner-dind # If dind_enabled=false, set this to 'summerwind/actions-runner'<br> scope = "ACME" # org name for Organization runners, repo name for Repository runners<br> group = "core-automation" # Optional. Assigns the runners to a runner group, for access control.<br> scale_down_delay_seconds = 300<br> min_replicas = 1<br> max_replicas = 5<br> labels = [<br> "Ubuntu",<br> "core-automation",<br> ]<br>}</pre> | <pre>map(object({<br> type = string<br> scope = string<br> group = optional(string, null)<br> image = optional(string, "summerwind/actions-runner-dind")<br> dind_enabled = optional(bool, true)<br> node_selector = optional(map(string), {})<br> pod_annotations = optional(map(string), {})<br><br> # running_pod_annotations are only applied to the pods once they start running a job<br> running_pod_annotations = optional(map(string), {})<br><br> # affinity is too complex to model. Whatever you assigned affinity will be copied<br> # to the runner Pod spec.<br> affinity = optional(any)<br><br> tolerations = optional(list(object({<br> key = string<br> operator = string<br> value = optional(string, null)<br> effect = string<br> })), [])<br> scale_down_delay_seconds = optional(number, 300)<br> min_replicas = number<br> max_replicas = number<br> # Scheduled overrides. See https://github.com/actions/actions-runner-controller/blob/master/docs/automatically-scaling-runners.md#scheduled-overrides<br> # Order is important. The earlier entry is prioritized higher than later entries. So you usually define<br> # one-time overrides at the top of your list, then yearly, monthly, weekly, and lastly daily overrides.<br> scheduled_overrides = optional(list(object({<br> start_time = string # ISO 8601 format, eg, "2021-06-01T00:00:00+09:00"<br> end_time = string # ISO 8601 format, eg, "2021-06-01T00:00:00+09:00"<br> min_replicas = optional(number)<br> max_replicas = optional(number)<br> recurrence_rule = optional(object({<br> frequency = string # One of Daily, Weekly, Monthly, Yearly<br> until_time = optional(string) # ISO 8601 format time after which the schedule will no longer apply<br> }))<br> })), [])<br> busy_metrics = optional(object({<br> scale_up_threshold = string<br> scale_down_threshold = string<br> scale_up_adjustment = optional(string)<br> scale_down_adjustment = optional(string)<br> scale_up_factor = optional(string)<br> scale_down_factor = optional(string)<br> }))<br> webhook_driven_scaling_enabled = optional(bool, true)<br> # max_duration is the duration after which a job will be considered completed,<br> # even if the webhook has not received a "job completed" event.<br> # This is to ensure that if an event is missed, it does not leave the runner running forever.<br> # Set it long enough to cover the longest job you expect to run and then some.<br> # See https://github.com/actions/actions-runner-controller/blob/9afd93065fa8b1f87296f0dcdf0c2753a0548cb7/docs/automatically-scaling-runners.md?plain=1#L264-L268<br> # Defaults to 1 hour programmatically (to be able to detect if both max_duration and webhook_startup_timeout are set).<br> max_duration = optional(string)<br> # The name `webhook_startup_timeout` was misleading and has been deprecated.<br> # It has been renamed `max_duration`.<br> webhook_startup_timeout = optional(string)<br> # Adjust the time (in seconds) to wait for the Docker in Docker daemon to become responsive.<br> wait_for_docker_seconds = optional(string, "")<br> pull_driven_scaling_enabled = optional(bool, false)<br> labels = optional(list(string), [])<br> # If not null, `docker_storage` specifies the size (as `go` string) of<br> # an ephemeral (default storage class) Persistent Volume to allocate for the Docker daemon.<br> # Takes precedence over `tmpfs_enabled` for the Docker daemon storage.<br> docker_storage = optional(string, null)<br> # storage is deprecated in favor of docker_storage, since it is only storage for the Docker daemon<br> storage = optional(string, null)<br> # If `pvc_enabled` is true, a Persistent Volume Claim will be created for the runner<br> # and mounted at /home/runner/work/shared. This is useful for sharing data between runners.<br> pvc_enabled = optional(bool, false)<br> # If `tmpfs_enabled` is `true`, both the runner and the docker daemon will use a tmpfs volume,<br> # meaning that all data will be stored in RAM rather than on disk, bypassing disk I/O limitations,<br> # but what would have been disk usage is now additional memory usage. You must specify memory<br> # requests and limits when using tmpfs or else the Pod will likely crash the Node.<br> tmpfs_enabled = optional(bool)<br> resources = optional(object({<br> limits = optional(object({<br> cpu = optional(string, "1")<br> memory = optional(string, "1Gi")<br> ephemeral_storage = optional(string, "10Gi")<br> }), {})<br> requests = optional(object({<br> cpu = optional(string, "500m")<br> memory = optional(string, "256Mi")<br> ephemeral_storage = optional(string, "1Gi")<br> }), {})<br> }), {})<br> }))</pre> | n/a | yes |
571+
| <a name="input_runners"></a> [runners](#input\_runners) | Map of Action Runner configurations, with the key being the name of the runner. Please note that the name must be in<br>kebab-case.<br><br>For example:<pre>hcl<br>organization_runner = {<br> type = "organization" # can be either 'organization' or 'repository'<br> dind_enabled: true # A Docker daemon will be started in the runner Pod<br> image: summerwind/actions-runner-dind # If dind_enabled=false, set this to 'summerwind/actions-runner'<br> scope = "ACME" # org name for Organization runners, repo name for Repository runners<br> group = "core-automation" # Optional. Assigns the runners to a runner group, for access control.<br> scale_down_delay_seconds = 300<br> min_replicas = 1<br> max_replicas = 5<br> labels = [<br> "Ubuntu",<br> "core-automation",<br> ]<br>}</pre> | <pre>map(object({<br> type = string<br> scope = string<br> group = optional(string, null)<br> image = optional(string, "summerwind/actions-runner-dind")<br> auto_update_enabled = optional(bool, true)<br> dind_enabled = optional(bool, true)<br> node_selector = optional(map(string), {})<br> pod_annotations = optional(map(string), {})<br><br> # running_pod_annotations are only applied to the pods once they start running a job<br> running_pod_annotations = optional(map(string), {})<br><br> # affinity is too complex to model. Whatever you assigned affinity will be copied<br> # to the runner Pod spec.<br> affinity = optional(any)<br><br> tolerations = optional(list(object({<br> key = string<br> operator = string<br> value = optional(string, null)<br> effect = string<br> })), [])<br> scale_down_delay_seconds = optional(number, 300)<br> min_replicas = number<br> max_replicas = number<br> # Scheduled overrides. See https://github.com/actions/actions-runner-controller/blob/master/docs/automatically-scaling-runners.md#scheduled-overrides<br> # Order is important. The earlier entry is prioritized higher than later entries. So you usually define<br> # one-time overrides at the top of your list, then yearly, monthly, weekly, and lastly daily overrides.<br> scheduled_overrides = optional(list(object({<br> start_time = string # ISO 8601 format, eg, "2021-06-01T00:00:00+09:00"<br> end_time = string # ISO 8601 format, eg, "2021-06-01T00:00:00+09:00"<br> min_replicas = optional(number)<br> max_replicas = optional(number)<br> recurrence_rule = optional(object({<br> frequency = string # One of Daily, Weekly, Monthly, Yearly<br> until_time = optional(string) # ISO 8601 format time after which the schedule will no longer apply<br> }))<br> })), [])<br> busy_metrics = optional(object({<br> scale_up_threshold = string<br> scale_down_threshold = string<br> scale_up_adjustment = optional(string)<br> scale_down_adjustment = optional(string)<br> scale_up_factor = optional(string)<br> scale_down_factor = optional(string)<br> }))<br> webhook_driven_scaling_enabled = optional(bool, true)<br> # max_duration is the duration after which a job will be considered completed,<br> # even if the webhook has not received a "job completed" event.<br> # This is to ensure that if an event is missed, it does not leave the runner running forever.<br> # Set it long enough to cover the longest job you expect to run and then some.<br> # See https://github.com/actions/actions-runner-controller/blob/9afd93065fa8b1f87296f0dcdf0c2753a0548cb7/docs/automatically-scaling-runners.md?plain=1#L264-L268<br> # Defaults to 1 hour programmatically (to be able to detect if both max_duration and webhook_startup_timeout are set).<br> max_duration = optional(string)<br> # The name `webhook_startup_timeout` was misleading and has been deprecated.<br> # It has been renamed `max_duration`.<br> webhook_startup_timeout = optional(string)<br> # Adjust the time (in seconds) to wait for the Docker in Docker daemon to become responsive.<br> wait_for_docker_seconds = optional(string, "")<br> pull_driven_scaling_enabled = optional(bool, false)<br> labels = optional(list(string), [])<br> # If not null, `docker_storage` specifies the size (as `go` string) of<br> # an ephemeral (default storage class) Persistent Volume to allocate for the Docker daemon.<br> # Takes precedence over `tmpfs_enabled` for the Docker daemon storage.<br> docker_storage = optional(string, null)<br> # storage is deprecated in favor of docker_storage, since it is only storage for the Docker daemon<br> storage = optional(string, null)<br> # If `pvc_enabled` is true, a Persistent Volume Claim will be created for the runner<br> # and mounted at /home/runner/work/shared. This is useful for sharing data between runners.<br> pvc_enabled = optional(bool, false)<br> # If `tmpfs_enabled` is `true`, both the runner and the docker daemon will use a tmpfs volume,<br> # meaning that all data will be stored in RAM rather than on disk, bypassing disk I/O limitations,<br> # but what would have been disk usage is now additional memory usage. You must specify memory<br> # requests and limits when using tmpfs or else the Pod will likely crash the Node.<br> tmpfs_enabled = optional(bool)<br> resources = optional(object({<br> limits = optional(object({<br> cpu = optional(string, "1")<br> memory = optional(string, "1Gi")<br> # ephemeral-storage is the Kubernetes name, but `ephemeral_storage` is the gomplate name,<br> # so allow either. If both are specified, `ephemeral-storage` takes precedence.<br> ephemeral-storage = optional(string)<br> ephemeral_storage = optional(string, "10Gi")<br> }), {})<br> requests = optional(object({<br> cpu = optional(string, "500m")<br> memory = optional(string, "256Mi")<br> # ephemeral-storage is the Kubernetes name, but `ephemeral_storage` is the gomplate name,<br> # so allow either. If both are specified, `ephemeral-storage` takes precedence.<br> ephemeral-storage = optional(string)<br> ephemeral_storage = optional(string, "1Gi")<br> }), {})<br> }), {})<br> }))</pre> | n/a | yes |
574572
| <a name="input_s3_bucket_arns"></a> [s3\_bucket\_arns](#input\_s3\_bucket\_arns) | List of ARNs of S3 Buckets to which the runners will have read-write access to. | `list(string)` | `[]` | no |
575573
| <a name="input_ssm_docker_config_json_path"></a> [ssm\_docker\_config\_json\_path](#input\_ssm\_docker\_config\_json\_path) | SSM path to the Docker config JSON | `string` | `null` | no |
576574
| <a name="input_ssm_github_secret_path"></a> [ssm\_github\_secret\_path](#input\_ssm\_github\_secret\_path) | The path in SSM to the GitHub app private key file contents or GitHub PAT token. | `string` | `""` | no |

src/charts/actions-runner/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type: application
1515
# This is the chart version. This version number should be incremented each time you make changes
1616
# to the chart and its templates, including the app version.
1717
# Versions are expected to follow Semantic Versioning (https://semver.org/)
18-
version: 0.3.1
18+
version: 0.3.2
1919

2020
# This chart only deploys Resources for actions-runner-controller, so app version does not really apply.
2121
# We use Resource API version instead.

src/charts/actions-runner/templates/runnerdeployment.yaml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,21 @@ spec:
139139
# to report its status and deregister itself from the runner pool.
140140
- name: RUNNER_GRACEFUL_STOP_TIMEOUT
141141
value: "80"
142+
- name: DISABLE_RUNNER_UPDATE
143+
value: "{{ printf "%v" (not .Values.auto_update_enabled) }}"
142144
{{- with .Values.wait_for_docker_seconds }}
143145
# If Docker is taking too long to start (which is likely due to some other performance issue),
144146
# increase the timeout from the default of 120 seconds.
145147
- name: WAIT_FOR_DOCKER_SECONDS
146148
value: "{{ . }}"
147149
{{- end }}
150+
{{- if $use_tmpfs }}
151+
- name: RUNNER_HOME
152+
value: "/runner-tmpfs"
153+
- name: RUNNER_WORKDIR
154+
value: "/runner-tmpfs/_work"
155+
{{- end }}
156+
148157
# You could reserve nodes for runners by labeling and tainting nodes with
149158
# node-role.kubernetes.io/actions-runner
150159
# and then adding the following to this RunnerDeployment
@@ -206,6 +215,7 @@ spec:
206215
{{- end }}
207216
# dockerdWithinRunnerContainer = false means access to a Docker daemon is provided by a sidecar container.
208217
dockerdWithinRunnerContainer: {{ $use_dind_in_runner }}
218+
dockerEnabled: {{ $use_dind }}
209219
image: {{ .Values.image | quote }}
210220
imagePullPolicy: IfNotPresent
211221
{{- if $use_dockerconfig }}
@@ -217,15 +227,23 @@ spec:
217227
limits:
218228
cpu: {{ .Values.resources.limits.cpu }}
219229
memory: {{ .Values.resources.limits.memory }}
230+
{{- if index .Values.resources.limits "ephemeral-storage" }}
231+
ephemeral-storage: {{ index .Values.resources.limits "ephemeral-storage" }}
232+
{{- else }}
220233
{{- if index .Values.resources.limits "ephemeral_storage" }}
221234
ephemeral-storage: {{ .Values.resources.limits.ephemeral_storage }}
222235
{{- end }}
236+
{{- end }}
223237
requests:
224238
cpu: {{ .Values.resources.requests.cpu }}
225239
memory: {{ .Values.resources.requests.memory }}
240+
{{- if index .Values.resources.requests "ephemeral-storage" }}
241+
ephemeral-storage: {{ index .Values.resources.requests "ephemeral-storage" }}
242+
{{- else }}
226243
{{- if index .Values.resources.requests "ephemeral_storage" }}
227244
ephemeral-storage: {{ .Values.resources.requests.ephemeral_storage }}
228245
{{- end }}
246+
{{- end }}
229247
{{- if and (not $use_dind_in_runner) (or .Values.docker_storage $use_tmpfs) }}
230248
{{- /* dockerVolumeMounts are mounted into the docker sidecar, and ignored if running with dockerdWithinRunnerContainer */}}
231249
dockerVolumeMounts:
@@ -251,14 +269,14 @@ spec:
251269
{{- if $use_tmpfs }}
252270
- mountPath: /tmp
253271
name: tmp
254-
- mountPath: /runner/_work
255-
name: work
272+
- mountPath: /runner-tmpfs
273+
name: runner-tmpfs
256274
{{- end }}
257275
{{- end }}{{/* End of volumeMounts */}}
258276
{{- if or (and $use_dind (or .Values.docker_storage $use_tmpfs)) $use_pvc $use_dockerconfig (not (empty .Values.running_pod_annotations)) }}
259277
volumes:
260278
{{- if $use_tmpfs }}
261-
- name: work
279+
- name: runner-tmpfs
262280
emptyDir:
263281
medium: Memory
264282
- name: tmp

src/main.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ module "actions_runner" {
225225
type = each.value.type
226226
scope = each.value.scope
227227
image = each.value.image
228+
auto_update_enabled = each.value.auto_update_enabled
228229
dind_enabled = each.value.dind_enabled
229230
service_account_role_arn = module.actions_runner_controller.service_account_role_arn
230231
resources = each.value.resources

0 commit comments

Comments
 (0)