diff --git a/.github/workflows/packer-build.yml b/.github/workflows/packer-build.yml index 65db87ec64..2af5371133 100644 --- a/.github/workflows/packer-build.yml +++ b/.github/workflows/packer-build.yml @@ -19,7 +19,7 @@ jobs: image: index.docker.io/hashicorp/packer@sha256:297bbbbbbf3ce9e0431ac1e8f02934b20e1197613f877b55dfdb1ebfd94eb748 # ratchet:index.docker.io/hashicorp/packer:1.8.6 strategy: matrix: - image: ["linux-amzn2", "windows-core-2019", "windows-core-2022", "ubuntu-focal", "ubuntu-jammy", "ubuntu-jammy-arm64"] + image: ["linux-al2023", "windows-core-2019", "windows-core-2022", "ubuntu-focal", "ubuntu-jammy", "ubuntu-jammy-arm64"] defaults: run: working-directory: images/${{ matrix.image }} diff --git a/README.md b/README.md index 8cb61bf508..df7a533c6e 100644 --- a/README.md +++ b/README.md @@ -530,7 +530,7 @@ We welcome any improvement to the standard module to make the default as secure | [instance\_max\_spot\_price](#input\_instance\_max\_spot\_price) | Max price price for spot instances per hour. This variable will be passed to the create fleet as max spot price for the fleet. | `string` | `null` | no | | [instance\_profile\_path](#input\_instance\_profile\_path) | The path that will be added to the instance\_profile, if not set the environment name will be used. | `string` | `null` | no | | [instance\_target\_capacity\_type](#input\_instance\_target\_capacity\_type) | Default lifecycle used for runner instances, can be either `spot` or `on-demand`. | `string` | `"spot"` | no | -| [instance\_types](#input\_instance\_types) | List of instance types for the action runner. Defaults are based on runner\_os (amzn2 for linux and Windows Server Core for win). | `list(string)` |
[| no | +| [instance\_types](#input\_instance\_types) | List of instance types for the action runner. Defaults are based on runner\_os (al2023 for linux and Windows Server Core for win). | `list(string)` |
"m5.large",
"c5.large"
]
[| no | | [job\_queue\_retention\_in\_seconds](#input\_job\_queue\_retention\_in\_seconds) | The number of seconds the job is held in the queue before it is purged. | `number` | `86400` | no | | [key\_name](#input\_key\_name) | Key pair name | `string` | `null` | no | | [kms\_key\_arn](#input\_kms\_key\_arn) | Optional CMK Key ARN to be used for Parameter Store. This key must be in the current account. | `string` | `null` | no | diff --git a/examples/ephemeral/main.tf b/examples/ephemeral/main.tf index 43423861d0..85af868b37 100644 --- a/examples/ephemeral/main.tf +++ b/examples/ephemeral/main.tf @@ -71,7 +71,7 @@ module "runners" { # configure your pre-built AMI # enable_userdata = false - # ami_filter = { name = ["github-runner-amzn2-x86_64-*"], state = ["available"] } + # ami_filter = { name = ["github-runner-al2023-x86_64-*"], state = ["available"] } # data "aws_caller_identity" "current" {} # ami_owners = [data.aws_caller_identity.current.account_id] diff --git a/examples/prebuilt/README.md b/examples/prebuilt/README.md index 71ed53a26d..69d1e7869f 100644 --- a/examples/prebuilt/README.md +++ b/examples/prebuilt/README.md @@ -13,7 +13,7 @@ Steps for the full setup, such as creating a GitHub app can be found in the root | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [ami\_filter](#input\_ami\_filter) | The amis to search. Use the default for the provided amazon linux image, `github-runner-windows-core-2019-*` for the provided Windows image | `string` | `github-runner-amzn2-x86_64-2021*` | no | +| [ami\_filter](#input\_ami\_filter) | The amis to search. Use the default for the provided amazon linux image, `github-runner-windows-core-2019-*` for the provided Windows image | `string` | `github-runner-al2023-x86_64-2023*` | no | | [github\_app\_key\_base64](#input\_github\_app\_key\_base64) | The base64 encoded private key you downloaded from GitHub when creating the app | `string` | | yes | | [github\_app\_id](#input\_github\_app\_id) | The id of the app you created on GitHub | `string` | | yes | | [region](#input\_region) | The target aws region | `string` | `eu-west-1` | no | @@ -52,13 +52,13 @@ You will need to build your image. This example deployment uses the image exampl To use your image in the terraform modules you will need to set some values on the module. -Assuming you have built the `linux-amzn2` image which has a pre-defined AMI name in the following format `github-runner-amzn2-x86_64-YYYYMMDDhhmm` you can use the following values. +Assuming you have built the `linux-al2023` image which has a pre-defined AMI name in the following format `github-runner-al2023-x86_64-YYYYMMDDhhmm` you can use the following values. ```hcl module "runners" { ... # set the name of the ami to use - ami_filter = { name = ["github-runner-amzn2-x86_64-2021*"], state = ["available"] } + ami_filter = { name = ["github-runner-al2023-x86_64-2023*"], state = ["available"] } # provide the owner id of ami_owners = ["
"m5.large",
"c5.large"
]
object({| n/a | yes | | [runner\_os](#input\_runner\_os) | n/a | `string` | `"linux"` | no | diff --git a/examples/prebuilt/variables.tf b/examples/prebuilt/variables.tf index 573533ad5f..424dbddf47 100644 --- a/examples/prebuilt/variables.tf +++ b/examples/prebuilt/variables.tf @@ -14,5 +14,5 @@ variable "runner_os" { variable "ami_name_filter" { type = string - default = "github-runner-amzn2-x86_64-*" + default = "github-runner-al2023-x86_64-*" } diff --git a/images/README.md b/images/README.md index 31e6f9d792..c800b0587e 100644 --- a/images/README.md +++ b/images/README.md @@ -4,14 +4,14 @@ The images inside this folder are pre-built images designed to shorten the boot These images share the same scripting as used in the user-data mechanism in `/modules/runners/templates/`. We use a `templatefile` mechanism to insert the relevant script fragments into the scripts used for provisioning the images. -The examples in `linux-amzn2` and `windows-core-2019` also upload a `start-runner` script that uses the exact same startup process as used in the user-data mechanism. This means that the image created here does not need any extra scripts injected or changes to boot up and connect to GH. +The examples in `linux-al2023` and `windows-core-2019` also upload a `start-runner` script that uses the exact same startup process as used in the user-data mechanism. This means that the image created here does not need any extra scripts injected or changes to boot up and connect to GH. ## Building your own To build these images you first need to install packer. You will also need an amazon account and to have provisioned your credentials for packer to consume. -Assuming you are building the `linux-amzn2` image. Then run the following from within the `linux-amzn2` folder +Assuming you are building the `linux-al2023` image. Then run the following from within the `linux-al2023` folder ```bash packer init . @@ -25,12 +25,12 @@ Your image will then begin to build inside AWS and when finished you will be pro To use your image in the terraform modules you will need to set some values on the module. -Assuming you have built the `linux-amzn2` image which has a pre-defined AMI name in the following format `github-runner-amzn2-x86_64-YYYYMMDDhhmm` you can use the following values. +Assuming you have built the `linux-al2023` image which has a pre-defined AMI name in the following format `github-runner-al2023-x86_64-YYYYMMDDhhmm` you can use the following values. ```hcl # set the name of the ami to use -ami_filter = { name = ["github-runner-amzn2-x86_64-2021*"] } -# provide the owner id of +ami_filter = { name = ["github-runner-al2023-x86_64-2023*"] } +# provide the owner id of ami_owners = ["
id = string
key_base64 = string
})
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)), { state = ["available"] })
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)
ebs_optimized = 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
runner_additional_security_group_ids = optional(list(string), [])
scale_down_schedule_expression = optional(string, "cron(*/5 * * * ? *)")
scale_up_reserved_concurrent_executions = optional(number, 1)
userdata_template = optional(string, null)
enable_jit_config = optional(bool, null)
enable_runner_detailed_monitoring = optional(bool, false)
enable_cloudwatch_agent = optional(bool, true)
cloudwatch_config = optional(string, null)
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
evictionStrategy = optional(string, "oldest_first")
})), [])
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/variables.tf b/modules/multi-runner/variables.tf index cec945838f..4c5cf0e558 100644 --- a/modules/multi-runner/variables.tf +++ b/modules/multi-runner/variables.tf @@ -151,7 +151,7 @@ variable "multi_runner_config" { instance_allocation_strategy: "The allocation strategy for spot instances. AWS recommends to use `capacity-optimized` however the AWS default is `lowest-price`." instance_max_spot_price: "Max price price for spot intances per hour. This variable will be passed to the create fleet as max spot price for the fleet." instance_target_capacity_type: "Default lifecycle used for runner instances, can be either `spot` or `on-demand`." - instance_types: "List of instance types for the action runner. Defaults are based on runner_os (amzn2 for linux and Windows Server Core for win)." + instance_types: "List of instance types for the action runner. Defaults are based on runner_os (al2023 for linux and Windows Server Core for win)." job_queue_retention_in_seconds: "The number of seconds the job is held in the queue before it is purged" minimum_running_time_in_minutes: "The time an ec2 action runner should be running at minimum before terminated if not busy." 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." diff --git a/modules/runners/README.md b/modules/runners/README.md index 32b07a1342..512fb2e48f 100644 --- a/modules/runners/README.md +++ b/modules/runners/README.md @@ -156,7 +156,7 @@ yarn run dist | [instance\_profile\_path](#input\_instance\_profile\_path) | The path that will be added to the instance\_profile, if not set the prefix will be used. | `string` | `null` | no | | [instance\_target\_capacity\_type](#input\_instance\_target\_capacity\_type) | Default lifecyle used runner instances, can be either `spot` or `on-demand`. | `string` | `"spot"` | no | | [instance\_type](#input\_instance\_type) | [DEPRECATED] See instance\_types. | `string` | `"m5.large"` | no | -| [instance\_types](#input\_instance\_types) | List of instance types for the action runner. Defaults are based on runner\_os (amzn2 for linux and Windows Server Core for win). | `list(string)` | `null` | no | +| [instance\_types](#input\_instance\_types) | List of instance types for the action runner. Defaults are based on runner\_os (al2023 for linux and Windows Server Core for win). | `list(string)` | `null` | no | | [key\_name](#input\_key\_name) | Key pair name | `string` | `null` | no | | [kms\_key\_arn](#input\_kms\_key\_arn) | Optional CMK Key ARN to be used for Parameter Store. | `string` | `null` | no | | [lambda\_architecture](#input\_lambda\_architecture) | AWS Lambda architecture. Lambda functions using Graviton processors ('arm64') tend to have better price/performance than 'x86\_64' functions. | `string` | `"arm64"` | no | diff --git a/modules/runners/main.tf b/modules/runners/main.tf index f768033fe7..13cea5d9b8 100644 --- a/modules/runners/main.tf +++ b/modules/runners/main.tf @@ -19,7 +19,7 @@ locals { s3_location_runner_distribution = var.enable_runner_binaries_syncer ? "s3://${var.s3_runner_binaries.id}/${var.s3_runner_binaries.key}" : "" default_ami = { "windows" = { name = ["Windows_Server-2022-English-Full-ECS_Optimized-*"] } - "linux" = var.runner_architecture == "arm64" ? { name = ["amzn2-ami-kernel-5.*-hvm-*-arm64-gp2"] } : { name = ["amzn2-ami-kernel-5.*-hvm-*-x86_64-gp2"] } + "linux" = var.runner_architecture == "arm64" ? { name = ["al2023-ami-2023.*-kernel-6.*-arm64"] } : { name = ["al2023-ami-2023.*-kernel-6.*-x86_64"] } } default_userdata_template = { diff --git a/modules/runners/templates/install-runner.sh b/modules/runners/templates/install-runner.sh index d960d6f45c..f793730fc4 100644 --- a/modules/runners/templates/install-runner.sh +++ b/modules/runners/templates/install-runner.sh @@ -45,9 +45,9 @@ rm -rf $file_name os_id=$(awk -F= '/^ID/{print $2}' /etc/os-release) echo OS: $os_id -# Install libicu60 for arm64 on non-ubuntu -if [[ "$architecture" == "arm64" ]] && [[ ! "$os_id" =~ ^ubuntu.* ]]; then - yum install -y libicu60 +# Install libicu on non-ubuntu +if [[ ! "$os_id" =~ ^ubuntu.* ]]; then + dnf install -y libicu fi # Install dependencies for ubuntu diff --git a/modules/runners/templates/user-data.sh b/modules/runners/templates/user-data.sh index 08465eba97..3de7f41273 100644 --- a/modules/runners/templates/user-data.sh +++ b/modules/runners/templates/user-data.sh @@ -15,14 +15,15 @@ set -x ${pre_install} -yum update -y +dnf upgrade-minimal -y # Install docker -amazon-linux-extras install docker +dnf install -y docker service docker start usermod -a -G docker ec2-user -yum install -y amazon-cloudwatch-agent curl jq git +dnf install -y amazon-cloudwatch-agent jq git +dnf install -y --allowerasing curl user_name=ec2-user diff --git a/modules/runners/variables.tf b/modules/runners/variables.tf index ffe7288e3a..6b910bcae2 100644 --- a/modules/runners/variables.tf +++ b/modules/runners/variables.tf @@ -125,7 +125,7 @@ variable "instance_type" { # tflint-ignore: terraform_unused_declarations } variable "instance_types" { - description = "List of instance types for the action runner. Defaults are based on runner_os (amzn2 for linux and Windows Server Core for win)." + description = "List of instance types for the action runner. Defaults are based on runner_os (al2023 for linux and Windows Server Core for win)." type = list(string) default = null } diff --git a/variables.tf b/variables.tf index 4268314302..fb93db42c7 100644 --- a/variables.tf +++ b/variables.tf @@ -479,7 +479,7 @@ variable "instance_max_spot_price" { } variable "instance_types" { - description = "List of instance types for the action runner. Defaults are based on runner_os (amzn2 for linux and Windows Server Core for win)." + description = "List of instance types for the action runner. Defaults are based on runner_os (al2023 for linux and Windows Server Core for win)." type = list(string) default = ["m5.large", "c5.large"] }
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)), { state = ["available"] })
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
runner_additional_security_group_ids = optional(list(string), [])
scale_down_schedule_expression = optional(string, "cron(*/5 * * * ? *)")
scale_up_reserved_concurrent_executions = optional(number, 1)
userdata_template = optional(string, null)
enable_jit_config = optional(bool, null)
enable_runner_detailed_monitoring = optional(bool, false)
enable_cloudwatch_agent = optional(bool, true)
cloudwatch_config = optional(string, null)
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
evictionStrategy = optional(string, "oldest_first")
})), [])
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
})
}))