From 499c7a19ed4dcbf567e0c8173f5a71cd8c9b7dab Mon Sep 17 00:00:00 2001 From: AppliNH Date: Mon, 6 Jan 2025 10:40:06 +0100 Subject: [PATCH 01/24] feat(ssm): condition ssm parameters creation to a new variable to avoid having secrets in state --- main.tf | 17 ++++++++----- modules/multi-runner/main.tf | 11 ++++++--- modules/multi-runner/outputs.tf | 2 +- modules/multi-runner/ssm.tf | 4 ++-- modules/multi-runner/variables.tf | 40 ++++++++++++++++++++++++++++--- modules/multi-runner/webhook.tf | 2 +- outputs.tf | 2 +- variables.tf | 38 ++++++++++++++++++++++++++--- 8 files changed, 96 insertions(+), 20 deletions(-) diff --git a/main.tf b/main.tf index 3f3c9808b4..a2923b544b 100644 --- a/main.tf +++ b/main.tf @@ -3,9 +3,14 @@ locals { "ghr:environment" = var.prefix }) - github_app_parameters = { - id = module.ssm.parameters.github_app_id - key_base64 = module.ssm.parameters.github_app_key_base64 + github_app_parameters = var.create_ssm_parameters_github_app ? { + id = module.ssm[0].parameters.github_app_id + key_base64 = module.ssm[0].parameters.github_app_key_base64 + webhook_secret = module.ssm[0].parameters.github_app_webhook_secret + } : { + id = var.github_app_ssm_parameters.id + key_base64 = var.github_app_ssm_parameters.key_base64 + webhook_secret = var.github_app_ssm_parameters.webhook_secret } default_runner_labels = distinct(concat(["self-hosted", var.runner_os, var.runner_architecture])) @@ -87,8 +92,8 @@ resource "aws_sqs_queue" "queued_builds_dlq" { } module "ssm" { - source = "./modules/ssm" - + source = "./modules/ssm" + count = var.create_ssm_parameters_github_app ? 1 : 0 kms_key_arn = var.kms_key_arn path_prefix = "${local.ssm_root_path}/${var.ssm_paths.app}" github_app = var.github_app @@ -120,7 +125,7 @@ module "webhook" { matcher_config_parameter_store_tier = var.matcher_config_parameter_store_tier github_app_parameters = { - webhook_secret = module.ssm.parameters.github_app_webhook_secret + webhook_secret = local.github_app_parameters.webhook_secret } lambda_s3_bucket = var.lambda_s3_bucket diff --git a/modules/multi-runner/main.tf b/modules/multi-runner/main.tf index 22ec0df3ba..b3e598d28c 100644 --- a/modules/multi-runner/main.tf +++ b/modules/multi-runner/main.tf @@ -3,9 +3,14 @@ locals { "ghr:environment" = var.prefix }) - github_app_parameters = { - id = module.ssm.parameters.github_app_id - key_base64 = module.ssm.parameters.github_app_key_base64 + github_app_parameters = var.create_ssm_parameters_github_app ? { + id = module.ssm[0].parameters.github_app_id + key_base64 = module.ssm[0].parameters.github_app_key_base64 + webhook_secret = module.ssm[0].parameters.github_app_webhook_secret + } : { + id = var.github_app_ssm_parameters.id + key_base64 = var.github_app_ssm_parameters.key_base64 + webhook_secret = var.github_app_ssm_parameters.webhook_secret } runner_extra_labels = { for k, v in var.multi_runner_config : k => sort(setunion(flatten(v.matcherConfig.labelMatchers), compact(v.runner_config.runner_extra_labels))) } diff --git a/modules/multi-runner/outputs.tf b/modules/multi-runner/outputs.tf index 42758c0652..10ab21761c 100644 --- a/modules/multi-runner/outputs.tf +++ b/modules/multi-runner/outputs.tf @@ -45,7 +45,7 @@ output "webhook" { } output "ssm_parameters" { - value = module.ssm.parameters + value = var.create_ssm_parameters_github_app ? module.ssm[0].parameters : var.github_app_ssm_parameters } output "instance_termination_watcher" { diff --git a/modules/multi-runner/ssm.tf b/modules/multi-runner/ssm.tf index 6b2591f465..562d2fa5de 100644 --- a/modules/multi-runner/ssm.tf +++ b/modules/multi-runner/ssm.tf @@ -1,6 +1,6 @@ module "ssm" { - source = "../ssm" - + source = "../ssm" + count = var.create_ssm_parameters_github_app ? 1 : 0 kms_key_arn = var.kms_key_arn path_prefix = "${local.ssm_root_path}/${var.ssm_paths.app}" github_app = var.github_app diff --git a/modules/multi-runner/variables.tf b/modules/multi-runner/variables.tf index f962d1ea8c..bf2de5fd3c 100644 --- a/modules/multi-runner/variables.tf +++ b/modules/multi-runner/variables.tf @@ -1,12 +1,34 @@ variable "github_app" { description = "GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`)." type = object({ - key_base64 = string - id = string - webhook_secret = string + key_base64 = optional(string) + id = optional(string) + webhook_secret = optional(string) }) + default = {} +} + + +variable "github_app_ssm_parameters" { + description = "If you opt to create the SSM parameters yourself (see create_ssm_parameters_github_app), you need to provide name and arn here." + type = object({ + key_base64 = optional(object({ + arn = string + name = string + })) + id = optional(object({ + arn = string + name = string + })) + webhook_secret = optional(object({ + arn = string + name = string + })) + }) + default = {} } + variable "prefix" { description = "The prefix used for naming resources" type = string @@ -671,3 +693,15 @@ variable "eventbridge" { default = {} } + +variable "create_ssm_parameters_github_app" { + description = < Date: Mon, 6 Jan 2025 10:40:31 +0100 Subject: [PATCH 02/24] docs(examples): add a new example to use manual ssm parameters option --- .../manual-ssm-parameters/.terraform.lock.hcl | 85 +++++++++ examples/manual-ssm-parameters/README.md | 77 ++++++++ examples/manual-ssm-parameters/main.tf | 164 ++++++++++++++++++ examples/manual-ssm-parameters/outputs.tf | 15 ++ examples/manual-ssm-parameters/providers.tf | 9 + examples/manual-ssm-parameters/variables.tf | 32 ++++ examples/manual-ssm-parameters/versions.tf | 17 ++ 7 files changed, 399 insertions(+) create mode 100644 examples/manual-ssm-parameters/.terraform.lock.hcl create mode 100644 examples/manual-ssm-parameters/README.md create mode 100644 examples/manual-ssm-parameters/main.tf create mode 100644 examples/manual-ssm-parameters/outputs.tf create mode 100644 examples/manual-ssm-parameters/providers.tf create mode 100644 examples/manual-ssm-parameters/variables.tf create mode 100644 examples/manual-ssm-parameters/versions.tf diff --git a/examples/manual-ssm-parameters/.terraform.lock.hcl b/examples/manual-ssm-parameters/.terraform.lock.hcl new file mode 100644 index 0000000000..045fb7350a --- /dev/null +++ b/examples/manual-ssm-parameters/.terraform.lock.hcl @@ -0,0 +1,85 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.82.1" + constraints = ">= 5.0.0, ~> 5.0, ~> 5.27" + hashes = [ + "h1:QTOtDMehUfiD3wDbbDuXYuTqGgLDkKK9Agkd5NCUEic=", + "zh:0fde8533282973f1f5d33b2c4f82d962a2c78860d39b42ac20a9ce399f06f62c", + "zh:1fd1a252bffe91668f35be8eac4e0a980f022120254eae1674c3c05049aff88a", + "zh:31bbd380cd7d74bf9a8c961fc64da4222bed40ffbdb27b011e637fa8b2d33641", + "zh:333ee400cf6f62fa199dc1270bf8efac6ffe56659f86918070b8351b8636e03b", + "zh:42ea9fee0a152d344d548eab43583299a13bcd73fae9e53e7e1a708720ac1315", + "zh:4b78f25a8cda3316eb56aa01909a403ec2f325a2eb0512c9a73966068c26cf29", + "zh:5e9cf9a275eda8f7940a41e32abe0b92ba76b5744def4af5124b343b5f33eb94", + "zh:6a46c8630c16b9e1338c2daed6006118db951420108b58b8b886403c69317439", + "zh:6efe11cf1a01f98a8d8043cdcd8c0ee5fe93a0e582c2b69ebb73ea073f5068c3", + "zh:88ab5c768c7d8133dab94eff48071e764424ad2b7cfeee5abe6d5bb16e4b85c6", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:a614beb312574342b27dbc34d65b450997f63fa3e948d0d30f441e4f69337380", + "zh:c1f486e27130610a9b64cacb0bd928009c433d62b3be515488185e6467b4aa1f", + "zh:dccd166e89e1a02e7ce658df3c42d040edec4b09c6f7906aa5743938518148b1", + "zh:e75a3ae0fb42b7ea5a0bb5dffd8f8468004c9700fcc934eb04c264fda2ba9984", + ] +} + +provider "registry.terraform.io/hashicorp/local" { + version = "2.5.2" + constraints = "~> 2.0" + hashes = [ + "h1:IyFbOIO6mhikFNL/2h1iZJ6kyN3U00jgkpCLUCThAfE=", + "zh:136299545178ce281c56f36965bf91c35407c11897f7082b3b983d86cb79b511", + "zh:3b4486858aa9cb8163378722b642c57c529b6c64bfbfc9461d940a84cd66ebea", + "zh:4855ee628ead847741aa4f4fc9bed50cfdbf197f2912775dd9fe7bc43fa077c0", + "zh:4b8cd2583d1edcac4011caafe8afb7a95e8110a607a1d5fb87d921178074a69b", + "zh:52084ddaff8c8cd3f9e7bcb7ce4dc1eab00602912c96da43c29b4762dc376038", + "zh:71562d330d3f92d79b2952ffdda0dad167e952e46200c767dd30c6af8d7c0ed3", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:805f81ade06ff68fa8b908d31892eaed5c180ae031c77ad35f82cb7a74b97cf4", + "zh:8b6b3ebeaaa8e38dd04e56996abe80db9be6f4c1df75ac3cccc77642899bd464", + "zh:ad07750576b99248037b897de71113cc19b1a8d0bc235eb99173cc83d0de3b1b", + "zh:b9f1c3bfadb74068f5c205292badb0661e17ac05eb23bfe8bd809691e4583d0e", + "zh:cc4cbcd67414fefb111c1bf7ab0bc4beb8c0b553d01719ad17de9a047adff4d1", + ] +} + +provider "registry.terraform.io/hashicorp/null" { + version = "3.2.3" + constraints = "~> 3.0, ~> 3.2" + hashes = [ + "h1:I0Um8UkrMUb81Fxq/dxbr3HLP2cecTH2WMJiwKSrwQY=", + "zh:22d062e5278d872fe7aed834f5577ba0a5afe34a3bdac2b81f828d8d3e6706d2", + "zh:23dead00493ad863729495dc212fd6c29b8293e707b055ce5ba21ee453ce552d", + "zh:28299accf21763ca1ca144d8f660688d7c2ad0b105b7202554ca60b02a3856d3", + "zh:55c9e8a9ac25a7652df8c51a8a9a422bd67d784061b1de2dc9fe6c3cb4e77f2f", + "zh:756586535d11698a216291c06b9ed8a5cc6a4ec43eee1ee09ecd5c6a9e297ac1", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:9d5eea62fdb587eeb96a8c4d782459f4e6b73baeece4d04b4a40e44faaee9301", + "zh:a6355f596a3fb8fc85c2fb054ab14e722991533f87f928e7169a486462c74670", + "zh:b5a65a789cff4ada58a5baffc76cb9767dc26ec6b45c00d2ec8b1b027f6db4ed", + "zh:db5ab669cf11d0e9f81dc380a6fdfcac437aea3d69109c7aef1a5426639d2d65", + "zh:de655d251c470197bcbb5ac45d289595295acb8f829f6c781d4a75c8c8b7c7dd", + "zh:f5c68199f2e6076bce92a12230434782bf768103a427e9bb9abee99b116af7b5", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.6.3" + constraints = "~> 3.0" + hashes = [ + "h1:zG9uFP8l9u+yGZZvi5Te7PV62j50azpgwPunq2vTm1E=", + "zh:04ceb65210251339f07cd4611885d242cd4d0c7306e86dda9785396807c00451", + "zh:448f56199f3e99ff75d5c0afacae867ee795e4dfda6cb5f8e3b2a72ec3583dd8", + "zh:4b4c11ccfba7319e901df2dac836b1ae8f12185e37249e8d870ee10bb87a13fe", + "zh:4fa45c44c0de582c2edb8a2e054f55124520c16a39b2dfc0355929063b6395b1", + "zh:588508280501a06259e023b0695f6a18149a3816d259655c424d068982cbdd36", + "zh:737c4d99a87d2a4d1ac0a54a73d2cb62974ccb2edbd234f333abd079a32ebc9e", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:a357ab512e5ebc6d1fda1382503109766e21bbfdfaa9ccda43d313c122069b30", + "zh:c51bfb15e7d52cc1a2eaec2a903ac2aff15d162c172b1b4c17675190e8147615", + "zh:e0951ee6fa9df90433728b96381fb867e3db98f66f735e0c3e24f8f16903f0ad", + "zh:e3cdcb4e73740621dabd82ee6a37d6cfce7fee2a03d8074df65086760f5cf556", + "zh:eff58323099f1bd9a0bec7cb04f717e7f1b2774c7d612bf7581797e1622613a0", + ] +} diff --git a/examples/manual-ssm-parameters/README.md b/examples/manual-ssm-parameters/README.md new file mode 100644 index 0000000000..be566433e1 --- /dev/null +++ b/examples/manual-ssm-parameters/README.md @@ -0,0 +1,77 @@ +# Amazon Linux X64 (default) + +This module shows how to create GitHub action runners. Lambda release will be downloaded from GitHub. + +The only difference compared to [`default`](../default/README.md) is that you need to create SSM parameters manually so their values are not stored in the state (see `create_ssm_parameters_github_app` variable). + +## Usages + +Before all, manually create the SSM parameters for the GitHub App ID, base64-encoded private key and webhook secret. Then refer their name and arn through the [`github_app_ssm_parameters` variable](./variables.tf). + +Steps for the full setup, such as creating a GitHub app can be found in the root module's [README](https://github.com/philips-labs/terraform-aws-github-runner). First download the Lambda releases from GitHub. Alternatively you can build the lambdas locally with Node or Docker, there is a simple build script in `/.ci/build.sh`. In the `main.tf` you can simply remove the location of the lambda zip files, the default location will work in this case. + +> The default example assumes local built lambda's available. Ensure you have built the lambda's. Alternativly you can downlowd the lambda's. The version needs to be set to a GitHub release version, see https://github.com/philips-labs/terraform-aws-github-runner/releases + +```bash +cd ../lambdas-download +terraform init +terraform apply -var=module_version= +cd - +``` + +Before running Terraform, ensure the GitHub app is configured. See the [configuration details](https://github.com/philips-labs/terraform-aws-github-runner#usages) for more details. + +```bash +terraform init +terraform apply +``` + +The example will try to update the webhook of your GitHub. In case the update fails the apply will not fail. You can receive the webhook details by running: + +```bash +terraform output -raw webhook_secret +``` + + + +## Requirements + +| Name | Version | +| ------------------------------------------------------------------------ | -------- | +| [terraform](#requirement_terraform) | >= 1.3.0 | +| [aws](#requirement_aws) | ~> 5.27 | +| [local](#requirement_local) | ~> 2.0 | +| [random](#requirement_random) | ~> 3.0 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +| -------------------------------------------------------- | ------- | ------- | +| [base](#module_base) | ../base | n/a | +| [runners](#module_runners) | ../../ | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +| ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | :------: | +| [aws_region](#input_aws_region) | AWS region. | `string` | `"eu-west-1"` | no | +| [environment](#input_environment) | Environment name, used as prefix. | `string` | `null` | no | +| [github_app_ssm_parameters](#input_github_app_ssm_parameters) | SSM parameters details for the GitHub App, that you've created manually on AWS. |
object({
key_base64 = optional(object({
arn = string
name = string
}))
id = optional(object({
arn = string
name = string
}))
webhook_secret = optional(object({
arn = string
name = string
}))
})
| `{}` | no | + +## Outputs + +| Name | Description | +| ----------------------------------------------------------------------------------- | ----------- | +| [runners](#output_runners) | n/a | +| [webhook_endpoint](#output_webhook_endpoint) | n/a | +| [webhook_secret](#output_webhook_secret) | n/a | + + diff --git a/examples/manual-ssm-parameters/main.tf b/examples/manual-ssm-parameters/main.tf new file mode 100644 index 0000000000..c07ea1c11e --- /dev/null +++ b/examples/manual-ssm-parameters/main.tf @@ -0,0 +1,164 @@ +locals { + environment = var.environment != null ? var.environment : "default" + aws_region = var.aws_region +} + +# resource "random_id" "random" { +# byte_length = 20 +# } + +module "base" { + source = "../base" + + prefix = local.environment + aws_region = local.aws_region +} + +module "runners" { + source = "../../" + create_service_linked_role_spot = true + aws_region = local.aws_region + vpc_id = module.base.vpc.vpc_id + subnet_ids = module.base.vpc.private_subnets + + prefix = local.environment + tags = { + Project = "ProjectX" + } + create_ssm_parameters_github_app = false + github_app_ssm_parameters = var.github_app_ssm_parameters + + + # configure the block device mappings, default for Amazon Linux2 + # block_device_mappings = [{ + # device_name = "/dev/xvda" + # delete_on_termination = true + # volume_type = "gp3" + # volume_size = 10 + # encrypted = true + # iops = null + # }] + + # When not explicitly set lambda zip files are grapped from the module requiring lambda build. + # Alternatively you can set the path to the lambda zip files here. + # + # For example grab zip files via lambda_download + # webhook_lambda_zip = "../lambdas-download/webhook.zip" + # runner_binaries_syncer_lambda_zip = "../lambdas-download/runner-binaries-syncer.zip" + # runners_lambda_zip = "../lambdas-download/runners.zip" + + enable_organization_runners = true + runner_extra_labels = ["default", "example"] + + # enable access to the runners via SSM + enable_ssm_on_runners = true + + # use S3 or KMS SSE to runners S3 bucket + # runner_binaries_s3_sse_configuration = { + # rule = { + # apply_server_side_encryption_by_default = { + # sse_algorithm = "AES256" + # } + # } + # } + + # enable S3 versioning for runners S3 bucket + # runner_binaries_s3_versioning = "Enabled" + + # Uncommet idle config to have idle runners from 9 to 5 in time zone Amsterdam + # idle_config = [{ + # cron = "* * 9-17 * * *" + # timeZone = "Europe/Amsterdam" + # idleCount = 1 + # }] + + # Let the module manage the service linked role + # create_service_linked_role_spot = true + + instance_types = ["m7a.large", "m5.large"] + + # override delay of events in seconds + delay_webhook_event = 5 + runners_maximum_count = 2 + + # override scaling down + scale_down_schedule_expression = "cron(* * * * ? *)" + + enable_user_data_debug_logging_runner = true + + # prefix GitHub runners with the environment name + runner_name_prefix = "${local.environment}_" + + # by default eventbridge is used, see multi-runner example. Here we disable the eventbridge + eventbridge = { + enable = false + } + + # Enable debug logging for the lambda functions + # log_level = "debug" + + # tracing_config = { + # mode = "Active" + # capture_error = true + # capture_http_requests = true + # } + + enable_ami_housekeeper = true + ami_housekeeper_cleanup_config = { + ssmParameterNames = ["*/ami-id"] + minimumDaysOld = 10 + amiFilters = [ + { + Name = "name" + Values = ["*al2023*"] + } + ] + } + + instance_termination_watcher = { + enable = true + } + + # enable metric creation (experimental) + # metrics = { + # enable = true + # metric = { + # enable_spot_termination_warning = true + # enable_job_retry = false + # enable_github_app_rate_limit = false + # } + # } + + # enable job_retry feature. Be careful with this feature, it can lead to you hitting API rate limits. + # job_retry = { + # enable = true + # max_attempts = 1 + # delay_in_seconds = 180 + # } + + # enable CMK instead of aws managed key for encryptions + # kms_key_arn = aws_kms_key.github.arn +} + +# ❌ When creating SSM parameters manually to avoid having them in the state, you shouldn't manage the github app settings in the state neither! +# module "webhook_github_app" { +# source = "../../modules/webhook-github-app" +# depends_on = [module.runners] + +# github_app = { +# key_base64 = var.github_app.key_base64 +# id = var.github_app.id +# webhook_secret = random_id.random.hex +# } +# webhook_endpoint = module.runners.webhook.endpoint +# } + +# enable CMK instead of aws managed key for encryptions +# resource "aws_kms_key" "github" { +# is_enabled = true +# } + +# resource "aws_kms_alias" "github" { +# name = "alias/github/action-runners" +# target_key_id = aws_kms_key.github.key_id +# } diff --git a/examples/manual-ssm-parameters/outputs.tf b/examples/manual-ssm-parameters/outputs.tf new file mode 100644 index 0000000000..c50214f566 --- /dev/null +++ b/examples/manual-ssm-parameters/outputs.tf @@ -0,0 +1,15 @@ +output "runners" { + value = { + lambda_syncer_name = module.runners.binaries_syncer.lambda.function_name + } +} + +output "webhook_endpoint" { + value = module.runners.webhook.endpoint +} + +output "webhook_secret" { + sensitive = true + value = random_id.random.hex +} + diff --git a/examples/manual-ssm-parameters/providers.tf b/examples/manual-ssm-parameters/providers.tf new file mode 100644 index 0000000000..eca2fe96a7 --- /dev/null +++ b/examples/manual-ssm-parameters/providers.tf @@ -0,0 +1,9 @@ +provider "aws" { + region = local.aws_region + + default_tags { + tags = { + Example = local.environment + } + } +} diff --git a/examples/manual-ssm-parameters/variables.tf b/examples/manual-ssm-parameters/variables.tf new file mode 100644 index 0000000000..047f404400 --- /dev/null +++ b/examples/manual-ssm-parameters/variables.tf @@ -0,0 +1,32 @@ +variable "github_app_ssm_parameters" { + description = "SSM parameters details for the GitHub App, that you've created manually on AWS." + type = object({ + key_base64 = optional(object({ + arn = string + name = string + })) + id = optional(object({ + arn = string + name = string + })) + webhook_secret = optional(object({ + arn = string + name = string + })) + }) + default = {} +} + +variable "environment" { + description = "Environment name, used as prefix." + + type = string + default = null +} + +variable "aws_region" { + description = "AWS region." + + type = string + default = "eu-west-1" +} diff --git a/examples/manual-ssm-parameters/versions.tf b/examples/manual-ssm-parameters/versions.tf new file mode 100644 index 0000000000..349e8243a5 --- /dev/null +++ b/examples/manual-ssm-parameters/versions.tf @@ -0,0 +1,17 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.27" + } + local = { + source = "hashicorp/local" + version = "~> 2.0" + } + random = { + source = "hashicorp/random" + version = "~> 3.0" + } + } + required_version = ">= 1.3.0" +} From 65a07551c53eeb8edf2d870103a8ff092827cc13 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 13 Feb 2025 14:00:54 +0000 Subject: [PATCH 03/24] docs: auto update terraform docs --- README.md | 4 ++- examples/manual-ssm-parameters/README.md | 42 +++++++++++------------- modules/multi-runner/README.md | 4 ++- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index c9c247f5d3..96761ebd40 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,7 @@ Join our discord community via [this invite link](https://discord.gg/bxgXW8jJGh) | [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`. |
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")
}))
|
[
{
"volume_size": 30
}
]
| no | | [cloudwatch\_config](#input\_cloudwatch\_config) | (optional) Replaces the module's 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 | +| [create\_ssm\_parameters\_github\_app](#input\_create\_ssm\_parameters\_github\_app) | Create SSM parameters for the runner configuration. The parameters are used to configure the runner. The parameters are created in the `ssm_paths.root` path.

Setting this to false will disable the creation of the SSM parameters. This can be useful when you want to manage the SSM parameters yourself, and avoid having github app details in the state.
After creating the SSM parameters, fill the name and arn in the `github_app_ssm_parameters` variable. | `bool` | `true` | no | | [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 | | [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 | | [enable\_ami\_housekeeper](#input\_enable\_ami\_housekeeper) | Option to disable the lambda to clean up old AMIs. | `bool` | `false` | no | @@ -141,7 +142,8 @@ Join our discord community via [this invite link](https://discord.gg/bxgXW8jJGh) | [eventbridge](#input\_eventbridge) | Enable the use of EventBridge by the module. By enabling this feature events will be put on the EventBridge by the webhook instead of directly dispatching to queues for scaling.

`enable`: Enable the EventBridge feature.
`accept_events`: List can be used to only allow specific events to be putted on the EventBridge. By default all events, empty list will be be interpreted as all events. |
object({
enable = optional(bool, true)
accept_events = optional(list(string), null)
})
| `{}` | no | | [ghes\_ssl\_verify](#input\_ghes\_ssl\_verify) | GitHub Enterprise SSL verification. Set to 'false' when custom certificate (chains) is used for GitHub Enterprise Server (insecure). | `bool` | `true` | no | | [ghes\_url](#input\_ghes\_url) | GitHub Enterprise Server URL. Example: https://github.internal.co - DO NOT SET IF USING PUBLIC GITHUB. However if you are using Github Enterprise Cloud with data-residency (ghe.com), set the endpoint here. Example - https://companyname.ghe.com | `string` | `null` | no | -| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = string
id = string
webhook_secret = string
})
| n/a | yes | +| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
id = optional(string)
webhook_secret = optional(string)
})
| `{}` | no | +| [github\_app\_ssm\_parameters](#input\_github\_app\_ssm\_parameters) | If you opt to create the SSM parameters yourself (see create\_ssm\_parameters\_github\_app), you need to provide name and arn here. |
object({
key_base64 = optional(object({
arn = string
name = string
}))
id = optional(object({
arn = string
name = string
}))
webhook_secret = optional(object({
arn = string
name = string
}))
})
| `{}` | no | | [idle\_config](#input\_idle\_config) | List of time periods, defined as a cron expression, to keep a minimum amount of runners active instead of scaling down to 0. By defining this list you can ensure that in time periods that match the cron expression within 5 seconds a runner is kept idle. |
list(object({
cron = string
timeZone = string
idleCount = number
evictionStrategy = optional(string, "oldest_first")
}))
| `[]` | no | | [instance\_allocation\_strategy](#input\_instance\_allocation\_strategy) | The allocation strategy for spot instances. AWS recommends using `price-capacity-optimized` however the AWS default is `lowest-price`. | `string` | `"lowest-price"` | no | | [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 | diff --git a/examples/manual-ssm-parameters/README.md b/examples/manual-ssm-parameters/README.md index be566433e1..034a65414e 100644 --- a/examples/manual-ssm-parameters/README.md +++ b/examples/manual-ssm-parameters/README.md @@ -33,15 +33,14 @@ terraform output -raw webhook_secret ``` - ## Requirements -| Name | Version | -| ------------------------------------------------------------------------ | -------- | -| [terraform](#requirement_terraform) | >= 1.3.0 | -| [aws](#requirement_aws) | ~> 5.27 | -| [local](#requirement_local) | ~> 2.0 | -| [random](#requirement_random) | ~> 3.0 | +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3.0 | +| [aws](#requirement\_aws) | ~> 5.27 | +| [local](#requirement\_local) | ~> 2.0 | +| [random](#requirement\_random) | ~> 3.0 | ## Providers @@ -49,10 +48,10 @@ No providers. ## Modules -| Name | Source | Version | -| -------------------------------------------------------- | ------- | ------- | -| [base](#module_base) | ../base | n/a | -| [runners](#module_runners) | ../../ | n/a | +| Name | Source | Version | +|------|--------|---------| +| [base](#module\_base) | ../base | n/a | +| [runners](#module\_runners) | ../../ | n/a | ## Resources @@ -60,18 +59,17 @@ No resources. ## Inputs -| Name | Description | Type | Default | Required | -| ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | :------: | -| [aws_region](#input_aws_region) | AWS region. | `string` | `"eu-west-1"` | no | -| [environment](#input_environment) | Environment name, used as prefix. | `string` | `null` | no | -| [github_app_ssm_parameters](#input_github_app_ssm_parameters) | SSM parameters details for the GitHub App, that you've created manually on AWS. |
object({
key_base64 = optional(object({
arn = string
name = string
}))
id = optional(object({
arn = string
name = string
}))
webhook_secret = optional(object({
arn = string
name = string
}))
})
| `{}` | no | +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [aws\_region](#input\_aws\_region) | AWS region. | `string` | `"eu-west-1"` | no | +| [environment](#input\_environment) | Environment name, used as prefix. | `string` | `null` | no | +| [github\_app\_ssm\_parameters](#input\_github\_app\_ssm\_parameters) | SSM parameters details for the GitHub App, that you've created manually on AWS. |
object({
key_base64 = optional(object({
arn = string
name = string
}))
id = optional(object({
arn = string
name = string
}))
webhook_secret = optional(object({
arn = string
name = string
}))
})
| `{}` | no | ## Outputs -| Name | Description | -| ----------------------------------------------------------------------------------- | ----------- | -| [runners](#output_runners) | n/a | -| [webhook_endpoint](#output_webhook_endpoint) | n/a | -| [webhook_secret](#output_webhook_secret) | n/a | - +| Name | Description | +|------|-------------| +| [runners](#output\_runners) | n/a | +| [webhook\_endpoint](#output\_webhook\_endpoint) | n/a | +| [webhook\_secret](#output\_webhook\_secret) | n/a | diff --git a/modules/multi-runner/README.md b/modules/multi-runner/README.md index 771f7e1f98..3269c00859 100644 --- a/modules/multi-runner/README.md +++ b/modules/multi-runner/README.md @@ -126,12 +126,14 @@ module "multi-runner" { | [aws\_partition](#input\_aws\_partition) | (optiona) partition in the arn namespace to use if not 'aws' | `string` | `"aws"` | no | | [aws\_region](#input\_aws\_region) | AWS region. | `string` | n/a | yes | | [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\_ssm\_parameters\_github\_app](#input\_create\_ssm\_parameters\_github\_app) | Create SSM parameters for the runner configuration. The parameters are used to configure the runner. The parameters are created in the `ssm_paths.root` path.

Setting this to false will disable the creation of the SSM parameters. This can be useful when you want to manage the SSM parameters yourself, and avoid having github app details in the state.
After creating the SSM parameters, fill the name and arn in the `github_app_ssm_parameters` variable. | `bool` | `true` | no | | [enable\_ami\_housekeeper](#input\_enable\_ami\_housekeeper) | Option to disable the lambda to clean up old AMIs. | `bool` | `false` | 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 | | [eventbridge](#input\_eventbridge) | Enable the use of EventBridge by the module. By enabling this feature events will be put on the EventBridge by the webhook instead of directly dispatching to queues for scaling. |
object({
enable = optional(bool, true)
accept_events = optional(list(string), [])
})
| `{}` | no | | [ghes\_ssl\_verify](#input\_ghes\_ssl\_verify) | GitHub Enterprise SSL verification. Set to 'false' when custom certificate (chains) is used for GitHub Enterprise Server (insecure). | `bool` | `true` | no | | [ghes\_url](#input\_ghes\_url) | GitHub Enterprise Server URL. Example: https://github.internal.co - DO NOT SET IF USING PUBLIC GITHUB. .However if you are using Github Enterprise Cloud with data-residency (ghe.com), set the endpoint here. Example - https://companyname.ghe.com\| | `string` | `null` | no | -| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = string
id = string
webhook_secret = string
})
| n/a | yes | +| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
id = optional(string)
webhook_secret = optional(string)
})
| `{}` | no | +| [github\_app\_ssm\_parameters](#input\_github\_app\_ssm\_parameters) | If you opt to create the SSM parameters yourself (see create\_ssm\_parameters\_github\_app), you need to provide name and arn here. |
object({
key_base64 = optional(object({
arn = string
name = string
}))
id = optional(object({
arn = string
name = string
}))
webhook_secret = optional(object({
arn = string
name = string
}))
})
| `{}` | 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\_termination\_watcher](#input\_instance\_termination\_watcher) | Configuration for the spot termination watcher lambda function. This feature is Beta, changes will not trigger a major release as long in beta.

`enable`: Enable or disable the spot termination watcher.
`memory_size`: Memory size linit in MB of the lambda.
`s3_key`: S3 key for syncer lambda function. Required if using S3 bucket to specify lambdas.
`s3_object_version`: S3 object version for syncer lambda function. Useful if S3 versioning is enabled on source bucket.
`timeout`: Time out of the lambda in seconds.
`zip`: File location of the lambda zip file. |
object({
enable = optional(bool, false)
features = optional(object({
enable_spot_termination_handler = optional(bool, true)
enable_spot_termination_notification_watcher = optional(bool, true)
}), {})
memory_size = optional(number, null)
s3_key = optional(string, null)
s3_object_version = optional(string, null)
timeout = optional(number, null)
zip = optional(string, null)
})
| `{}` | no | | [key\_name](#input\_key\_name) | Key pair name | `string` | `null` | no | From fd65672cd0171465227d5e184f5e68a38b8a8c42 Mon Sep 17 00:00:00 2001 From: AppliNH Date: Thu, 13 Feb 2025 15:39:24 +0100 Subject: [PATCH 04/24] mv(example external-managed-ssm): change example name and refactor doc --- .../.terraform.lock.hcl | 0 .../README.md | 36 +++++++++++++++---- .../main.tf | 8 +++-- .../outputs.tf | 0 .../providers.tf | 0 .../variables.tf | 0 .../versions.tf | 0 7 files changed, 35 insertions(+), 9 deletions(-) rename examples/{manual-ssm-parameters => external-managed-ssm-secrets}/.terraform.lock.hcl (100%) rename examples/{manual-ssm-parameters => external-managed-ssm-secrets}/README.md (76%) rename examples/{manual-ssm-parameters => external-managed-ssm-secrets}/main.tf (95%) rename examples/{manual-ssm-parameters => external-managed-ssm-secrets}/outputs.tf (100%) rename examples/{manual-ssm-parameters => external-managed-ssm-secrets}/providers.tf (100%) rename examples/{manual-ssm-parameters => external-managed-ssm-secrets}/variables.tf (100%) rename examples/{manual-ssm-parameters => external-managed-ssm-secrets}/versions.tf (100%) diff --git a/examples/manual-ssm-parameters/.terraform.lock.hcl b/examples/external-managed-ssm-secrets/.terraform.lock.hcl similarity index 100% rename from examples/manual-ssm-parameters/.terraform.lock.hcl rename to examples/external-managed-ssm-secrets/.terraform.lock.hcl diff --git a/examples/manual-ssm-parameters/README.md b/examples/external-managed-ssm-secrets/README.md similarity index 76% rename from examples/manual-ssm-parameters/README.md rename to examples/external-managed-ssm-secrets/README.md index be566433e1..be72c4993c 100644 --- a/examples/manual-ssm-parameters/README.md +++ b/examples/external-managed-ssm-secrets/README.md @@ -1,16 +1,40 @@ -# Amazon Linux X64 (default) +# Externally managed SSM secrets -This module shows how to create GitHub action runners. Lambda release will be downloaded from GitHub. +This example is based on the [default setup](../default/README.md), but shows how to use configure runners with already existing SSM parameters that you'd have created manually. -The only difference compared to [`default`](../default/README.md) is that you need to create SSM parameters manually so their values are not stored in the state (see `create_ssm_parameters_github_app` variable). +Manually creating the SSM parameters that hold the configuration of your GitHub App avoids leaking critical plain text values in your terraform state and version control system. This is a recommended security practice for handling sensitive credentials. -## Usages +## Prerequisites + +Create the following SSM parameters on the AWS console, or by using the following aws-cli commands: -Before all, manually create the SSM parameters for the GitHub App ID, base64-encoded private key and webhook secret. Then refer their name and arn through the [`github_app_ssm_parameters` variable](./variables.tf). +```bash + # GitHub App ID + aws ssm put-parameter \ + --name "/github-action-runners/app/github_app_id" \ + --value "YOUR_APP_ID" \ + --type "SecureString" + + # GitHub App Private Key + aws ssm put-parameter \ + --name "/github-action-runners/app/github_app_key_base64" \ + --value "YOUR_PRIVATE_KEY" \ + --type "SecureString" + + # GitHub App Installation ID + aws ssm put-parameter \ + --name "/github-action-runners/app/github_app_webhook_secret" \ + --value "YOUR_INSTALLATION_ID" \ + --type "SecureString" +``` + +Then fill the `arn` and `name` values for each of these inside the [`github_app_ssm_parameters` variable](./variables.tf). + +## Usages Steps for the full setup, such as creating a GitHub app can be found in the root module's [README](https://github.com/philips-labs/terraform-aws-github-runner). First download the Lambda releases from GitHub. Alternatively you can build the lambdas locally with Node or Docker, there is a simple build script in `/.ci/build.sh`. In the `main.tf` you can simply remove the location of the lambda zip files, the default location will work in this case. -> The default example assumes local built lambda's available. Ensure you have built the lambda's. Alternativly you can downlowd the lambda's. The version needs to be set to a GitHub release version, see https://github.com/philips-labs/terraform-aws-github-runner/releases +> This example assumes local built lambda's available. Ensure you have built the lambda's. Alternativly you can downlowd the lambda's. The version needs to be set to a GitHub release version, see https://github.com/philips-labs/terraform-aws-github-runner/releases ```bash cd ../lambdas-download diff --git a/examples/manual-ssm-parameters/main.tf b/examples/external-managed-ssm-secrets/main.tf similarity index 95% rename from examples/manual-ssm-parameters/main.tf rename to examples/external-managed-ssm-secrets/main.tf index c07ea1c11e..bf5532a1ad 100644 --- a/examples/manual-ssm-parameters/main.tf +++ b/examples/external-managed-ssm-secrets/main.tf @@ -25,9 +25,11 @@ module "runners" { tags = { Project = "ProjectX" } - create_ssm_parameters_github_app = false - github_app_ssm_parameters = var.github_app_ssm_parameters - + github_app = { + key_base64_ssm = var.github_app_ssm_parameters.key_base64 + id_ssm = var.github_app_ssm_parameters.id + webhook_secret_ssm = var.github_app_ssm_parameters.webhook_secret + } # configure the block device mappings, default for Amazon Linux2 # block_device_mappings = [{ diff --git a/examples/manual-ssm-parameters/outputs.tf b/examples/external-managed-ssm-secrets/outputs.tf similarity index 100% rename from examples/manual-ssm-parameters/outputs.tf rename to examples/external-managed-ssm-secrets/outputs.tf diff --git a/examples/manual-ssm-parameters/providers.tf b/examples/external-managed-ssm-secrets/providers.tf similarity index 100% rename from examples/manual-ssm-parameters/providers.tf rename to examples/external-managed-ssm-secrets/providers.tf diff --git a/examples/manual-ssm-parameters/variables.tf b/examples/external-managed-ssm-secrets/variables.tf similarity index 100% rename from examples/manual-ssm-parameters/variables.tf rename to examples/external-managed-ssm-secrets/variables.tf diff --git a/examples/manual-ssm-parameters/versions.tf b/examples/external-managed-ssm-secrets/versions.tf similarity index 100% rename from examples/manual-ssm-parameters/versions.tf rename to examples/external-managed-ssm-secrets/versions.tf From b61380517f36d1034518ab23b5ae79462dc627be Mon Sep 17 00:00:00 2001 From: AppliNH Date: Thu, 13 Feb 2025 15:39:53 +0100 Subject: [PATCH 05/24] other(github_app): include ssm parameters inside existing github_app + remove unused variables --- main.tf | 13 +++------ modules/multi-runner/main.tf | 12 +++------ modules/multi-runner/outputs.tf | 6 ++++- modules/multi-runner/ssm.tf | 1 - modules/multi-runner/variables.tf | 44 +++++++++---------------------- modules/ssm/ssm.tf | 3 +++ modules/ssm/variables.tf | 18 ++++++++++--- outputs.tf | 6 ++++- variables.tf | 37 +++++++++----------------- 9 files changed, 60 insertions(+), 80 deletions(-) diff --git a/main.tf b/main.tf index 31528724f1..81ed53ba39 100644 --- a/main.tf +++ b/main.tf @@ -3,14 +3,10 @@ locals { "ghr:environment" = var.prefix }) - github_app_parameters = var.create_ssm_parameters_github_app ? { - id = module.ssm[0].parameters.github_app_id - key_base64 = module.ssm[0].parameters.github_app_key_base64 - webhook_secret = module.ssm[0].parameters.github_app_webhook_secret - } : { - id = var.github_app_ssm_parameters.id - key_base64 = var.github_app_ssm_parameters.key_base64 - webhook_secret = var.github_app_ssm_parameters.webhook_secret + github_app_parameters = { + id = coalesce(var.github_app.id_ssm, module.ssm[0].parameters.github_app_id) + key_base64 = coalesce(var.github_app.key_base64_ssm, module.ssm[0].parameters.github_app_key_base64) + webhook_secret = coalesce(var.github_app.webhook_secret_ssm, module.ssm[0].parameters.github_app_webhook_secret) } default_runner_labels = distinct(concat(["self-hosted", var.runner_os, var.runner_architecture])) @@ -93,7 +89,6 @@ resource "aws_sqs_queue" "queued_builds_dlq" { module "ssm" { source = "./modules/ssm" - count = var.create_ssm_parameters_github_app ? 1 : 0 kms_key_arn = var.kms_key_arn path_prefix = "${local.ssm_root_path}/${var.ssm_paths.app}" github_app = var.github_app diff --git a/modules/multi-runner/main.tf b/modules/multi-runner/main.tf index b3e598d28c..f267228432 100644 --- a/modules/multi-runner/main.tf +++ b/modules/multi-runner/main.tf @@ -3,14 +3,10 @@ locals { "ghr:environment" = var.prefix }) - github_app_parameters = var.create_ssm_parameters_github_app ? { - id = module.ssm[0].parameters.github_app_id - key_base64 = module.ssm[0].parameters.github_app_key_base64 - webhook_secret = module.ssm[0].parameters.github_app_webhook_secret - } : { - id = var.github_app_ssm_parameters.id - key_base64 = var.github_app_ssm_parameters.key_base64 - webhook_secret = var.github_app_ssm_parameters.webhook_secret + github_app_parameters = { + id = coalesce(var.github_app.id_ssm, module.ssm[0].parameters.github_app_id) + key_base64 = coalesce(var.github_app.key_base64_ssm, module.ssm[0].parameters.github_app_key_base64) + webhook_secret = coalesce(var.github_app.webhook_secret_ssm, module.ssm[0].parameters.github_app_webhook_secret) } runner_extra_labels = { for k, v in var.multi_runner_config : k => sort(setunion(flatten(v.matcherConfig.labelMatchers), compact(v.runner_config.runner_extra_labels))) } diff --git a/modules/multi-runner/outputs.tf b/modules/multi-runner/outputs.tf index 10ab21761c..7ce7171faf 100644 --- a/modules/multi-runner/outputs.tf +++ b/modules/multi-runner/outputs.tf @@ -45,7 +45,11 @@ output "webhook" { } output "ssm_parameters" { - value = var.create_ssm_parameters_github_app ? module.ssm[0].parameters : var.github_app_ssm_parameters + value = { for k, v in local.github_app_parameters : k => { + name = v.name + arn = v.arn + } + } } output "instance_termination_watcher" { diff --git a/modules/multi-runner/ssm.tf b/modules/multi-runner/ssm.tf index 562d2fa5de..6a3a234e6f 100644 --- a/modules/multi-runner/ssm.tf +++ b/modules/multi-runner/ssm.tf @@ -1,6 +1,5 @@ module "ssm" { source = "../ssm" - count = var.create_ssm_parameters_github_app ? 1 : 0 kms_key_arn = var.kms_key_arn path_prefix = "${local.ssm_root_path}/${var.ssm_paths.app}" github_app = var.github_app diff --git a/modules/multi-runner/variables.tf b/modules/multi-runner/variables.tf index 74ca777fb8..0b0b7fc6ae 100644 --- a/modules/multi-runner/variables.tf +++ b/modules/multi-runner/variables.tf @@ -1,26 +1,23 @@ variable "github_app" { - description = "GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`)." - type = object({ - key_base64 = optional(string) - id = optional(string) - webhook_secret = optional(string) - }) - default = {} -} - - -variable "github_app_ssm_parameters" { - description = "If you opt to create the SSM parameters yourself (see create_ssm_parameters_github_app), you need to provide name and arn here." + description = < { + name = v.name + arn = v.arn + } + } } diff --git a/variables.tf b/variables.tf index f41ad350e9..bab9d0a7aa 100644 --- a/variables.tf +++ b/variables.tf @@ -32,27 +32,25 @@ variable "enable_organization_runners" { } variable "github_app" { - description = "GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`)." - type = object({ - key_base64 = optional(string) - id = optional(string) - webhook_secret = optional(string) - }) - default = {} -} - -variable "github_app_ssm_parameters" { - description = "If you opt to create the SSM parameters yourself (see create_ssm_parameters_github_app), you need to provide name and arn here." + description = < Date: Thu, 13 Feb 2025 14:41:53 +0000 Subject: [PATCH 06/24] docs: auto update terraform docs --- README.md | 4 +--- modules/multi-runner/README.md | 5 +---- modules/ssm/README.md | 2 +- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 96761ebd40..f4944e4e34 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,6 @@ Join our discord community via [this invite link](https://discord.gg/bxgXW8jJGh) | [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`. |
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")
}))
|
[
{
"volume_size": 30
}
]
| no | | [cloudwatch\_config](#input\_cloudwatch\_config) | (optional) Replaces the module's 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 | -| [create\_ssm\_parameters\_github\_app](#input\_create\_ssm\_parameters\_github\_app) | Create SSM parameters for the runner configuration. The parameters are used to configure the runner. The parameters are created in the `ssm_paths.root` path.

Setting this to false will disable the creation of the SSM parameters. This can be useful when you want to manage the SSM parameters yourself, and avoid having github app details in the state.
After creating the SSM parameters, fill the name and arn in the `github_app_ssm_parameters` variable. | `bool` | `true` | no | | [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 | | [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 | | [enable\_ami\_housekeeper](#input\_enable\_ami\_housekeeper) | Option to disable the lambda to clean up old AMIs. | `bool` | `false` | no | @@ -142,8 +141,7 @@ Join our discord community via [this invite link](https://discord.gg/bxgXW8jJGh) | [eventbridge](#input\_eventbridge) | Enable the use of EventBridge by the module. By enabling this feature events will be put on the EventBridge by the webhook instead of directly dispatching to queues for scaling.

`enable`: Enable the EventBridge feature.
`accept_events`: List can be used to only allow specific events to be putted on the EventBridge. By default all events, empty list will be be interpreted as all events. |
object({
enable = optional(bool, true)
accept_events = optional(list(string), null)
})
| `{}` | no | | [ghes\_ssl\_verify](#input\_ghes\_ssl\_verify) | GitHub Enterprise SSL verification. Set to 'false' when custom certificate (chains) is used for GitHub Enterprise Server (insecure). | `bool` | `true` | no | | [ghes\_url](#input\_ghes\_url) | GitHub Enterprise Server URL. Example: https://github.internal.co - DO NOT SET IF USING PUBLIC GITHUB. However if you are using Github Enterprise Cloud with data-residency (ghe.com), set the endpoint here. Example - https://companyname.ghe.com | `string` | `null` | no | -| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
id = optional(string)
webhook_secret = optional(string)
})
| `{}` | no | -| [github\_app\_ssm\_parameters](#input\_github\_app\_ssm\_parameters) | If you opt to create the SSM parameters yourself (see create\_ssm\_parameters\_github\_app), you need to provide name and arn here. |
object({
key_base64 = optional(object({
arn = string
name = string
}))
id = optional(object({
arn = string
name = string
}))
webhook_secret = optional(object({
arn = string
name = string
}))
})
| `{}` | no | +| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app.
You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes.
If you chose to provide the configuration values directly here,
please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| `{}` | no | | [idle\_config](#input\_idle\_config) | List of time periods, defined as a cron expression, to keep a minimum amount of runners active instead of scaling down to 0. By defining this list you can ensure that in time periods that match the cron expression within 5 seconds a runner is kept idle. |
list(object({
cron = string
timeZone = string
idleCount = number
evictionStrategy = optional(string, "oldest_first")
}))
| `[]` | no | | [instance\_allocation\_strategy](#input\_instance\_allocation\_strategy) | The allocation strategy for spot instances. AWS recommends using `price-capacity-optimized` however the AWS default is `lowest-price`. | `string` | `"lowest-price"` | no | | [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 | diff --git a/modules/multi-runner/README.md b/modules/multi-runner/README.md index 3269c00859..6a3c86e26d 100644 --- a/modules/multi-runner/README.md +++ b/modules/multi-runner/README.md @@ -126,14 +126,12 @@ module "multi-runner" { | [aws\_partition](#input\_aws\_partition) | (optiona) partition in the arn namespace to use if not 'aws' | `string` | `"aws"` | no | | [aws\_region](#input\_aws\_region) | AWS region. | `string` | n/a | yes | | [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\_ssm\_parameters\_github\_app](#input\_create\_ssm\_parameters\_github\_app) | Create SSM parameters for the runner configuration. The parameters are used to configure the runner. The parameters are created in the `ssm_paths.root` path.

Setting this to false will disable the creation of the SSM parameters. This can be useful when you want to manage the SSM parameters yourself, and avoid having github app details in the state.
After creating the SSM parameters, fill the name and arn in the `github_app_ssm_parameters` variable. | `bool` | `true` | no | | [enable\_ami\_housekeeper](#input\_enable\_ami\_housekeeper) | Option to disable the lambda to clean up old AMIs. | `bool` | `false` | 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 | | [eventbridge](#input\_eventbridge) | Enable the use of EventBridge by the module. By enabling this feature events will be put on the EventBridge by the webhook instead of directly dispatching to queues for scaling. |
object({
enable = optional(bool, true)
accept_events = optional(list(string), [])
})
| `{}` | no | | [ghes\_ssl\_verify](#input\_ghes\_ssl\_verify) | GitHub Enterprise SSL verification. Set to 'false' when custom certificate (chains) is used for GitHub Enterprise Server (insecure). | `bool` | `true` | no | | [ghes\_url](#input\_ghes\_url) | GitHub Enterprise Server URL. Example: https://github.internal.co - DO NOT SET IF USING PUBLIC GITHUB. .However if you are using Github Enterprise Cloud with data-residency (ghe.com), set the endpoint here. Example - https://companyname.ghe.com\| | `string` | `null` | no | -| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
id = optional(string)
webhook_secret = optional(string)
})
| `{}` | no | -| [github\_app\_ssm\_parameters](#input\_github\_app\_ssm\_parameters) | If you opt to create the SSM parameters yourself (see create\_ssm\_parameters\_github\_app), you need to provide name and arn here. |
object({
key_base64 = optional(object({
arn = string
name = string
}))
id = optional(object({
arn = string
name = string
}))
webhook_secret = optional(object({
arn = string
name = string
}))
})
| `{}` | no | +| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app.
You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes.
If you chose to provide the configuration values directly here,
please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| `{}` | 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\_termination\_watcher](#input\_instance\_termination\_watcher) | Configuration for the spot termination watcher lambda function. This feature is Beta, changes will not trigger a major release as long in beta.

`enable`: Enable or disable the spot termination watcher.
`memory_size`: Memory size linit in MB of the lambda.
`s3_key`: S3 key for syncer lambda function. Required if using S3 bucket to specify lambdas.
`s3_object_version`: S3 object version for syncer lambda function. Useful if S3 versioning is enabled on source bucket.
`timeout`: Time out of the lambda in seconds.
`zip`: File location of the lambda zip file. |
object({
enable = optional(bool, false)
features = optional(object({
enable_spot_termination_handler = optional(bool, true)
enable_spot_termination_notification_watcher = optional(bool, true)
}), {})
memory_size = optional(number, null)
s3_key = optional(string, null)
s3_object_version = optional(string, null)
timeout = optional(number, null)
zip = optional(string, null)
})
| `{}` | no | | [key\_name](#input\_key\_name) | Key pair name | `string` | `null` | no | @@ -180,7 +178,6 @@ module "multi-runner" { | [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. | `string` | `null` | no | | [tags](#input\_tags) | Map of tags that will be added to created resources. By default resources will be tagged with name and environment. | `map(string)` | `{}` | no | | [tracing\_config](#input\_tracing\_config) | Configuration for lambda tracing. |
object({
mode = optional(string, null)
capture_http_requests = optional(bool, false)
capture_error = optional(bool, false)
})
| `{}` | no | -| [user\_agent](#input\_user\_agent) | User agent used for API calls by lambda functions. | `string` | `"github-aws-runners"` | no | | [vpc\_id](#input\_vpc\_id) | The VPC for security groups of the action runners. | `string` | n/a | yes | | [webhook\_lambda\_apigateway\_access\_log\_settings](#input\_webhook\_lambda\_apigateway\_access\_log\_settings) | Access log settings for webhook API gateway. |
object({
destination_arn = string
format = string
})
| `null` | no | | [webhook\_lambda\_memory\_size](#input\_webhook\_lambda\_memory\_size) | Memory size limit in MB for webhook lambda. | `number` | `256` | no | diff --git a/modules/ssm/README.md b/modules/ssm/README.md index a188f543f5..65bb14ee7b 100644 --- a/modules/ssm/README.md +++ b/modules/ssm/README.md @@ -34,7 +34,7 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = string
id = string
webhook_secret = string
})
| n/a | yes | +| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| n/a | yes | | [kms\_key\_arn](#input\_kms\_key\_arn) | Optional CMK Key ARN to be used for Parameter Store. | `string` | `null` | no | | [path\_prefix](#input\_path\_prefix) | The path prefix used for naming resources | `string` | n/a | yes | | [tags](#input\_tags) | Map of tags that will be added to created resources. By default resources will be tagged with name and environment. | `map(string)` | `{}` | no | From c6535993a5095377c0ddd9fc8f037ada79145374 Mon Sep 17 00:00:00 2001 From: AppliNH Date: Thu, 13 Feb 2025 15:58:02 +0100 Subject: [PATCH 07/24] fix(modules ssm): fix outputs --- modules/multi-runner/variables.tf | 6 ++++++ modules/ssm/outputs.tf | 12 ++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/modules/multi-runner/variables.tf b/modules/multi-runner/variables.tf index 0b0b7fc6ae..d738b3c4e4 100644 --- a/modules/multi-runner/variables.tf +++ b/modules/multi-runner/variables.tf @@ -690,3 +690,9 @@ variable "eventbridge" { default = {} } + +variable "user_agent" { + description = "User agent used for API calls by lambda functions." + type = string + default = "github-aws-runners" +} diff --git a/modules/ssm/outputs.tf b/modules/ssm/outputs.tf index 3545a839c3..4beeef3097 100644 --- a/modules/ssm/outputs.tf +++ b/modules/ssm/outputs.tf @@ -1,16 +1,16 @@ output "parameters" { value = { github_app_id = { - name = aws_ssm_parameter.github_app_id.name - arn = aws_ssm_parameter.github_app_id.arn + name = coalesce(var.github_app.id_ssm, aws_ssm_parameter.github_app_id[0]).name + arn = coalesce(var.github_app.id_ssm, aws_ssm_parameter.github_app_id[0]).arn } github_app_key_base64 = { - name = aws_ssm_parameter.github_app_key_base64.name - arn = aws_ssm_parameter.github_app_key_base64.arn + name = coalesce(var.github_app.key_base64_ssm, aws_ssm_parameter.github_app_key_base64[0]).name + arn = coalesce(var.github_app.key_base64_ssm, aws_ssm_parameter.github_app_key_base64[0]).arn } github_app_webhook_secret = { - name = aws_ssm_parameter.github_app_webhook_secret.name - arn = aws_ssm_parameter.github_app_webhook_secret.arn + name = coalesce(var.github_app.webhook_secret_ssm, aws_ssm_parameter.github_app_webhook_secret[0]).name + arn = coalesce(var.github_app.webhook_secret_ssm, aws_ssm_parameter.github_app_webhook_secret[0]).arn } } } From 201a973b5157472b53bcddaca232f4d070640c49 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 13 Feb 2025 14:58:32 +0000 Subject: [PATCH 08/24] docs: auto update terraform docs --- modules/multi-runner/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/multi-runner/README.md b/modules/multi-runner/README.md index 6a3c86e26d..f62861e9fc 100644 --- a/modules/multi-runner/README.md +++ b/modules/multi-runner/README.md @@ -178,6 +178,7 @@ module "multi-runner" { | [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. | `string` | `null` | no | | [tags](#input\_tags) | Map of tags that will be added to created resources. By default resources will be tagged with name and environment. | `map(string)` | `{}` | no | | [tracing\_config](#input\_tracing\_config) | Configuration for lambda tracing. |
object({
mode = optional(string, null)
capture_http_requests = optional(bool, false)
capture_error = optional(bool, false)
})
| `{}` | no | +| [user\_agent](#input\_user\_agent) | User agent used for API calls by lambda functions. | `string` | `"github-aws-runners"` | no | | [vpc\_id](#input\_vpc\_id) | The VPC for security groups of the action runners. | `string` | n/a | yes | | [webhook\_lambda\_apigateway\_access\_log\_settings](#input\_webhook\_lambda\_apigateway\_access\_log\_settings) | Access log settings for webhook API gateway. |
object({
destination_arn = string
format = string
})
| `null` | no | | [webhook\_lambda\_memory\_size](#input\_webhook\_lambda\_memory\_size) | Memory size limit in MB for webhook lambda. | `number` | `256` | no | From c2d2cd118d23baf97ee6f0d1b8759e1fcb70a701 Mon Sep 17 00:00:00 2001 From: AppliNH Date: Thu, 13 Feb 2025 16:09:11 +0100 Subject: [PATCH 09/24] fix(ssm): fix module.ssm refs --- main.tf | 6 +++--- modules/multi-runner/main.tf | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/main.tf b/main.tf index 81ed53ba39..b9456c0a52 100644 --- a/main.tf +++ b/main.tf @@ -4,9 +4,9 @@ locals { }) github_app_parameters = { - id = coalesce(var.github_app.id_ssm, module.ssm[0].parameters.github_app_id) - key_base64 = coalesce(var.github_app.key_base64_ssm, module.ssm[0].parameters.github_app_key_base64) - webhook_secret = coalesce(var.github_app.webhook_secret_ssm, module.ssm[0].parameters.github_app_webhook_secret) + id = coalesce(var.github_app.id_ssm, module.ssm.parameters.github_app_id) + key_base64 = coalesce(var.github_app.key_base64_ssm, module.ssm.parameters.github_app_key_base64) + webhook_secret = coalesce(var.github_app.webhook_secret_ssm, module.ssm.parameters.github_app_webhook_secret) } default_runner_labels = distinct(concat(["self-hosted", var.runner_os, var.runner_architecture])) diff --git a/modules/multi-runner/main.tf b/modules/multi-runner/main.tf index f267228432..905cc7f793 100644 --- a/modules/multi-runner/main.tf +++ b/modules/multi-runner/main.tf @@ -4,9 +4,9 @@ locals { }) github_app_parameters = { - id = coalesce(var.github_app.id_ssm, module.ssm[0].parameters.github_app_id) - key_base64 = coalesce(var.github_app.key_base64_ssm, module.ssm[0].parameters.github_app_key_base64) - webhook_secret = coalesce(var.github_app.webhook_secret_ssm, module.ssm[0].parameters.github_app_webhook_secret) + id = coalesce(var.github_app.id_ssm, module.ssm.parameters.github_app_id) + key_base64 = coalesce(var.github_app.key_base64_ssm, module.ssm.parameters.github_app_key_base64) + webhook_secret = coalesce(var.github_app.webhook_secret_ssm, module.ssm.parameters.github_app_webhook_secret) } runner_extra_labels = { for k, v in var.multi_runner_config : k => sort(setunion(flatten(v.matcherConfig.labelMatchers), compact(v.runner_config.runner_extra_labels))) } From 556bca10deff31ac518f8342afd9a7435523ffe3 Mon Sep 17 00:00:00 2001 From: AppliNH Date: Thu, 13 Feb 2025 16:12:54 +0100 Subject: [PATCH 10/24] fix(ssm ouputs): use simplier condition as coalesce cant be used here --- modules/ssm/outputs.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/ssm/outputs.tf b/modules/ssm/outputs.tf index 4beeef3097..4017f6ab3d 100644 --- a/modules/ssm/outputs.tf +++ b/modules/ssm/outputs.tf @@ -1,16 +1,16 @@ output "parameters" { value = { github_app_id = { - name = coalesce(var.github_app.id_ssm, aws_ssm_parameter.github_app_id[0]).name - arn = coalesce(var.github_app.id_ssm, aws_ssm_parameter.github_app_id[0]).arn + name = var.github_app.id_ssm != null ? var.github_app.id_ssm.name : aws_ssm_parameter.github_app_id[0].name + arn = var.github_app.id_ssm != null ? var.github_app.id_ssm.arn : aws_ssm_parameter.github_app_id[0].arn } github_app_key_base64 = { - name = coalesce(var.github_app.key_base64_ssm, aws_ssm_parameter.github_app_key_base64[0]).name - arn = coalesce(var.github_app.key_base64_ssm, aws_ssm_parameter.github_app_key_base64[0]).arn + name = var.github_app.key_base64_ssm != null ? var.github_app.key_base64_ssm.name : aws_ssm_parameter.github_app_key_base64[0].name + arn = var.github_app.key_base64_ssm != null ? var.github_app.key_base64_ssm.arn : aws_ssm_parameter.github_app_key_base64[0].arn } github_app_webhook_secret = { - name = coalesce(var.github_app.webhook_secret_ssm, aws_ssm_parameter.github_app_webhook_secret[0]).name - arn = coalesce(var.github_app.webhook_secret_ssm, aws_ssm_parameter.github_app_webhook_secret[0]).arn + name = var.github_app.webhook_secret_ssm != null ? var.github_app.webhook_secret_ssm.name : aws_ssm_parameter.github_app_webhook_secret[0].name + arn = var.github_app.webhook_secret_ssm != null ? var.github_app.webhook_secret_ssm.arn : aws_ssm_parameter.github_app_webhook_secret[0].arn } } } From 91723f0962ee960db36e2e3f2ba4f96c2fc032a8 Mon Sep 17 00:00:00 2001 From: AppliNH Date: Tue, 18 Feb 2025 16:41:10 +0100 Subject: [PATCH 11/24] other(vars github_app): add validation block and update description --- modules/multi-runner/variables.tf | 11 ++++++++++- modules/ssm/variables.tf | 16 +++++++++++++++- variables.tf | 10 +++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/modules/multi-runner/variables.tf b/modules/multi-runner/variables.tf index d738b3c4e4..df52689abe 100644 --- a/modules/multi-runner/variables.tf +++ b/modules/multi-runner/variables.tf @@ -22,7 +22,16 @@ variable "github_app" { name = string })) }) - default = {} + + validation { + condition = (var.github_app.key_base64 != null || var.github_app.key_base64_ssm != null) && (var.github_app.id != null || var.github_app.id_ssm != null) && (var.github_app.webhook_secret != null || var.github_app.webhook_secret_ssm != null) + error_message = < Date: Tue, 18 Feb 2025 15:41:31 +0000 Subject: [PATCH 12/24] docs: auto update terraform docs --- README.md | 2 +- modules/multi-runner/README.md | 2 +- modules/ssm/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f4944e4e34..fde97b16e0 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ Join our discord community via [this invite link](https://discord.gg/bxgXW8jJGh) | [eventbridge](#input\_eventbridge) | Enable the use of EventBridge by the module. By enabling this feature events will be put on the EventBridge by the webhook instead of directly dispatching to queues for scaling.

`enable`: Enable the EventBridge feature.
`accept_events`: List can be used to only allow specific events to be putted on the EventBridge. By default all events, empty list will be be interpreted as all events. |
object({
enable = optional(bool, true)
accept_events = optional(list(string), null)
})
| `{}` | no | | [ghes\_ssl\_verify](#input\_ghes\_ssl\_verify) | GitHub Enterprise SSL verification. Set to 'false' when custom certificate (chains) is used for GitHub Enterprise Server (insecure). | `bool` | `true` | no | | [ghes\_url](#input\_ghes\_url) | GitHub Enterprise Server URL. Example: https://github.internal.co - DO NOT SET IF USING PUBLIC GITHUB. However if you are using Github Enterprise Cloud with data-residency (ghe.com), set the endpoint here. Example - https://companyname.ghe.com | `string` | `null` | no | -| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app.
You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes.
If you chose to provide the configuration values directly here,
please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| `{}` | no | +| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app.
You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes.
If you chose to provide the configuration values directly here,
please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| n/a | yes | | [idle\_config](#input\_idle\_config) | List of time periods, defined as a cron expression, to keep a minimum amount of runners active instead of scaling down to 0. By defining this list you can ensure that in time periods that match the cron expression within 5 seconds a runner is kept idle. |
list(object({
cron = string
timeZone = string
idleCount = number
evictionStrategy = optional(string, "oldest_first")
}))
| `[]` | no | | [instance\_allocation\_strategy](#input\_instance\_allocation\_strategy) | The allocation strategy for spot instances. AWS recommends using `price-capacity-optimized` however the AWS default is `lowest-price`. | `string` | `"lowest-price"` | no | | [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 | diff --git a/modules/multi-runner/README.md b/modules/multi-runner/README.md index f62861e9fc..f9eb1b6f9f 100644 --- a/modules/multi-runner/README.md +++ b/modules/multi-runner/README.md @@ -131,7 +131,7 @@ module "multi-runner" { | [eventbridge](#input\_eventbridge) | Enable the use of EventBridge by the module. By enabling this feature events will be put on the EventBridge by the webhook instead of directly dispatching to queues for scaling. |
object({
enable = optional(bool, true)
accept_events = optional(list(string), [])
})
| `{}` | no | | [ghes\_ssl\_verify](#input\_ghes\_ssl\_verify) | GitHub Enterprise SSL verification. Set to 'false' when custom certificate (chains) is used for GitHub Enterprise Server (insecure). | `bool` | `true` | no | | [ghes\_url](#input\_ghes\_url) | GitHub Enterprise Server URL. Example: https://github.internal.co - DO NOT SET IF USING PUBLIC GITHUB. .However if you are using Github Enterprise Cloud with data-residency (ghe.com), set the endpoint here. Example - https://companyname.ghe.com\| | `string` | `null` | no | -| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app.
You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes.
If you chose to provide the configuration values directly here,
please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| `{}` | no | +| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app.
You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes.
If you chose to provide the configuration values directly here,
please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| n/a | yes | | [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\_termination\_watcher](#input\_instance\_termination\_watcher) | Configuration for the spot termination watcher lambda function. This feature is Beta, changes will not trigger a major release as long in beta.

`enable`: Enable or disable the spot termination watcher.
`memory_size`: Memory size linit in MB of the lambda.
`s3_key`: S3 key for syncer lambda function. Required if using S3 bucket to specify lambdas.
`s3_object_version`: S3 object version for syncer lambda function. Useful if S3 versioning is enabled on source bucket.
`timeout`: Time out of the lambda in seconds.
`zip`: File location of the lambda zip file. |
object({
enable = optional(bool, false)
features = optional(object({
enable_spot_termination_handler = optional(bool, true)
enable_spot_termination_notification_watcher = optional(bool, true)
}), {})
memory_size = optional(number, null)
s3_key = optional(string, null)
s3_object_version = optional(string, null)
timeout = optional(number, null)
zip = optional(string, null)
})
| `{}` | no | | [key\_name](#input\_key\_name) | Key pair name | `string` | `null` | no | diff --git a/modules/ssm/README.md b/modules/ssm/README.md index 65bb14ee7b..a2f0d8e34f 100644 --- a/modules/ssm/README.md +++ b/modules/ssm/README.md @@ -34,7 +34,7 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| n/a | yes | +| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app.
You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes.
If you chose to provide the configuration values directly here,
please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| n/a | yes | | [kms\_key\_arn](#input\_kms\_key\_arn) | Optional CMK Key ARN to be used for Parameter Store. | `string` | `null` | no | | [path\_prefix](#input\_path\_prefix) | The path prefix used for naming resources | `string` | n/a | yes | | [tags](#input\_tags) | Map of tags that will be added to created resources. By default resources will be tagged with name and environment. | `map(string)` | `{}` | no | From 64bda92fa436dcfcca031608c81359bef74dce95 Mon Sep 17 00:00:00 2001 From: AppliNH Date: Tue, 18 Feb 2025 17:03:07 +0100 Subject: [PATCH 13/24] other(vars github_app): add note regarding precedence --- modules/multi-runner/variables.tf | 1 + modules/ssm/variables.tf | 1 + variables.tf | 1 + 3 files changed, 3 insertions(+) diff --git a/modules/multi-runner/variables.tf b/modules/multi-runner/variables.tf index df52689abe..ff4419d4d9 100644 --- a/modules/multi-runner/variables.tf +++ b/modules/multi-runner/variables.tf @@ -4,6 +4,7 @@ variable "github_app" { You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes. If you chose to provide the configuration values directly here, please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). + Note: the provided SSM parameters arn and name have a precedence over the actual value (i.e `key_base64_ssm` has a precedence over `key_base64` etc). EOF type = object({ key_base64 = optional(string) diff --git a/modules/ssm/variables.tf b/modules/ssm/variables.tf index 367f8d64c0..1eb796aea7 100644 --- a/modules/ssm/variables.tf +++ b/modules/ssm/variables.tf @@ -4,6 +4,7 @@ variable "github_app" { You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes. If you chose to provide the configuration values directly here, please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). + Note: the provided SSM parameters arn and name have a precedence over the actual value (i.e `key_base64_ssm` has a precedence over `key_base64` etc). EOF type = object({ key_base64 = optional(string) diff --git a/variables.tf b/variables.tf index 84276c62c6..cb30dcef5d 100644 --- a/variables.tf +++ b/variables.tf @@ -37,6 +37,7 @@ variable "github_app" { You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes. If you chose to provide the configuration values directly here, please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). + Note: the provided SSM parameters arn and name have a precedence over the actual value (i.e `key_base64_ssm` has a precedence over `key_base64` etc). EOF type = object({ key_base64 = optional(string) From af32f7e177a58af8dbc8f70579cb305890f68b78 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 18 Feb 2025 16:04:02 +0000 Subject: [PATCH 14/24] docs: auto update terraform docs --- README.md | 2 +- modules/multi-runner/README.md | 2 +- modules/ssm/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fde97b16e0..67a7438819 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ Join our discord community via [this invite link](https://discord.gg/bxgXW8jJGh) | [eventbridge](#input\_eventbridge) | Enable the use of EventBridge by the module. By enabling this feature events will be put on the EventBridge by the webhook instead of directly dispatching to queues for scaling.

`enable`: Enable the EventBridge feature.
`accept_events`: List can be used to only allow specific events to be putted on the EventBridge. By default all events, empty list will be be interpreted as all events. |
object({
enable = optional(bool, true)
accept_events = optional(list(string), null)
})
| `{}` | no | | [ghes\_ssl\_verify](#input\_ghes\_ssl\_verify) | GitHub Enterprise SSL verification. Set to 'false' when custom certificate (chains) is used for GitHub Enterprise Server (insecure). | `bool` | `true` | no | | [ghes\_url](#input\_ghes\_url) | GitHub Enterprise Server URL. Example: https://github.internal.co - DO NOT SET IF USING PUBLIC GITHUB. However if you are using Github Enterprise Cloud with data-residency (ghe.com), set the endpoint here. Example - https://companyname.ghe.com | `string` | `null` | no | -| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app.
You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes.
If you chose to provide the configuration values directly here,
please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| n/a | yes | +| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app.
You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes.
If you chose to provide the configuration values directly here,
please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`).
Note: the provided SSM parameters arn and name have a precedence over the actual value (i.e `key_base64_ssm` has a precedence over `key_base64` etc). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| n/a | yes | | [idle\_config](#input\_idle\_config) | List of time periods, defined as a cron expression, to keep a minimum amount of runners active instead of scaling down to 0. By defining this list you can ensure that in time periods that match the cron expression within 5 seconds a runner is kept idle. |
list(object({
cron = string
timeZone = string
idleCount = number
evictionStrategy = optional(string, "oldest_first")
}))
| `[]` | no | | [instance\_allocation\_strategy](#input\_instance\_allocation\_strategy) | The allocation strategy for spot instances. AWS recommends using `price-capacity-optimized` however the AWS default is `lowest-price`. | `string` | `"lowest-price"` | no | | [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 | diff --git a/modules/multi-runner/README.md b/modules/multi-runner/README.md index f9eb1b6f9f..dca32e2662 100644 --- a/modules/multi-runner/README.md +++ b/modules/multi-runner/README.md @@ -131,7 +131,7 @@ module "multi-runner" { | [eventbridge](#input\_eventbridge) | Enable the use of EventBridge by the module. By enabling this feature events will be put on the EventBridge by the webhook instead of directly dispatching to queues for scaling. |
object({
enable = optional(bool, true)
accept_events = optional(list(string), [])
})
| `{}` | no | | [ghes\_ssl\_verify](#input\_ghes\_ssl\_verify) | GitHub Enterprise SSL verification. Set to 'false' when custom certificate (chains) is used for GitHub Enterprise Server (insecure). | `bool` | `true` | no | | [ghes\_url](#input\_ghes\_url) | GitHub Enterprise Server URL. Example: https://github.internal.co - DO NOT SET IF USING PUBLIC GITHUB. .However if you are using Github Enterprise Cloud with data-residency (ghe.com), set the endpoint here. Example - https://companyname.ghe.com\| | `string` | `null` | no | -| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app.
You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes.
If you chose to provide the configuration values directly here,
please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| n/a | yes | +| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app.
You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes.
If you chose to provide the configuration values directly here,
please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`).
Note: the provided SSM parameters arn and name have a precedence over the actual value (i.e `key_base64_ssm` has a precedence over `key_base64` etc). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| n/a | yes | | [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\_termination\_watcher](#input\_instance\_termination\_watcher) | Configuration for the spot termination watcher lambda function. This feature is Beta, changes will not trigger a major release as long in beta.

`enable`: Enable or disable the spot termination watcher.
`memory_size`: Memory size linit in MB of the lambda.
`s3_key`: S3 key for syncer lambda function. Required if using S3 bucket to specify lambdas.
`s3_object_version`: S3 object version for syncer lambda function. Useful if S3 versioning is enabled on source bucket.
`timeout`: Time out of the lambda in seconds.
`zip`: File location of the lambda zip file. |
object({
enable = optional(bool, false)
features = optional(object({
enable_spot_termination_handler = optional(bool, true)
enable_spot_termination_notification_watcher = optional(bool, true)
}), {})
memory_size = optional(number, null)
s3_key = optional(string, null)
s3_object_version = optional(string, null)
timeout = optional(number, null)
zip = optional(string, null)
})
| `{}` | no | | [key\_name](#input\_key\_name) | Key pair name | `string` | `null` | no | diff --git a/modules/ssm/README.md b/modules/ssm/README.md index a2f0d8e34f..f8ca2f9453 100644 --- a/modules/ssm/README.md +++ b/modules/ssm/README.md @@ -34,7 +34,7 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app.
You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes.
If you chose to provide the configuration values directly here,
please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| n/a | yes | +| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app.
You can optionally create the SSM parameters yourself and provide the ARN and name here, through the `*_ssm` attributes.
If you chose to provide the configuration values directly here,
please ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`).
Note: the provided SSM parameters arn and name have a precedence over the actual value (i.e `key_base64_ssm` has a precedence over `key_base64` etc). |
object({
key_base64 = optional(string)
key_base64_ssm = optional(object({
arn = string
name = string
}))
id = optional(string)
id_ssm = optional(object({
arn = string
name = string
}))
webhook_secret = optional(string)
webhook_secret_ssm = optional(object({
arn = string
name = string
}))
})
| n/a | yes | | [kms\_key\_arn](#input\_kms\_key\_arn) | Optional CMK Key ARN to be used for Parameter Store. | `string` | `null` | no | | [path\_prefix](#input\_path\_prefix) | The path prefix used for naming resources | `string` | n/a | yes | | [tags](#input\_tags) | Map of tags that will be added to created resources. By default resources will be tagged with name and environment. | `map(string)` | `{}` | no | From 3b799b23047543362f2b29badb1f9d909daacfd0 Mon Sep 17 00:00:00 2001 From: AppliNH Date: Tue, 18 Feb 2025 17:25:35 +0100 Subject: [PATCH 15/24] doc: add note regarde github app secrets in SSM --- docs/configuration.md | 50 ++++++++++++++----- docs/examples/external-managed-ssm-secrets.md | 1 + 2 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 docs/examples/external-managed-ssm-secrets.md diff --git a/docs/configuration.md b/docs/configuration.md index c7f53121ed..bdf1e72bea 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -10,7 +10,7 @@ To be able to support a number of use-cases, the module has quite a lot of confi - Linux vs Windows. You can configure the OS types linux and win. Linux will be used by default. - Re-use vs Ephemeral. By default runners are re-used, until detected idle. Once idle they will be removed from the pool. To improve security we are introducing ephemeral runners. Those runners are only used for one job. Ephemeral runners only work in combination with the workflow job event. For ephemeral runners the lambda requests a JIT (just in time) configuration via the GitHub API to register the runner. [JIT configuration](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-just-in-time-runners) is limited to ephemeral runners (and currently not supported by GHES). For non-ephemeral runners, a registration token is always requested. In both cases the configuration is made available to the instance via the same SSM parameter. To disable JIT configuration for ephemeral runners set `enable_jit_config` to `false`. We also suggest using a pre-build AMI to improve the start time of jobs for ephemeral runners. - Job retry (**Beta**). By default the scale-up lambda will discard the message when it is handled. Meaning in the ephemeral use-case an instance is created. The created runner will ask GitHub for a job, no guarantee it will run the job for which it was scaling. Result could be that with small system hick-up the job is keeping waiting for a runner. Enable a pool (org runners) is one option to avoid this problem. Another option is to enable the job retry function. Which will retry the job after a delay for a configured number of times. -- GitHub Cloud vs GitHub Enterprise Server (GHES). The runners support GitHub Cloud (Public GitHub - github.com), GitHub Data Residency instances (ghe.com), and GitHub Enterprise Server. For GHES, we rely on our community for support and testing. We have no capability to test GHES ourselves. +- GitHub Cloud vs GitHub Enterprise Server (GHES). The runners support GitHub Cloud (Public GitHub - github.com), GitHub Data Residency instances (ghe.com), and GitHub Enterprise Server. For GHES, we rely on our community for support and testing. We have no capability to test GHES ourselves. - Spot vs on-demand. The runners use either the EC2 spot or on-demand life cycle. Runners will be created via the AWS [CreateFleet API](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateFleet.html). The module (scale up lambda) will request via the CreateFleet API to create instances in one of the subnets and of the specified instance types. - ARM64 support via Graviton/Graviton2 instance-types. When using the default example or top-level module, specifying `instance_types` that match a Graviton/Graviton 2 (ARM64) architecture (e.g. a1, t4g or any 6th-gen `g` or `gd` type), you must also specify `runner_architecture = "arm64"` and the sub-modules will be automatically configured to provision with ARM64 AMIs and leverage GitHub's ARM64 action runner. See below for more details. - Disable default labels for the runners (os, architecture and `self-hosted`) can achieve by setting `runner_disable_default_labels` = true. If enabled, the runner will only have the extra labels provided in `runner_extra_labels`. In case you on own start script is used, this configuration parameter needs to be parsed via SSM. @@ -24,17 +24,44 @@ The module uses the AWS System Manager Parameter Store to store configuration fo | `ssm_paths.root/var.prefix?/app/` | App secrets used by Lambda's | | `ssm_paths.root/var.prefix?/runners/config/` | Configuration parameters used by runner start script | | `ssm_paths.root/var.prefix?/runners/tokens/` | Either JIT configuration (ephemeral runners) or registration tokens (non ephemeral runners) generated by the control plane (scale-up lambda), and consumed by the start script on the runner to activate / register the runner. | -| `ssm_paths.root/var.prefix?/webhook/runner-matcher-config` | Runner matcher config used by webhook to decide the target for the webhook event. | +| `ssm_paths.root/var.prefix?/webhook/runner-matcher-config` | Runner matcher config used by webhook to decide the target for the webhook event. | Available configuration parameters: -| Parameter name | Description | -|-------------------------------------|---------------------------------------------------------------------------------------------------| -| `agent_mode` | Indicates if the agent is running in ephemeral mode or not. | -| `disable_default_labels` | Indicates if the default labels for the runners (os, architecture and `self-hosted`) are disabled | -| `enable_cloudwatch` | Configuration for the cloudwatch agent to stream logging. | -| `run_as` | The user used for running the GitHub action runner agent. | -| `token_path` | The path where tokens are stored. | +| Parameter name | Description | +| ------------------------ | ------------------------------------------------------------------------------------------------- | +| `agent_mode` | Indicates if the agent is running in ephemeral mode or not. | +| `disable_default_labels` | Indicates if the default labels for the runners (os, architecture and `self-hosted`) are disabled | +| `enable_cloudwatch` | Configuration for the cloudwatch agent to stream logging. | +| `run_as` | The user used for running the GitHub action runner agent. | +| `token_path` | The path where tokens are stored. | + +### Note regarding GitHub App secrets provisioning in SSM + +SSM parameters for GitHub App secrets (`webhook_secret`, `key_base64`, `id`) can also be manually created at the SSM path of your choice. + +If you opt for this approach, please fill the `*_ssm` attributes of the `github_app` variable as following: + +``` +github_app = { + key_base64_ssm = { + name = "/your/path/to/ssm/parameter/key-base-64" + arn = "arn:aws:ssm:eu-west-3:402738628039:parameter/your/path/to/ssm/parameter/key-base-64" + } + id_ssm = { + name = "/your/path/to/ssm/parameter/id" + arn = "arn:aws:ssm:eu-west-3:402738628039:parameter/your/path/to/ssm/parameter/id" + } + webhook_secret_ssm = { + name = "/your/path/to/ssm/parameter/webhook-secret" + arn = "arn:aws:ssm:eu-west-3:402738628039:parameter/your/path/to/ssm/parameter/webhook-secret" + } + } +``` + +Manually creating the SSM parameters that hold the configuration of your GitHub App avoids leaking critical plain text values in your terraform state and version control system. This is a recommended security practice for handling sensitive credentials. + +You can read more [over here](../examples/external-managed-ssm-secrets/README.md). ## Encryption @@ -124,7 +151,6 @@ You can configure runners to be ephemeral, in which case runners will be used on The example for [ephemeral runners](examples/ephemeral.md) is based on the [default example](examples/default.md). Have look at the diff to see the major configuration differences. - ## Job retry (**Beta**) You can enable the job retry function to retry a job after a delay for a configured number of times. The function is disabled by default. To enable the function set `job_retry.enable` to `true`. The function will check the job status after a delay, and when the is still queued, it will create a new runner. The new runner is created in the same way as the others via the scale-up function. Hence the same configuration applies. @@ -133,7 +159,6 @@ For checking the job status a API call is made to GitHub. Which can exhaust the The option `job_retry.delay_in_seconds` is the delay before the job status is checked. The delay is increased by the factor `job_retry.delay_backoff` for each attempt. The upper bound for a delay is 900 seconds, which is the max message delay on SQS. The maximum number of attempts is configured via `job_retry.max_attempts`. The delay should be set to a higher value than the time it takes to start a runner. - ## Prebuilt Images This module also allows you to run agents from a prebuilt AMI to gain faster startup times. The module provides several examples to build your own custom AMI. To remove old images, an [AMI housekeeper module](modules/public/ami-housekeeper.md) can be used. See the [AMI examples](ami-examples/index.md) for more details. @@ -231,7 +256,7 @@ The watcher is listening for spot termination warnings and create a log message ### Termination handler !!! warning - This feature will only work once the CloudTrail is enabled. +This feature will only work once the CloudTrail is enabled. The termination handler is listening for spot terminations by capture the `BidEvictedEvent` via CloudTrail. The handler will log and optionally create a metric for each termination. The intend is to enhance the logic to inform the user about the termination via the GitHub Job or Workflow run. The feature is disabled by default. The feature is enabled once the watcher is enabled, the feature can be disabled explicit by setting `instance_termination_watcher.features.enable_spot_termination_handler = false`. @@ -332,5 +357,4 @@ resource "aws_iam_role_policy" "event_rule_firehose_role" { } ``` - NOTE: By default, a runner AMI update requires a re-apply of this terraform config (the runner AMI ID is looked up by a terraform data source). To avoid this, you can use `ami_id_ssm_parameter_name` to have the scale-up lambda dynamically lookup the runner AMI ID from an SSM parameter at instance launch time. Said SSM parameter is managed outside of this module (e.g. by a runner AMI build workflow). diff --git a/docs/examples/external-managed-ssm-secrets.md b/docs/examples/external-managed-ssm-secrets.md new file mode 100644 index 0000000000..411b843d60 --- /dev/null +++ b/docs/examples/external-managed-ssm-secrets.md @@ -0,0 +1 @@ +--8<-- "examples/external-managed-ssm-secrets/README.md" From e96a56054076a984481ceef2c718c007a613ed71 Mon Sep 17 00:00:00 2001 From: Niek Palm Date: Wed, 19 Feb 2025 21:52:42 +0100 Subject: [PATCH 16/24] chore: adjust examples and add script to easy test example --- .../external-managed-ssm-secrets/README.md | 3 +- examples/external-managed-ssm-secrets/main.tf | 120 +----------------- .../external-managed-ssm-secrets/outputs.tf | 9 +- 3 files changed, 7 insertions(+), 125 deletions(-) diff --git a/examples/external-managed-ssm-secrets/README.md b/examples/external-managed-ssm-secrets/README.md index cbe57bbdb1..e6846b6c57 100644 --- a/examples/external-managed-ssm-secrets/README.md +++ b/examples/external-managed-ssm-secrets/README.md @@ -6,7 +6,7 @@ Manually creating the SSM parameters that hold the configuration of your GitHub ## Prerequisites -Create the following SSM parameters on the AWS console, or by using the following aws-cli commands: +Create the following SSM parameters on the AWS console, or by using the following aws-cli commands, see example below. You can also use the script `ssm.sh`. First set the required values, next source the script before running terraform. ```bash # GitHub App ID @@ -95,5 +95,4 @@ No resources. |------|-------------| | [runners](#output\_runners) | n/a | | [webhook\_endpoint](#output\_webhook\_endpoint) | n/a | -| [webhook\_secret](#output\_webhook\_secret) | n/a | diff --git a/examples/external-managed-ssm-secrets/main.tf b/examples/external-managed-ssm-secrets/main.tf index bf5532a1ad..e390a56792 100644 --- a/examples/external-managed-ssm-secrets/main.tf +++ b/examples/external-managed-ssm-secrets/main.tf @@ -3,10 +3,6 @@ locals { aws_region = var.aws_region } -# resource "random_id" "random" { -# byte_length = 20 -# } - module "base" { source = "../base" @@ -25,58 +21,19 @@ module "runners" { tags = { Project = "ProjectX" } + github_app = { key_base64_ssm = var.github_app_ssm_parameters.key_base64 id_ssm = var.github_app_ssm_parameters.id webhook_secret_ssm = var.github_app_ssm_parameters.webhook_secret } - # configure the block device mappings, default for Amazon Linux2 - # block_device_mappings = [{ - # device_name = "/dev/xvda" - # delete_on_termination = true - # volume_type = "gp3" - # volume_size = 10 - # encrypted = true - # iops = null - # }] - - # When not explicitly set lambda zip files are grapped from the module requiring lambda build. - # Alternatively you can set the path to the lambda zip files here. - # - # For example grab zip files via lambda_download - # webhook_lambda_zip = "../lambdas-download/webhook.zip" - # runner_binaries_syncer_lambda_zip = "../lambdas-download/runner-binaries-syncer.zip" - # runners_lambda_zip = "../lambdas-download/runners.zip" - enable_organization_runners = true runner_extra_labels = ["default", "example"] # enable access to the runners via SSM enable_ssm_on_runners = true - # use S3 or KMS SSE to runners S3 bucket - # runner_binaries_s3_sse_configuration = { - # rule = { - # apply_server_side_encryption_by_default = { - # sse_algorithm = "AES256" - # } - # } - # } - - # enable S3 versioning for runners S3 bucket - # runner_binaries_s3_versioning = "Enabled" - - # Uncommet idle config to have idle runners from 9 to 5 in time zone Amsterdam - # idle_config = [{ - # cron = "* * 9-17 * * *" - # timeZone = "Europe/Amsterdam" - # idleCount = 1 - # }] - - # Let the module manage the service linked role - # create_service_linked_role_spot = true - instance_types = ["m7a.large", "m5.large"] # override delay of events in seconds @@ -86,81 +43,6 @@ module "runners" { # override scaling down scale_down_schedule_expression = "cron(* * * * ? *)" - enable_user_data_debug_logging_runner = true - # prefix GitHub runners with the environment name runner_name_prefix = "${local.environment}_" - - # by default eventbridge is used, see multi-runner example. Here we disable the eventbridge - eventbridge = { - enable = false - } - - # Enable debug logging for the lambda functions - # log_level = "debug" - - # tracing_config = { - # mode = "Active" - # capture_error = true - # capture_http_requests = true - # } - - enable_ami_housekeeper = true - ami_housekeeper_cleanup_config = { - ssmParameterNames = ["*/ami-id"] - minimumDaysOld = 10 - amiFilters = [ - { - Name = "name" - Values = ["*al2023*"] - } - ] - } - - instance_termination_watcher = { - enable = true - } - - # enable metric creation (experimental) - # metrics = { - # enable = true - # metric = { - # enable_spot_termination_warning = true - # enable_job_retry = false - # enable_github_app_rate_limit = false - # } - # } - - # enable job_retry feature. Be careful with this feature, it can lead to you hitting API rate limits. - # job_retry = { - # enable = true - # max_attempts = 1 - # delay_in_seconds = 180 - # } - - # enable CMK instead of aws managed key for encryptions - # kms_key_arn = aws_kms_key.github.arn } - -# ❌ When creating SSM parameters manually to avoid having them in the state, you shouldn't manage the github app settings in the state neither! -# module "webhook_github_app" { -# source = "../../modules/webhook-github-app" -# depends_on = [module.runners] - -# github_app = { -# key_base64 = var.github_app.key_base64 -# id = var.github_app.id -# webhook_secret = random_id.random.hex -# } -# webhook_endpoint = module.runners.webhook.endpoint -# } - -# enable CMK instead of aws managed key for encryptions -# resource "aws_kms_key" "github" { -# is_enabled = true -# } - -# resource "aws_kms_alias" "github" { -# name = "alias/github/action-runners" -# target_key_id = aws_kms_key.github.key_id -# } diff --git a/examples/external-managed-ssm-secrets/outputs.tf b/examples/external-managed-ssm-secrets/outputs.tf index c50214f566..e764e732cd 100644 --- a/examples/external-managed-ssm-secrets/outputs.tf +++ b/examples/external-managed-ssm-secrets/outputs.tf @@ -8,8 +8,9 @@ output "webhook_endpoint" { value = module.runners.webhook.endpoint } -output "webhook_secret" { - sensitive = true - value = random_id.random.hex +output "note" { + value = <<-EOF + The runners are not yet ready to process jobs. Please ensure you updated the GitHub app with the webhook endpoint and secret. + The webhook endpoint is: ${module.runners.webhook.endpoint} + EOF } - From 328eb7422a4290a956be9859b6c371307da01129 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 19 Feb 2025 20:57:36 +0000 Subject: [PATCH 17/24] docs: auto update terraform docs --- examples/external-managed-ssm-secrets/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/external-managed-ssm-secrets/README.md b/examples/external-managed-ssm-secrets/README.md index e6846b6c57..c88c030704 100644 --- a/examples/external-managed-ssm-secrets/README.md +++ b/examples/external-managed-ssm-secrets/README.md @@ -93,6 +93,7 @@ No resources. | Name | Description | |------|-------------| +| [note](#output\_note) | n/a | | [runners](#output\_runners) | n/a | | [webhook\_endpoint](#output\_webhook\_endpoint) | n/a | From 12bffc87aa2dc376e7cd64e591386d05ccff61b3 Mon Sep 17 00:00:00 2001 From: Niek Palm Date: Wed, 19 Feb 2025 22:05:51 +0100 Subject: [PATCH 18/24] add script to setup ssm --- examples/external-managed-ssm-secrets/ssm.sh | 67 ++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100755 examples/external-managed-ssm-secrets/ssm.sh diff --git a/examples/external-managed-ssm-secrets/ssm.sh b/examples/external-managed-ssm-secrets/ssm.sh new file mode 100755 index 0000000000..300882c777 --- /dev/null +++ b/examples/external-managed-ssm-secrets/ssm.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +# NOTE: this script is only for demonstration purposes + +# Script to create SSM parameters outside of Terraform +# and set them as environment variables for Terraform + +APP_ID= +APP_PRIVATE_KEY_FILE= +APP_WEBHOOK_SECRET= +APP_PRIVATE_KEY=$(base64 -i $APP_PRIVATE_KEY_FILE) +SSM_PATH="/github-runners/example/app" + +if [ -z "$APP_ID" ]; then + echo "APP_ID is not set" + exit 1 +fi + +if [ -z "$APP_WEBHOOK_SECRET" ]; then + echo "APP_WEBHOOK_SECRET is not set" + exit 1 +fi + +if [ -z "$APP_PRIVATE_KEY_FILE" ]; then + echo "APP_PRIVATE_KEY_FILE is not set" + exit 1 +fi + + +export AWS_PAGER="" +export AWS_REGION=eu-central-1 +export TF_VAR_aws_region=$AWS_REGION + + +# GitHub App ID +aws ssm put-parameter \ + --name "${SSM_PATH}/github_app_id" \ + --overwrite \ + --value "${APP_ID}" \ + --type "SecureString" + +# GitHub App Private Key +aws ssm put-parameter \ + --name "${SSM_PATH}/github_app_key_base64" \ + --overwrite \ + --value "${APP_PRIVATE_KEY}" \ + --type "SecureString" + +# GitHub App Installation ID +aws ssm put-parameter \ + --name "${SSM_PATH}/github_app_webhook_secret" \ + --overwrite \ + --value "${APP_WEBHOOK_SECRET}" \ + --type "SecureString" + + +github_app_id_ssm=$(aws ssm get-parameter --name "${SSM_PATH}/github_app_id" --query 'Parameter.{arn:ARN,name:Name}' --output json) +github_app_key_base64_ssm=$(aws ssm get-parameter --name "${SSM_PATH}/github_app_key_base64" --query 'Parameter.{arn:ARN,name:Name}' --output json) +github_app_webhook_secret_ssm=$(aws ssm get-parameter --name "${SSM_PATH}/github_app_webhook_secret" --query 'Parameter.{arn:ARN,name:Name}' --output json) + +export TF_VAR_github_app_ssm_parameters="{ + "id": `echo $github_app_id_ssm`, + "key_base64": `echo $github_app_key_base64_ssm`, + "webhook_secret": `echo $github_app_webhook_secret_ssm` +}" + +export TF_VAR_environment=external-ssm From 89673da0a957bf506249ec7eb43e799b632a9e91 Mon Sep 17 00:00:00 2001 From: AppliNH Date: Thu, 20 Feb 2025 11:38:36 +0100 Subject: [PATCH 19/24] doc: clean docs --- docs/configuration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index bdf1e72bea..39240b24d9 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -46,15 +46,15 @@ If you opt for this approach, please fill the `*_ssm` attributes of the `github_ github_app = { key_base64_ssm = { name = "/your/path/to/ssm/parameter/key-base-64" - arn = "arn:aws:ssm:eu-west-3:402738628039:parameter/your/path/to/ssm/parameter/key-base-64" + arn = "arn:aws:ssm:::parameter/your/path/to/ssm/parameter/key-base-64" } id_ssm = { name = "/your/path/to/ssm/parameter/id" - arn = "arn:aws:ssm:eu-west-3:402738628039:parameter/your/path/to/ssm/parameter/id" + arn = "arn:aws:ssm:::parameter/your/path/to/ssm/parameter/id" } webhook_secret_ssm = { name = "/your/path/to/ssm/parameter/webhook-secret" - arn = "arn:aws:ssm:eu-west-3:402738628039:parameter/your/path/to/ssm/parameter/webhook-secret" + arn = "arn:aws:ssm:::parameter/your/path/to/ssm/parameter/webhook-secret" } } ``` From 4422e9337924cf5c85804a1822c5aa7b70e8c509 Mon Sep 17 00:00:00 2001 From: AppliNH Date: Thu, 20 Feb 2025 15:46:21 +0100 Subject: [PATCH 20/24] docs: add example to index --- docs/examples/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/examples/index.md b/docs/examples/index.md index 37b30bbd5e..ac611575fc 100644 --- a/docs/examples/index.md +++ b/docs/examples/index.md @@ -9,3 +9,4 @@ Examples are located in the [examples](https://github.com/github-aws-runners/ter - _[Prebuilt Images](prebuilt.md)_: Example usages of deploying runners with a custom prebuilt image. - _[Windows](windows.md)_: Example usage of creating a runner using Windows as the OS. - _[Termination watcher](termination-watcher.md)_: Example usages of termination watcher. +- _[Externally managed SSM secrets](external-managed-ssm-secrets.md)_: Example usage of externally managed SSM secrets for the GitHub App credentials. From 8006a817a83c9f5739afe352e2db9bb03c9f5459 Mon Sep 17 00:00:00 2001 From: AppliNH Date: Thu, 20 Feb 2025 16:15:40 +0100 Subject: [PATCH 21/24] other(ssm-script docs): escape double quotes and refactor doc --- .../external-managed-ssm-secrets/README.md | 64 ++++++++++++------- examples/external-managed-ssm-secrets/ssm.sh | 6 +- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/examples/external-managed-ssm-secrets/README.md b/examples/external-managed-ssm-secrets/README.md index c88c030704..5a27fe9412 100644 --- a/examples/external-managed-ssm-secrets/README.md +++ b/examples/external-managed-ssm-secrets/README.md @@ -6,7 +6,25 @@ Manually creating the SSM parameters that hold the configuration of your GitHub ## Prerequisites -Create the following SSM parameters on the AWS console, or by using the following aws-cli commands, see example below. You can also use the script `ssm.sh`. First set the required values, next source the script before running terraform. +To configure GitHub App credentials in AWS, you have two options: + +### 1. Using the [`ssm.sh`](./ssm.sh) script + +- Edit [`ssm.sh`](./ssm.sh) and set your values +- Run: `source ssm.sh` +- Then run your Terraform commands (`terraform plan` / `terraform apply`) + +### 2. Create them manually via the AWS console (or the `aws-cli`) + +- Create the following SSM parameters on the AWS console: + +``` +/github-action-runners/app/github_app_id (Your GitHub App ID) +/github-action-runners/app/github_app_key_base64 (Your GitHub App Private Key) +/github-action-runners/app/github_app_webhook_secret (Your Installation ID) +``` + +Example using AWS CLI: ```bash # GitHub App ID @@ -28,7 +46,7 @@ Create the following SSM parameters on the AWS console, or by using the followin --type "SecureString" ``` -Then fill the `arn` and `name` values for each of these inside the [`github_app_ssm_parameters` variable](./variables.tf). +- Fill the `arn` and `name` values for each of these inside the [`github_app_ssm_parameters` variable](./variables.tf). ## Usages @@ -57,14 +75,15 @@ terraform output -raw webhook_secret ``` + ## Requirements -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.3.0 | -| [aws](#requirement\_aws) | ~> 5.27 | -| [local](#requirement\_local) | ~> 2.0 | -| [random](#requirement\_random) | ~> 3.0 | +| Name | Version | +| ------------------------------------------------------------------------ | -------- | +| [terraform](#requirement_terraform) | >= 1.3.0 | +| [aws](#requirement_aws) | ~> 5.27 | +| [local](#requirement_local) | ~> 2.0 | +| [random](#requirement_random) | ~> 3.0 | ## Providers @@ -72,10 +91,10 @@ No providers. ## Modules -| Name | Source | Version | -|------|--------|---------| -| [base](#module\_base) | ../base | n/a | -| [runners](#module\_runners) | ../../ | n/a | +| Name | Source | Version | +| -------------------------------------------------------- | ------- | ------- | +| [base](#module_base) | ../base | n/a | +| [runners](#module_runners) | ../../ | n/a | ## Resources @@ -83,17 +102,18 @@ No resources. ## Inputs -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [aws\_region](#input\_aws\_region) | AWS region. | `string` | `"eu-west-1"` | no | -| [environment](#input\_environment) | Environment name, used as prefix. | `string` | `null` | no | -| [github\_app\_ssm\_parameters](#input\_github\_app\_ssm\_parameters) | SSM parameters details for the GitHub App, that you've created manually on AWS. |
object({
key_base64 = optional(object({
arn = string
name = string
}))
id = optional(object({
arn = string
name = string
}))
webhook_secret = optional(object({
arn = string
name = string
}))
})
| `{}` | no | +| Name | Description | Type | Default | Required | +| ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | :------: | +| [aws_region](#input_aws_region) | AWS region. | `string` | `"eu-west-1"` | no | +| [environment](#input_environment) | Environment name, used as prefix. | `string` | `null` | no | +| [github_app_ssm_parameters](#input_github_app_ssm_parameters) | SSM parameters details for the GitHub App, that you've created manually on AWS. |
object({
key_base64 = optional(object({
arn = string
name = string
}))
id = optional(object({
arn = string
name = string
}))
webhook_secret = optional(object({
arn = string
name = string
}))
})
| `{}` | no | ## Outputs -| Name | Description | -|------|-------------| -| [note](#output\_note) | n/a | -| [runners](#output\_runners) | n/a | -| [webhook\_endpoint](#output\_webhook\_endpoint) | n/a | +| Name | Description | +| ----------------------------------------------------------------------------------- | ----------- | +| [note](#output_note) | n/a | +| [runners](#output_runners) | n/a | +| [webhook_endpoint](#output_webhook_endpoint) | n/a | + diff --git a/examples/external-managed-ssm-secrets/ssm.sh b/examples/external-managed-ssm-secrets/ssm.sh index 300882c777..cfccd5e637 100755 --- a/examples/external-managed-ssm-secrets/ssm.sh +++ b/examples/external-managed-ssm-secrets/ssm.sh @@ -59,9 +59,9 @@ github_app_key_base64_ssm=$(aws ssm get-parameter --name "${SSM_PATH}/github_app github_app_webhook_secret_ssm=$(aws ssm get-parameter --name "${SSM_PATH}/github_app_webhook_secret" --query 'Parameter.{arn:ARN,name:Name}' --output json) export TF_VAR_github_app_ssm_parameters="{ - "id": `echo $github_app_id_ssm`, - "key_base64": `echo $github_app_key_base64_ssm`, - "webhook_secret": `echo $github_app_webhook_secret_ssm` + \"id\": `echo $github_app_id_ssm`, + \"key_base64\": `echo $github_app_key_base64_ssm`, + \"webhook_secret\": `echo $github_app_webhook_secret_ssm` }" export TF_VAR_environment=external-ssm From a1ef8676bb1333913e055decb5be1feaa5611ef0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 20 Feb 2025 15:16:01 +0000 Subject: [PATCH 22/24] docs: auto update terraform docs --- .../external-managed-ssm-secrets/README.md | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/examples/external-managed-ssm-secrets/README.md b/examples/external-managed-ssm-secrets/README.md index 5a27fe9412..dd14d36960 100644 --- a/examples/external-managed-ssm-secrets/README.md +++ b/examples/external-managed-ssm-secrets/README.md @@ -75,15 +75,14 @@ terraform output -raw webhook_secret ``` - ## Requirements -| Name | Version | -| ------------------------------------------------------------------------ | -------- | -| [terraform](#requirement_terraform) | >= 1.3.0 | -| [aws](#requirement_aws) | ~> 5.27 | -| [local](#requirement_local) | ~> 2.0 | -| [random](#requirement_random) | ~> 3.0 | +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3.0 | +| [aws](#requirement\_aws) | ~> 5.27 | +| [local](#requirement\_local) | ~> 2.0 | +| [random](#requirement\_random) | ~> 3.0 | ## Providers @@ -91,10 +90,10 @@ No providers. ## Modules -| Name | Source | Version | -| -------------------------------------------------------- | ------- | ------- | -| [base](#module_base) | ../base | n/a | -| [runners](#module_runners) | ../../ | n/a | +| Name | Source | Version | +|------|--------|---------| +| [base](#module\_base) | ../base | n/a | +| [runners](#module\_runners) | ../../ | n/a | ## Resources @@ -102,18 +101,17 @@ No resources. ## Inputs -| Name | Description | Type | Default | Required | -| ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | :------: | -| [aws_region](#input_aws_region) | AWS region. | `string` | `"eu-west-1"` | no | -| [environment](#input_environment) | Environment name, used as prefix. | `string` | `null` | no | -| [github_app_ssm_parameters](#input_github_app_ssm_parameters) | SSM parameters details for the GitHub App, that you've created manually on AWS. |
object({
key_base64 = optional(object({
arn = string
name = string
}))
id = optional(object({
arn = string
name = string
}))
webhook_secret = optional(object({
arn = string
name = string
}))
})
| `{}` | no | +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [aws\_region](#input\_aws\_region) | AWS region. | `string` | `"eu-west-1"` | no | +| [environment](#input\_environment) | Environment name, used as prefix. | `string` | `null` | no | +| [github\_app\_ssm\_parameters](#input\_github\_app\_ssm\_parameters) | SSM parameters details for the GitHub App, that you've created manually on AWS. |
object({
key_base64 = optional(object({
arn = string
name = string
}))
id = optional(object({
arn = string
name = string
}))
webhook_secret = optional(object({
arn = string
name = string
}))
})
| `{}` | no | ## Outputs -| Name | Description | -| ----------------------------------------------------------------------------------- | ----------- | -| [note](#output_note) | n/a | -| [runners](#output_runners) | n/a | -| [webhook_endpoint](#output_webhook_endpoint) | n/a | - +| Name | Description | +|------|-------------| +| [note](#output\_note) | n/a | +| [runners](#output\_runners) | n/a | +| [webhook\_endpoint](#output\_webhook\_endpoint) | n/a | From 0c4a797018771b3f9f3b608c5aaea2e9d3c3ea6e Mon Sep 17 00:00:00 2001 From: Niek Palm Date: Thu, 20 Feb 2025 16:50:50 +0100 Subject: [PATCH 23/24] chore(ci): add new wexample to workflow --- .github/workflows/terraform.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index ad66e20ac3..8a5accc15d 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -139,6 +139,7 @@ jobs: "ephemeral", "termination-watcher", "multi-runner", + "external-managed-ssm-secrets" ] defaults: run: From ad261066749a2b8d9e01cd2b2882b55a351f382f Mon Sep 17 00:00:00 2001 From: Niek Palm Date: Fri, 21 Feb 2025 09:08:31 +0100 Subject: [PATCH 24/24] chore: small fixes --- examples/default/README.md | 2 +- examples/multi-runner/README.md | 2 +- mkdocs.yaml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/default/README.md b/examples/default/README.md index 771b2c7bab..f3129d71bc 100644 --- a/examples/default/README.md +++ b/examples/default/README.md @@ -6,7 +6,7 @@ This module shows how to create GitHub action runners. Lambda release will be do Steps for the full setup, such as creating a GitHub app can be found in the root module's [README](https://github.com/github-aws-runners/terraform-aws-github-runner). First download the Lambda releases from GitHub. Alternatively you can build the lambdas locally with Node or Docker, there is a simple build script in `/.ci/build.sh`. In the `main.tf` you can simply remove the location of the lambda zip files, the default location will work in this case. -> The default example assumes local built lambda's available. Ensure you have built the lambda's. Alternativly you can downlowd the lambda's. The version needs to be set to a GitHub release version, see https://github.com/github-aws-runners/terraform-aws-github-runner/releases +> The default example assumes local built lambda's available. Ensure you have built the lambda's. Alternatively you can download the lambda's. The version needs to be set to a GitHub release version, see https://github.com/github-aws-runners/terraform-aws-github-runner/releases ```bash cd ../lambdas-download diff --git a/examples/multi-runner/README.md b/examples/multi-runner/README.md index 70b2220f89..0a4bb295e1 100644 --- a/examples/multi-runner/README.md +++ b/examples/multi-runner/README.md @@ -23,7 +23,7 @@ Per combination of OS and architecture a lambda distribution syncer will be crea Steps for the full setup, such as creating a GitHub app can be found the [docs](https://github-aws-runners.github.io/terraform-aws-github-runner/). First download the Lambda releases from GitHub. Alternatively you can build the lambdas locally with Node or Docker, there is a simple build script in `/.ci/build.sh`. In the `main.tf` you can simply remove the location of the lambda zip files, the default location will work in this case. -> The default example assumes local built lambda's available. Ensure you have built the lambda's. Alternativly you can downlowd the lambda's. The version needs to be set to a GitHub release version, see https://github.com/github-aws-runners/terraform-aws-github-runner/releases +> The default example assumes local built lambda's available. Ensure you have built the lambda's. Alternatively you can download the lambda's. The version needs to be set to a GitHub release version, see https://github.com/github-aws-runners/terraform-aws-github-runner/releases ```bash cd ../lambdas-download diff --git a/mkdocs.yaml b/mkdocs.yaml index 1fe9cb301f..d4bb359f42 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -70,6 +70,7 @@ nav: - Default: examples/default.md - Multi Runner: examples/multi-runner.md - Ephemeral: examples/ephemeral.md + - External managed secrets: examples/external-managed-ssm-secrets.md - Custom AMI: examples/prebuilt.md - Termination watcher: examples/termination-watcher.md - Lambda download: examples/lambda-download.md