From 9f7d32d7edd724ee015a053dc1914a4b871aafe1 Mon Sep 17 00:00:00 2001 From: Niek Palm Date: Mon, 15 Aug 2022 20:20:33 +0200 Subject: [PATCH] feat: Add option to disable lambda to sync runner binaries (#2314) - Added variable enable_runner_binaries_syncer to disable syncer - Refactored the internals of the runner moduel. When using the internal modules directoy be-aware of breaking changes, you have to set s3_runner_binaries. - Updated example for pre-build AMI to disable the syncer module. - Narrowed down the bucket permission of the runner to only the relevant distribution. Co-authored-by: GuptaNavdeep1983 --- .editorconfig | 11 +++++++++++ .vscode/extensions.json | 1 - README.md | 4 ++-- examples/prebuilt/README.md | 7 +++++-- examples/prebuilt/main.tf | 6 +++++- examples/prebuilt/outputs.tf | 6 ------ images/linux-amzn2/github_agent.linux.pkr.hcl | 2 +- main.tf | 11 ++++++++--- modules/runners/README.md | 4 ++-- modules/runners/main.tf | 3 +-- modules/runners/policies-runner.tf | 4 +++- .../runners/policies/instance-s3-policy.json | 2 +- modules/runners/variables.tf | 18 +++++++++++------- outputs.tf | 12 ++++++------ variables.tf | 8 +++++++- 15 files changed, 63 insertions(+), 36 deletions(-) diff --git a/.editorconfig b/.editorconfig index 270106b1fa..a26201409e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,2 +1,13 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + [*] +indent_style = space +indent_size = 2 +tab_width = 2 end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.vscode/extensions.json b/.vscode/extensions.json index cb3fc99278..68a2778682 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -5,7 +5,6 @@ // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp "editorconfig.editorconfig", "yzhang.markdown-all-in-one", - "sonarsource.sonarlint-vscode", "hashicorp.terraform" ] } \ No newline at end of file diff --git a/README.md b/README.md index f69f093843..19cf7fa98e 100644 --- a/README.md +++ b/README.md @@ -309,8 +309,7 @@ The example for [ephemeral runners](./examples/ephemeral) is based on the [defau ### Prebuilt Images -This module also allows you to run agents from a prebuilt AMI to gain faster startup times. You can find more information in [the image README.md](/images/README.md) - +This module also allows you to run agents from a prebuilt AMI to gain faster startup times. You can find more information in [the image README.md](/images/README.md). When the GitHub runner is part of the AMI you can disable the binary syncer by setting `enable_runner_binaries_syncer = false`. ## Examples @@ -407,6 +406,7 @@ In case the setup does not work as intended follow the trace of events: | [enable\_job\_queued\_check](#input\_enable\_job\_queued\_check) | Only scale if the job event received by the scale up lambda is is in the state queued. By default enabled for non ephemeral runners and disabled for ephemeral. Set this variable to overwrite the default behavior. | `bool` | `null` | no | | [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 | | [enable\_organization\_runners](#input\_enable\_organization\_runners) | Register runners to organization, instead of repo level | `bool` | `false` | no | +| [enable\_runner\_binaries\_syncer](#input\_enable\_runner\_binaries\_syncer) | Option to disable the lambda to sync GitHub runner distribution, usefull when using a pre-build AMI. | `bool` | `true` | no | | [enable\_runner\_detailed\_monitoring](#input\_enable\_runner\_detailed\_monitoring) | Should detailed monitoring be enabled for the runner. Set this to true if you want to use detailed monitoring. See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-cloudwatch-new.html for details. | `bool` | `false` | no | | [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 | | [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 | diff --git a/examples/prebuilt/README.md b/examples/prebuilt/README.md index e4e51938c7..de0addf46f 100644 --- a/examples/prebuilt/README.md +++ b/examples/prebuilt/README.md @@ -1,6 +1,9 @@ # Action runners deployment with prebuilt image -This module shows how to create GitHub action runners using a prebuilt AMI for the runners +This module shows how to create GitHub action runners using a prebuilt AMI for the runners. + +- Configured to run with org level runners. +- GitHub runner binary syncer is not deployed. ## Usages @@ -56,7 +59,7 @@ module "runners" { ... # set the name of the ami to use ami_filter = { name = ["github-runner-amzn2-x86_64-2021*"] } - # provide the owner id of + # provide the owner id of ami_owners = [""] enabled_userdata = false diff --git a/examples/prebuilt/main.tf b/examples/prebuilt/main.tf index 9134dfc464..7b135555b1 100644 --- a/examples/prebuilt/main.tf +++ b/examples/prebuilt/main.tf @@ -15,7 +15,8 @@ module "runners" { vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.private_subnets - prefix = local.environment + prefix = local.environment + enable_organization_runners = false github_app = { key_base64 = var.github_app_key_base64 @@ -36,6 +37,9 @@ module "runners" { ami_filter = { name = [var.ami_name_filter] } ami_owners = [data.aws_caller_identity.current.account_id] + # disable binary syncer since github agent is already installed in the AMI. + enable_runner_binaries_syncer = false + # enable access to the runners via SSM enable_ssm_on_runners = true diff --git a/examples/prebuilt/outputs.tf b/examples/prebuilt/outputs.tf index c50214f566..a922cb4f5c 100644 --- a/examples/prebuilt/outputs.tf +++ b/examples/prebuilt/outputs.tf @@ -1,9 +1,3 @@ -output "runners" { - value = { - lambda_syncer_name = module.runners.binaries_syncer.lambda.function_name - } -} - output "webhook_endpoint" { value = module.runners.webhook.endpoint } diff --git a/images/linux-amzn2/github_agent.linux.pkr.hcl b/images/linux-amzn2/github_agent.linux.pkr.hcl index 2c7a92f04d..54ef6664f6 100644 --- a/images/linux-amzn2/github_agent.linux.pkr.hcl +++ b/images/linux-amzn2/github_agent.linux.pkr.hcl @@ -10,7 +10,7 @@ packer { variable "runner_version" { description = "The version (no v prefix) of the runner software to install https://github.com/actions/runner/releases" type = string - default = "2.286.1" + default = "2.295.0" } variable "region" { diff --git a/main.tf b/main.tf index 70b4d4d111..3a3525bd3b 100644 --- a/main.tf +++ b/main.tf @@ -3,7 +3,6 @@ locals { "ghr:environment" = var.prefix }) - s3_action_runner_url = "s3://${module.runner_binaries.bucket.id}/${module.runner_binaries.runner_distribution_object_key}" github_app_parameters = { id = module.ssm.parameters.github_app_id key_base64 = module.ssm.parameters.github_app_key_base64 @@ -134,8 +133,11 @@ module "runners" { prefix = var.prefix tags = local.tags - s3_bucket_runner_binaries = module.runner_binaries.bucket - s3_location_runner_binaries = local.s3_action_runner_url + s3_runner_binaries = var.enable_runner_binaries_syncer ? { + arn = module.runner_binaries[0].bucket.arn + id = module.runner_binaries[0].bucket.id + key = module.runner_binaries[0].runner_distribution_object_key + } : null runner_os = var.runner_os instance_types = var.instance_types @@ -169,6 +171,7 @@ module "runners" { runner_additional_security_group_ids = var.runner_additional_security_group_ids metadata_options = var.runner_metadata_options + enable_runner_binaries_syncer = var.enable_runner_binaries_syncer lambda_s3_bucket = var.lambda_s3_bucket runners_lambda_s3_key = var.runners_lambda_s3_key runners_lambda_s3_object_version = var.runners_lambda_s3_object_version @@ -218,6 +221,8 @@ module "runners" { } module "runner_binaries" { + count = var.enable_runner_binaries_syncer ? 1 : 0 + source = "./modules/runner-binaries-syncer" aws_region = var.aws_region diff --git a/modules/runners/README.md b/modules/runners/README.md index 1778f34269..6fb103555a 100644 --- a/modules/runners/README.md +++ b/modules/runners/README.md @@ -127,6 +127,7 @@ yarn run dist | [enable\_job\_queued\_check](#input\_enable\_job\_queued\_check) | Only scale if the job event received by the scale up lambda is is in the state queued. By default enabled for non ephemeral runners and disabled for ephemeral. Set this variable to overwrite the default behavior. | `bool` | `null` | no | | [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 | | [enable\_organization\_runners](#input\_enable\_organization\_runners) | n/a | `bool` | n/a | yes | +| [enable\_runner\_binaries\_syncer](#input\_enable\_runner\_binaries\_syncer) | Option to disable the lambda to sync GitHub runner distribution, usefull when using a pre-build AMI. | `bool` | `true` | no | | [enable\_runner\_detailed\_monitoring](#input\_enable\_runner\_detailed\_monitoring) | Enable detailed monitoring for runners | `bool` | `false` | no | | [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 | | [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 | @@ -180,8 +181,7 @@ yarn run dist | [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 | | [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 | | [runners\_maximum\_count](#input\_runners\_maximum\_count) | The maximum number of runners that will be created. | `number` | `3` | no | -| [s3\_bucket\_runner\_binaries](#input\_s3\_bucket\_runner\_binaries) | n/a |
object({
arn = string
})
| n/a | yes | -| [s3\_location\_runner\_binaries](#input\_s3\_location\_runner\_binaries) | S3 location of runner distribution. | `string` | n/a | yes | +| [s3\_runner\_binaries](#input\_s3\_runner\_binaries) | Bucket details for cached GitHub binary. |
object({
arn = string
id = string
key = string
})
| n/a | yes | | [scale\_down\_schedule\_expression](#input\_scale\_down\_schedule\_expression) | Scheduler expression to check every x for scale down. | `string` | `"cron(*/5 * * * ? *)"` | no | | [scale\_up\_reserved\_concurrent\_executions](#input\_scale\_up\_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 | | [sqs\_build\_queue](#input\_sqs\_build\_queue) | SQS queue to consume accepted build events. |
object({
arn = string
})
| n/a | yes | diff --git a/modules/runners/main.tf b/modules/runners/main.tf index cec1d086c7..7fea4e8940 100644 --- a/modules/runners/main.tf +++ b/modules/runners/main.tf @@ -122,11 +122,10 @@ resource "aws_launch_template" "runner" { ) } - user_data = var.enabled_userdata ? base64encode(templatefile(local.userdata_template, { pre_install = var.userdata_pre_install install_runner = templatefile(local.userdata_install_runner[var.runner_os], { - S3_LOCATION_RUNNER_DISTRIBUTION = var.s3_location_runner_binaries + S3_LOCATION_RUNNER_DISTRIBUTION = var.enable_runner_binaries_syncer ? "s3://${var.s3_runner_binaries.id}/${var.s3_runner_binaries.key}" : "" RUNNER_ARCHITECTURE = var.runner_architecture }) post_install = var.userdata_post_install diff --git a/modules/runners/policies-runner.tf b/modules/runners/policies-runner.tf index 5ba9004b14..49f6b903de 100644 --- a/modules/runners/policies-runner.tf +++ b/modules/runners/policies-runner.tf @@ -33,11 +33,13 @@ resource "aws_iam_role_policy" "ssm_parameters" { } resource "aws_iam_role_policy" "dist_bucket" { + count = var.enable_runner_binaries_syncer ? 1 : 0 + name = "distribution-bucket" role = aws_iam_role.runner.name policy = templatefile("${path.module}/policies/instance-s3-policy.json", { - s3_arn = var.s3_bucket_runner_binaries.arn + s3_arn = "${var.s3_runner_binaries.arn}/${var.s3_runner_binaries.key}" } ) } diff --git a/modules/runners/policies/instance-s3-policy.json b/modules/runners/policies/instance-s3-policy.json index 68d21ebce6..65d8f84b22 100644 --- a/modules/runners/policies/instance-s3-policy.json +++ b/modules/runners/policies/instance-s3-policy.json @@ -5,7 +5,7 @@ "Sid": "githubActionDist", "Effect": "Allow", "Action": ["s3:GetObject", "s3:GetObjectAcl"], - "Resource": ["${s3_arn}/*"] + "Resource": ["${s3_arn}"] } ] } diff --git a/modules/runners/variables.tf b/modules/runners/variables.tf index ed82d4cbf3..60c1d25e62 100644 --- a/modules/runners/variables.tf +++ b/modules/runners/variables.tf @@ -46,17 +46,15 @@ variable "prefix" { default = "github-actions" } -variable "s3_bucket_runner_binaries" { +variable "s3_runner_binaries" { + description = "Bucket details for cached GitHub binary." type = object({ arn = string + id = string + key = string }) } -variable "s3_location_runner_binaries" { - description = "S3 location of runner distribution." - type = string -} - variable "block_device_mappings" { description = "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`." type = list(object({ @@ -566,4 +564,10 @@ variable "lambda_architecture" { condition = contains(["arm64", "x86_64"], var.lambda_architecture) error_message = "`lambda_architecture` value is not valid, valid values are: `arm64` and `x86_64`." } -} \ No newline at end of file +} + +variable "enable_runner_binaries_syncer" { + description = "Option to disable the lambda to sync GitHub runner distribution, usefull when using a pre-build AMI." + type = bool + default = true +} diff --git a/outputs.tf b/outputs.tf index d72f9acc93..70e1759247 100644 --- a/outputs.tf +++ b/outputs.tf @@ -14,12 +14,12 @@ output "runners" { } output "binaries_syncer" { - value = { - lambda = module.runner_binaries.lambda - lambda_role = module.runner_binaries.lambda_role - location = local.s3_action_runner_url - bucket = module.runner_binaries.bucket - } + value = var.enable_runner_binaries_syncer ? { + lambda = module.runner_binaries[0].lambda + lambda_role = module.runner_binaries[0].lambda_role + location = "s3://${module.runner_binaries[0].bucket.id}/module.runner_binaries[0].bucket.key" + bucket = module.runner_binaries[0].bucket + } : null } output "webhook" { diff --git a/variables.tf b/variables.tf index fc54081b92..7c45e06179 100644 --- a/variables.tf +++ b/variables.tf @@ -662,4 +662,10 @@ variable "lambda_architecture" { condition = contains(["arm64", "x86_64"], var.lambda_architecture) error_message = "`lambda_architecture` value is not valid, valid values are: `arm64` and `x86_64`." } -} \ No newline at end of file +} + +variable "enable_runner_binaries_syncer" { + description = "Option to disable the lambda to sync GitHub runner distribution, usefull when using a pre-build AMI." + type = bool + default = true +}