diff --git a/README.md b/README.md index cca8f62c49..c0b6721e00 100644 --- a/README.md +++ b/README.md @@ -560,6 +560,7 @@ We welcome any improvement to the standard module to make the default as secure | [runner\_binaries\_syncer\_lambda\_timeout](#input\_runner\_binaries\_syncer\_lambda\_timeout) | Time out of the binaries sync lambda in seconds. | `number` | `300` | no | | [runner\_binaries\_syncer\_lambda\_zip](#input\_runner\_binaries\_syncer\_lambda\_zip) | File location of the binaries sync lambda zip file. | `string` | `null` | no | | [runner\_boot\_time\_in\_minutes](#input\_runner\_boot\_time\_in\_minutes) | The minimum time for an EC2 runner to boot and register as a runner. | `number` | `5` | no | +| [runner\_credit\_specification](#input\_runner\_credit\_specification) | The credit option for CPU usage of a T instance. Can be unset, "standard" or "unlimited". | `string` | `null` | no | | [runner\_ec2\_tags](#input\_runner\_ec2\_tags) | Map of tags that will be added to the launch template instance tag specifications. | `map(string)` | `{}` | no | | [runner\_egress\_rules](#input\_runner\_egress\_rules) | List of egress rules for the GitHub runner instances. |
list(object({|
cidr_blocks = list(string)
ipv6_cidr_blocks = list(string)
prefix_list_ids = list(string)
from_port = number
protocol = string
security_groups = list(string)
self = bool
to_port = number
description = string
}))
[| no | | [runner\_enable\_workflow\_job\_labels\_check\_all](#input\_runner\_enable\_workflow\_job\_labels\_check\_all) | DEPCRECATED: Replaced by `enable_runner_workflow_job_labels_check_all`. | `string` | `null` | no | diff --git a/examples/multi-runner/templates/runner-configs/linux-arm64.yaml b/examples/multi-runner/templates/runner-configs/linux-arm64.yaml index 326543a258..6e4cd2113f 100644 --- a/examples/multi-runner/templates/runner-configs/linux-arm64.yaml +++ b/examples/multi-runner/templates/runner-configs/linux-arm64.yaml @@ -13,6 +13,7 @@ runner_config: runner_extra_labels: amazon runner_name_prefix: amazon-arm64_ enable_ssm_on_runners: true + credit_specification: unlimited instance_types: - t4g.large - c6g.large diff --git a/examples/multi-runner/templates/runner-configs/linux-x64-ubuntu.yaml b/examples/multi-runner/templates/runner-configs/linux-x64-ubuntu.yaml index b864c1cb91..40c30cbdfe 100644 --- a/examples/multi-runner/templates/runner-configs/linux-x64-ubuntu.yaml +++ b/examples/multi-runner/templates/runner-configs/linux-x64-ubuntu.yaml @@ -15,7 +15,9 @@ runner_config: runner_run_as: ubuntu runner_name_prefix: ubuntu-2204-x64_ enable_ssm_on_runners: true + credit_specification: standard instance_types: + - t3a.large - m5ad.large - m5a.large runners_maximum_count: 1 @@ -48,4 +50,4 @@ runner_config: - log_group_name: runner prefix_log_group: true file_path: /opt/actions-runner/_diag/Runner_**.log - log_stream_name: "{instance_id}/runner" \ No newline at end of file + log_stream_name: "{instance_id}/runner" diff --git a/main.tf b/main.tf index d975f063dc..dbb704cadb 100644 --- a/main.tf +++ b/main.tf @@ -224,6 +224,7 @@ module "runners" { egress_rules = var.runner_egress_rules runner_additional_security_group_ids = var.runner_additional_security_group_ids metadata_options = var.runner_metadata_options + credit_specification = var.runner_credit_specification enable_runner_binaries_syncer = var.enable_runner_binaries_syncer lambda_s3_bucket = var.lambda_s3_bucket diff --git a/modules/multi-runner/README.md b/modules/multi-runner/README.md index 29be2aac72..ce599ad8bf 100644 --- a/modules/multi-runner/README.md +++ b/modules/multi-runner/README.md @@ -139,7 +139,7 @@ module "multi-runner" { | [log\_type](#input\_log\_type) | Logging format for lambda logging. Valid values are 'json', 'pretty', 'hidden'. | `string` | `null` | no | | [logging\_kms\_key\_id](#input\_logging\_kms\_key\_id) | Specifies the kms key id to encrypt the logs with | `string` | `null` | no | | [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` | `7` | no | -| [multi\_runner\_config](#input\_multi\_runner\_config) | multi\_runner\_config = {
{
"cidr_blocks": [
"0.0.0.0/0"
],
"description": null,
"from_port": 0,
"ipv6_cidr_blocks": [
"::/0"
],
"prefix_list_ids": null,
"protocol": "-1",
"security_groups": null,
"self": null,
"to_port": 0
}
]
map(object({| n/a | yes | +| [multi\_runner\_config](#input\_multi\_runner\_config) | multi\_runner\_config = {
runner_config = object({
runner_os = string
runner_architecture = string
runner_metadata_options = optional(map(any), {
instance_metadata_tags = "enabled"
http_endpoint = "enabled"
http_tokens = "optional"
http_put_response_hop_limit = 1
})
ami_filter = optional(map(list(string)), null)
ami_owners = optional(list(string), ["amazon"])
ami_id_ssm_parameter_name = optional(string, null)
ami_kms_key_arn = optional(string, "")
create_service_linked_role_spot = optional(bool, false)
delay_webhook_event = optional(number, 30)
disable_runner_autoupdate = optional(bool, false)
enable_ephemeral_runners = optional(bool, false)
enable_job_queued_check = optional(bool, null)
enable_organization_runners = optional(bool, false)
enable_runner_binaries_syncer = optional(bool, true)
enable_ssm_on_runners = optional(bool, false)
enable_userdata = optional(bool, true)
instance_allocation_strategy = optional(string, "lowest-price")
instance_max_spot_price = optional(string, null)
instance_target_capacity_type = optional(string, "spot")
instance_types = list(string)
job_queue_retention_in_seconds = optional(number, 86400)
minimum_running_time_in_minutes = optional(number, null)
pool_runner_owner = optional(string, null)
runner_as_root = optional(bool, false)
runner_boot_time_in_minutes = optional(number, 5)
runner_extra_labels = string
runner_group_name = optional(string, "Default")
runner_name_prefix = optional(string, "")
runner_run_as = optional(string, "ec2-user")
runners_maximum_count = number
scale_down_schedule_expression = optional(string, "cron(*/5 * * * ? *)")
scale_up_reserved_concurrent_executions = optional(number, 1)
userdata_template = optional(string, null)
enable_runner_detailed_monitoring = optional(bool, false)
enable_cloudwatch_agent = optional(bool, true)
userdata_pre_install = optional(string, "")
userdata_post_install = optional(string, "")
runner_ec2_tags = optional(map(string), {})
runner_iam_role_managed_policy_arns = optional(list(string), [])
idle_config = optional(list(object({
cron = string
timeZone = string
idleCount = number
})), [])
runner_log_files = optional(list(object({
log_group_name = string
prefix_log_group = bool
file_path = string
log_stream_name = string
})), null)
block_device_mappings = optional(list(object({
delete_on_termination = bool
device_name = string
encrypted = bool
iops = number
kms_key_id = string
snapshot_id = string
throughput = number
volume_size = number
volume_type = string
})), [{
delete_on_termination = true
device_name = "/dev/xvda"
encrypted = true
iops = null
kms_key_id = null
snapshot_id = null
throughput = null
volume_size = 30
volume_type = "gp3"
}])
pool_config = optional(list(object({
schedule_expression = string
size = number
})), [])
})
matcherConfig = object({
labelMatchers = list(list(string))
exactMatch = optional(bool, false)
})
fifo = optional(bool, false)
redrive_build_queue = optional(object({
enabled = bool
maxReceiveCount = number
}), {
enabled = false
maxReceiveCount = null
})
}))
map(object({| n/a | yes | | [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 | | [pool\_lambda\_timeout](#input\_pool\_lambda\_timeout) | Time out for the pool lambda in seconds. | `number` | `60` | no | | [prefix](#input\_prefix) | The prefix used for naming resources | `string` | `"github-actions"` | no | diff --git a/modules/multi-runner/runners.tf b/modules/multi-runner/runners.tf index 1bcb6cf130..680b627a73 100644 --- a/modules/multi-runner/runners.tf +++ b/modules/multi-runner/runners.tf @@ -51,6 +51,7 @@ module "runners" { egress_rules = var.runner_egress_rules runner_additional_security_group_ids = var.runner_additional_security_group_ids metadata_options = each.value.runner_config.runner_metadata_options + credit_specification = each.value.runner_config.credit_specification enable_runner_binaries_syncer = each.value.runner_config.enable_runner_binaries_syncer lambda_s3_bucket = var.lambda_s3_bucket diff --git a/modules/multi-runner/variables.tf b/modules/multi-runner/variables.tf index f517e142eb..c8751835b2 100644 --- a/modules/multi-runner/variables.tf +++ b/modules/multi-runner/variables.tf @@ -41,6 +41,7 @@ variable "multi_runner_config" { ami_id_ssm_parameter_name = optional(string, null) ami_kms_key_arn = optional(string, "") create_service_linked_role_spot = optional(bool, false) + credit_specification = optional(string, null) delay_webhook_event = optional(number, 30) disable_runner_autoupdate = optional(bool, false) enable_ephemeral_runners = optional(bool, false) @@ -132,6 +133,7 @@ variable "multi_runner_config" { ami_filter: "(Optional) List of maps used to create the AMI filter for the action runner AMI. By default amazon linux 2 is used." ami_owners: "(Optional) The list of owners used to select the AMI of action runner instances." create_service_linked_role_spot: (Optional) create the serviced linked role for spot instances that is required by the scale-up lambda. + credit_specification: "(Optional) The credit specification of the runner instance_type. Can be unset, `standard` or `unlimited`. 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." 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/)" enable_ephemeral_runners: "Enable ephemeral runners, runners will only be used once." diff --git a/modules/runners/README.md b/modules/runners/README.md index 5425a7aee8..f2e9383c55 100644 --- a/modules/runners/README.md +++ b/modules/runners/README.md @@ -132,6 +132,7 @@ yarn run dist | [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`, `throughput`, `kms_key_id`, `snapshot_id`. |
runner_config = object({
runner_os = string
runner_architecture = string
runner_metadata_options = optional(map(any), {
instance_metadata_tags = "enabled"
http_endpoint = "enabled"
http_tokens = "optional"
http_put_response_hop_limit = 1
})
ami_filter = optional(map(list(string)), null)
ami_owners = optional(list(string), ["amazon"])
ami_id_ssm_parameter_name = optional(string, null)
ami_kms_key_arn = optional(string, "")
create_service_linked_role_spot = optional(bool, false)
credit_specification = optional(string, null)
delay_webhook_event = optional(number, 30)
disable_runner_autoupdate = optional(bool, false)
enable_ephemeral_runners = optional(bool, false)
enable_job_queued_check = optional(bool, null)
enable_organization_runners = optional(bool, false)
enable_runner_binaries_syncer = optional(bool, true)
enable_ssm_on_runners = optional(bool, false)
enable_userdata = optional(bool, true)
instance_allocation_strategy = optional(string, "lowest-price")
instance_max_spot_price = optional(string, null)
instance_target_capacity_type = optional(string, "spot")
instance_types = list(string)
job_queue_retention_in_seconds = optional(number, 86400)
minimum_running_time_in_minutes = optional(number, null)
pool_runner_owner = optional(string, null)
runner_as_root = optional(bool, false)
runner_boot_time_in_minutes = optional(number, 5)
runner_extra_labels = string
runner_group_name = optional(string, "Default")
runner_name_prefix = optional(string, "")
runner_run_as = optional(string, "ec2-user")
runners_maximum_count = number
scale_down_schedule_expression = optional(string, "cron(*/5 * * * ? *)")
scale_up_reserved_concurrent_executions = optional(number, 1)
userdata_template = optional(string, null)
enable_runner_detailed_monitoring = optional(bool, false)
enable_cloudwatch_agent = optional(bool, true)
userdata_pre_install = optional(string, "")
userdata_post_install = optional(string, "")
runner_ec2_tags = optional(map(string), {})
runner_iam_role_managed_policy_arns = optional(list(string), [])
idle_config = optional(list(object({
cron = string
timeZone = string
idleCount = number
})), [])
runner_log_files = optional(list(object({
log_group_name = string
prefix_log_group = bool
file_path = string
log_stream_name = string
})), null)
block_device_mappings = optional(list(object({
delete_on_termination = bool
device_name = string
encrypted = bool
iops = number
kms_key_id = string
snapshot_id = string
throughput = number
volume_size = number
volume_type = string
})), [{
delete_on_termination = true
device_name = "/dev/xvda"
encrypted = true
iops = null
kms_key_id = null
snapshot_id = null
throughput = null
volume_size = 30
volume_type = "gp3"
}])
pool_config = optional(list(object({
schedule_expression = string
size = number
})), [])
})
matcherConfig = object({
labelMatchers = list(list(string))
exactMatch = optional(bool, false)
})
fifo = optional(bool, false)
redrive_build_queue = optional(object({
enabled = bool
maxReceiveCount = number
}), {
enabled = false
maxReceiveCount = null
})
}))
list(object({|
delete_on_termination = optional(bool, true)
device_name = optional(string, "/dev/xvda")
encrypted = optional(bool, true)
iops = optional(number)
kms_key_id = optional(string)
snapshot_id = optional(string)
throughput = optional(number)
volume_size = number
volume_type = optional(string, "gp3")
}))
[| no | | [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 | | [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 | +| [credit\_specification](#input\_credit\_specification) | The credit option for CPU usage of a T instance. Can be unset, "standard" or "unlimited". | `string` | `null` | no | | [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 | | [egress\_rules](#input\_egress\_rules) | List of egress rules for the GitHub runner instances. |
{
"volume_size": 30
}
]
list(object({|
cidr_blocks = list(string)
ipv6_cidr_blocks = list(string)
prefix_list_ids = list(string)
from_port = number
protocol = string
security_groups = list(string)
self = bool
to_port = number
description = string
}))
[| no | | [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 | diff --git a/modules/runners/main.tf b/modules/runners/main.tf index eedfd53b09..0d3fc24668 100644 --- a/modules/runners/main.tf +++ b/modules/runners/main.tf @@ -97,6 +97,13 @@ resource "aws_launch_template" "runner" { } } + dynamic "credit_specification" { + for_each = var.credit_specification != null ? [var.credit_specification] : [] + content { + cpu_credits = credit_specification.value + } + } + monitoring { enabled = var.enable_runner_detailed_monitoring } diff --git a/modules/runners/variables.tf b/modules/runners/variables.tf index 85b869943d..0a789ff877 100644 --- a/modules/runners/variables.tf +++ b/modules/runners/variables.tf @@ -594,3 +594,14 @@ variable "lambda_tracing_mode" { type = string default = null } + +variable "credit_specification" { + description = "The credit option for CPU usage of a T instance. Can be unset, \"standard\" or \"unlimited\"." + type = string + default = null + + validation { + condition = var.credit_specification == null ? true : contains(["standard", "unlimited"], var.credit_specification) + error_message = "Valid values for credit_specification are (null, \"standard\", \"unlimited\")." + } +} diff --git a/variables.tf b/variables.tf index ac8c8e9e4b..580563a5c0 100644 --- a/variables.tf +++ b/variables.tf @@ -777,3 +777,14 @@ variable "lambda_tracing_mode" { type = string default = null } + +variable "runner_credit_specification" { + description = "The credit option for CPU usage of a T instance. Can be unset, \"standard\" or \"unlimited\"." + type = string + default = null + + validation { + condition = var.runner_credit_specification == null ? true : contains(["standard", "unlimited"], var.runner_credit_specification) + error_message = "Valid values for runner_credit_specification are (null, \"standard\", \"unlimited\")." + } +}
{
"cidr_blocks": [
"0.0.0.0/0"
],
"description": null,
"from_port": 0,
"ipv6_cidr_blocks": [
"::/0"
],
"prefix_list_ids": null,
"protocol": "-1",
"security_groups": null,
"self": null,
"to_port": 0
}
]