From 5d00f6150c462a3600a1284a9fce913a215d2773 Mon Sep 17 00:00:00 2001 From: Matthias Kay Date: Sun, 9 Feb 2025 11:41:11 +0100 Subject: [PATCH 01/13] move runner config into separate template --- main.tf | 17 ++++++++++++----- modules/terminate-agent-hook/README.md | 2 +- template/runner-agent.tftpl | 9 +++++++++ ...ner-config.tftpl => runner-definition.tftpl} | 7 ------- 4 files changed, 22 insertions(+), 13 deletions(-) create mode 100644 template/runner-agent.tftpl rename template/{runner-config.tftpl => runner-definition.tftpl} (88%) diff --git a/main.tf b/main.tf index 423a09b00..1be3b7b5a 100644 --- a/main.tf +++ b/main.tf @@ -107,7 +107,7 @@ locals { }] }) - template_runner_config = templatefile("${path.module}/template/runner-config.tftpl", + template_runner_worker_config = templatefile("${path.module}/template/runner-worker-config.tftpl", { aws_region = data.aws_region.current.name gitlab_url = var.runner_gitlab.url @@ -123,27 +123,34 @@ locals { runners_token = var.runner_gitlab.registration_token runners_executor = var.runner_worker.type runners_limit = var.runner_worker.max_jobs - runners_concurrent = var.runner_manager.maximum_concurrent_jobs runners_environment_vars = jsonencode(var.runner_worker.environment_variables) runners_pre_build_script = var.runner_worker_gitlab_pipeline.pre_build_script runners_post_build_script = var.runner_worker_gitlab_pipeline.post_build_script runners_pre_clone_script = var.runner_worker_gitlab_pipeline.pre_clone_script runners_request_concurrency = var.runner_worker.request_concurrency runners_output_limit = var.runner_worker.output_limit - runners_check_interval = var.runner_manager.gitlab_check_interval runners_volumes_tmpfs = join("\n", [for v in var.runner_worker_docker_volumes_tmpfs : format("\"%s\" = \"%s\"", v.volume, v.options)]) runners_services_volumes_tmpfs = join("\n", [for v in var.runner_worker_docker_services_volumes_tmpfs : format("\"%s\" = \"%s\"", v.volume, v.options)]) runners_docker_services = local.runners_docker_services runners_docker_options = local.runners_docker_options_toml bucket_name = local.bucket_name shared_cache = var.runner_worker_cache.shared - sentry_dsn = var.runner_manager.sentry_dsn - prometheus_listen_address = var.runner_manager.prometheus_listen_address auth_type = var.runner_worker_cache.authentication_type runners_docker_autoscaler = var.runner_worker.type == "docker-autoscaler" ? local.template_runner_docker_autoscaler : "" runners_docker_machine = var.runner_worker.type == "docker+machine" ? local.template_runner_docker_machine : "" } ) + + template_runner_config = templatefile("runner-agent.tftpl", + { + prometheus_listen_address = var.runner_manager.prometheus_listen_address + runners_check_interval = var.runner_manager.gitlab_check_interval + runners_concurrent = var.runner_manager.maximum_concurrent_jobs + sentry_dsn = var.runner_manager.sentry_dsn + + runners = [local.template_runner_worker_config] + } + ) } # ignores: Autoscaling Groups Supply Tags --> we use a "dynamic" block to create the tags diff --git a/modules/terminate-agent-hook/README.md b/modules/terminate-agent-hook/README.md index e9cb26531..a1e936c9a 100644 --- a/modules/terminate-agent-hook/README.md +++ b/modules/terminate-agent-hook/README.md @@ -7,7 +7,7 @@ This module is used __internally__ by the parent [_terraform\-aws\-gitlab\-runne ## Overview The Lambda functions evaluates an EC2 instance tag called `gitlab-runner-parent-id`, set in the -[runner config](../../template/runner-config.tftpl) by the parent module's +[runner config](../../template/runner-agent.tftpl) by the parent module's [user data](../../template/gitlab-runner.tftpl). Runner instances created by the runner will have this tag applied with the parent runner's instance ID. When the runner in the ASG is terminated, the lifecycle hook triggers the Lambda to diff --git a/template/runner-agent.tftpl b/template/runner-agent.tftpl new file mode 100644 index 000000000..dd8141701 --- /dev/null +++ b/template/runner-agent.tftpl @@ -0,0 +1,9 @@ +concurrent = ${runners_concurrent} +check_interval = ${runners_check_interval} +sentry_dsn = "${sentry_dsn}" +log_format = "json" +listen_address = "${prometheus_listen_address}" + +́%{ for runner_config in runners } +${runner_config} +%{ endfor } diff --git a/template/runner-config.tftpl b/template/runner-definition.tftpl similarity index 88% rename from template/runner-config.tftpl rename to template/runner-definition.tftpl index aabf0f3de..97d53f1b2 100644 --- a/template/runner-config.tftpl +++ b/template/runner-definition.tftpl @@ -1,9 +1,3 @@ -concurrent = ${runners_concurrent} -check_interval = ${runners_check_interval} -sentry_dsn = "${sentry_dsn}" -log_format = "json" -listen_address = "${prometheus_listen_address}" - [[runners]] name = "${runners_name}" url = "${gitlab_url}" @@ -51,4 +45,3 @@ listen_address = "${prometheus_listen_address}" ${key} = ${value} %{~ endfor ~} %{~ endfor ~} - From 729207098f2bf6ac71da498d0fad0ba720da8eb5 Mon Sep 17 00:00:00 2001 From: Matthias Kay Date: Sun, 9 Feb 2025 12:49:28 +0100 Subject: [PATCH 02/13] fix variables --- docker_machine.tf | 38 -------- locals.tf | 41 +-------- main.tf | 73 ++++----------- modules/runner-config/locals.tf | 138 +++++++++++++++++++++++++++++ modules/runner-config/main.tf | 1 + modules/runner-config/outputs.tf | 4 + modules/runner-config/variables.tf | 49 ++++++++++ tags.tf | 7 -- 8 files changed, 209 insertions(+), 142 deletions(-) create mode 100644 modules/runner-config/locals.tf create mode 100644 modules/runner-config/main.tf create mode 100644 modules/runner-config/outputs.tf create mode 100644 modules/runner-config/variables.tf diff --git a/docker_machine.tf b/docker_machine.tf index cd5d255d2..e83324aa6 100644 --- a/docker_machine.tf +++ b/docker_machine.tf @@ -1,41 +1,3 @@ -locals { - template_runner_docker_machine = templatefile("${path.module}/template/runner-docker-machine-config.tftpl", - { - runners_idle_count = var.runner_worker_docker_machine_instance.idle_count - runners_idle_time = var.runner_worker_docker_machine_instance.idle_time - runners_max_builds = local.runners_max_builds_string - docker_machine_name = format("%s-%s", local.runner_tags_merged["Name"], "%s") # %s is always needed - runners_instance_types = var.runner_worker_docker_machine_instance.types - aws_region = data.aws_region.current.name - runners_aws_zone = data.aws_availability_zone.runners.name_suffix - runners_userdata = var.runner_worker_docker_machine_instance.start_script - - runners_vpc_id = var.vpc_id - runners_subnet_id = var.subnet_id - runners_subnet_ids = length(var.runner_worker_docker_machine_instance.subnet_ids) > 0 ? var.runner_worker_docker_machine_instance.subnet_ids : [var.subnet_id] - runners_instance_profile = var.runner_worker.type == "docker+machine" ? aws_iam_instance_profile.docker_machine[0].name : "" - - runners_use_private_address_only = var.runner_worker_docker_machine_instance.private_address_only - runners_use_private_address = !var.runner_worker_docker_machine_instance.private_address_only - runners_request_spot_instance = var.runner_worker_docker_machine_instance_spot.enable - runners_spot_price_bid = var.runner_worker_docker_machine_instance_spot.max_price == "on-demand-price" || var.runner_worker_docker_machine_instance_spot.max_price == null ? "" : var.runner_worker_docker_machine_instance_spot.max_price - runners_security_group_name = var.runner_worker.type == "docker+machine" ? aws_security_group.docker_machine[0].name : "" - - runners_tags = replace(replace(local.runner_tags_string, ",,", ","), "/,$/", "") - runners_ebs_optimized = var.runner_worker_docker_machine_instance.ebs_optimized - runners_monitoring = var.runner_worker_docker_machine_instance.monitoring - runners_iam_instance_profile_name = var.runner_worker_docker_machine_role.profile_name - runners_root_size = var.runner_worker_docker_machine_instance.root_size - runners_volume_type = var.runner_worker_docker_machine_instance.volume_type - runners_ami = var.runner_worker.type == "docker+machine" ? (length(var.runner_worker_docker_machine_ami_id) > 0 ? var.runner_worker_docker_machine_ami_id : data.aws_ami.docker_machine_by_filter[0].id) : "" - use_fleet = var.runner_worker_docker_machine_fleet.enable - launch_template = var.runner_worker_docker_machine_fleet.enable == true ? aws_launch_template.fleet_gitlab_runner[0].name : "" - docker_machine_options = length(local.docker_machine_options_string) == 1 ? "" : local.docker_machine_options_string - runners_max_growth_rate = var.runner_worker_docker_machine_instance.max_growth_rate - runners_volume_kms_key = local.kms_key_arn - }) -} - resource "aws_iam_instance_profile" "docker_machine" { count = var.runner_worker.type == "docker+machine" ? 1 : 0 name = "${local.name_iam_objects}-docker-machine" diff --git a/locals.tf b/locals.tf index a4e089bf0..538ee7bad 100644 --- a/locals.tf +++ b/locals.tf @@ -44,28 +44,7 @@ locals { ) aws_iam_role_instance_arn = "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role/${local.aws_iam_role_instance_name}" - # Convert list to a string separated and prepend by a comma - docker_machine_options_string = format( - ",\"amazonec2-metadata-token=${var.runner_worker_docker_machine_ec2_metadata_options.http_tokens}\", \"amazonec2-metadata-token-response-hop-limit=${var.runner_worker_docker_machine_ec2_metadata_options.http_put_response_hop_limit}\",%s", - join(",", formatlist("%q", concat(var.runner_worker_docker_machine_ec2_options, local.runners_docker_registry_mirror_option))), - ) - - runners_docker_registry_mirror_option = var.runner_worker_docker_machine_instance.docker_registry_mirror_url == "" ? [] : ["engine-registry-mirror=${var.runner_worker_docker_machine_instance.docker_registry_mirror_url}"] - - runners_docker_options_toml = templatefile("${path.module}/template/runners_docker_options.tftpl", { - options = merge({ - for key, value in var.runner_worker_docker_options : key => value if value != null && key != "volumes" && key != "pull_policies" - }, { - pull_policy = var.runner_worker_docker_options.pull_policies - volumes = local.runners_volumes - }) - } - ) - - # Ensure max builds is optional - runners_max_builds_string = var.runner_worker_docker_machine_instance.destroy_after_max_builds == 0 ? "" : format("MaxBuilds = %d", var.runner_worker_docker_machine_instance.destroy_after_max_builds) - - # Define key for runner token for SSM + # Define key for runner token for SSM secure_parameter_store_runner_token_key = "${var.environment}-${var.runner_gitlab_token_secure_parameter_store}" secure_parameter_store_runner_sentry_dsn = "${var.environment}-${var.runner_sentry_secure_parameter_store_name}" @@ -74,24 +53,6 @@ locals { name_sg = var.security_group_prefix == "" ? local.tags["Name"] : var.security_group_prefix name_iam_objects = var.iam_object_prefix == "" ? local.tags["Name"] : var.iam_object_prefix - runners_volumes = concat(var.runner_worker_docker_options.volumes, var.runner_worker_docker_add_dind_volumes ? ["/certs/client", "/builds", "/var/run/docker.sock:/var/run/docker.sock"] : []) - - runners_docker_services = templatefile("${path.module}/template/runners_docker_services.tftpl", { - runners_docker_services = var.runner_worker_docker_services - } - ) - - /* determines if the docker machine executable adds the Name tag automatically (versions >= 0.16.2) */ - # make sure to skip pre-release stuff in the semver by ignoring everything after "-" - docker_machine_version_used = split(".", split("-", var.runner_install.docker_machine_version)[0]) - docker_machine_version_with_name_tag = split(".", "0.16.2") - docker_machine_version_test = [ - for i, j in reverse(range(length(local.docker_machine_version_used))) - : signum(local.docker_machine_version_with_name_tag[i] - local.docker_machine_version_used[i]) * pow(10, j) - ] - - docker_machine_adds_name_tag = signum(sum(local.docker_machine_version_test)) <= 0 - runner_worker_graceful_terminate_heartbeat_timeout = (var.runner_terminate_ec2_lifecycle_timeout_duration == null ? min(7200, tonumber(coalesce(var.runner_gitlab_registration_config.maximum_timeout, 0)) + 300) : var.runner_terminate_ec2_lifecycle_timeout_duration) diff --git a/main.tf b/main.tf index 1be3b7b5a..151a0f12b 100644 --- a/main.tf +++ b/main.tf @@ -85,62 +85,6 @@ locals { fleeting_plugin_version = var.runner_worker_docker_autoscaler.fleeting_plugin_version }) - template_runner_docker_autoscaler = templatefile("${path.module}/template/runner-docker-autoscaler-config.tftpl", - { - docker_autoscaling_name = var.runner_worker.type == "docker-autoscaler" ? aws_autoscaling_group.autoscaler[0].name : "" - connector_config_user = var.runner_worker_docker_autoscaler.connector_config_user - runners_capacity_per_instance = var.runner_worker_docker_autoscaler.capacity_per_instance - runners_max_use_count = var.runner_worker_docker_autoscaler.max_use_count - runners_max_instances = var.runner_worker.max_jobs - - runners_update_interval = var.runner_worker_docker_autoscaler.update_interval - runners_update_interval_when_expecting = var.runner_worker_docker_autoscaler.update_interval_when_expecting - - runners_instance_ready_command = var.runner_worker_docker_autoscaler.instance_ready_command - - use_private_key = var.runner_worker.use_private_key && var.runner_worker.type == "docker-autoscaler" - - runners_autoscaling = [for config in var.runner_worker_docker_autoscaler_autoscaling_options : { - for key, value in config : - # Convert key from snake_case to PascalCase which is the casing for this section. - key => jsonencode(value) if value != null - }] - }) - - template_runner_worker_config = templatefile("${path.module}/template/runner-worker-config.tftpl", - { - aws_region = data.aws_region.current.name - gitlab_url = var.runner_gitlab.url - gitlab_clone_url = var.runner_gitlab.url_clone - tls_ca_file = length(var.runner_gitlab.certificate) > 0 ? "tls-ca-file=\"/etc/gitlab-runner/certs/gitlab.crt\"" : "" - runners_machine_autoscaling = [for config in var.runner_worker_docker_machine_autoscaling_options : { - for key, value in config : - # Convert key from snake_case to PascalCase which is the casing for this section. - join("", [for subkey in split("_", key) : title(subkey)]) => jsonencode(value) if value != null - }] - - runners_name = var.runner_instance.name - runners_token = var.runner_gitlab.registration_token - runners_executor = var.runner_worker.type - runners_limit = var.runner_worker.max_jobs - runners_environment_vars = jsonencode(var.runner_worker.environment_variables) - runners_pre_build_script = var.runner_worker_gitlab_pipeline.pre_build_script - runners_post_build_script = var.runner_worker_gitlab_pipeline.post_build_script - runners_pre_clone_script = var.runner_worker_gitlab_pipeline.pre_clone_script - runners_request_concurrency = var.runner_worker.request_concurrency - runners_output_limit = var.runner_worker.output_limit - runners_volumes_tmpfs = join("\n", [for v in var.runner_worker_docker_volumes_tmpfs : format("\"%s\" = \"%s\"", v.volume, v.options)]) - runners_services_volumes_tmpfs = join("\n", [for v in var.runner_worker_docker_services_volumes_tmpfs : format("\"%s\" = \"%s\"", v.volume, v.options)]) - runners_docker_services = local.runners_docker_services - runners_docker_options = local.runners_docker_options_toml - bucket_name = local.bucket_name - shared_cache = var.runner_worker_cache.shared - auth_type = var.runner_worker_cache.authentication_type - runners_docker_autoscaler = var.runner_worker.type == "docker-autoscaler" ? local.template_runner_docker_autoscaler : "" - runners_docker_machine = var.runner_worker.type == "docker+machine" ? local.template_runner_docker_machine : "" - } - ) - template_runner_config = templatefile("runner-agent.tftpl", { prometheus_listen_address = var.runner_manager.prometheus_listen_address @@ -148,11 +92,26 @@ locals { runners_concurrent = var.runner_manager.maximum_concurrent_jobs sentry_dsn = var.runner_manager.sentry_dsn - runners = [local.template_runner_worker_config] + runners = [module.runner.runner_config] } ) } +module "runner" { + source = "./modules/runner-config" + + kms_key_arn = local.kms_key_arn + cache_bucket_name = local.bucket_name + docker_autoscaler_asg_name = var.runner_worker.type == "docker-autoscaler" ? aws_autoscaling_group.autoscaler[0].name : "" + docker_machine_runner_name = local.runner_tags_merged["Name"] + docker_machine_availability_zone_name = data.aws_availability_zone.runners.name_suffix + docker_machine_instance_profile_name = var.runner_worker.type == "docker+machine" ? aws_iam_instance_profile.docker_machine[0].name : "" + docker_machine_security_group_name = var.runner_worker.type == "docker+machine" ? aws_security_group.docker_machine[0].name : "" + docker_machine_ami_id = data.aws_ami.docker_machine_by_filter[0].id + docker_machine_fleet_launch_template_name = var.runner_worker_docker_machine_fleet.enable == true ? aws_launch_template.fleet_gitlab_runner[0].name : "" + docker_machine_tags = local.runner_tags_merged +} + # ignores: Autoscaling Groups Supply Tags --> we use a "dynamic" block to create the tags # ignores: Auto Scaling Group With No Associated ELB --> that's simply not true, as the EC2 instance contacts GitLab. So no ELB needed here. # kics-scan ignore-line diff --git a/modules/runner-config/locals.tf b/modules/runner-config/locals.tf new file mode 100644 index 000000000..20eda66f3 --- /dev/null +++ b/modules/runner-config/locals.tf @@ -0,0 +1,138 @@ +locals { + template_runner_worker_config = templatefile("${path.module}/template/runner-worker-config.tftpl", + { + aws_region = data.aws_region.current.name + gitlab_url = var.runner_gitlab.url + gitlab_clone_url = var.runner_gitlab.url_clone + tls_ca_file = length(var.runner_gitlab.certificate) > 0 ? "tls-ca-file=\"/etc/gitlab-runner/certs/gitlab.crt\"" : "" + runners_machine_autoscaling = [for config in var.runner_worker_docker_machine_autoscaling_options : { + for key, value in config : + # Convert key from snake_case to PascalCase which is the casing for this section. + join("", [for subkey in split("_", key) : title(subkey)]) => jsonencode(value) if value != null + }] + + runners_name = var.runner_instance.name + runners_token = var.runner_gitlab.registration_token + runners_executor = var.runner_worker.type + runners_limit = var.runner_worker.max_jobs + runners_environment_vars = jsonencode(var.runner_worker.environment_variables) + runners_pre_build_script = var.runner_worker_gitlab_pipeline.pre_build_script + runners_post_build_script = var.runner_worker_gitlab_pipeline.post_build_script + runners_pre_clone_script = var.runner_worker_gitlab_pipeline.pre_clone_script + runners_request_concurrency = var.runner_worker.request_concurrency + runners_output_limit = var.runner_worker.output_limit + runners_volumes_tmpfs = join("\n", [for v in var.runner_worker_docker_volumes_tmpfs : format("\"%s\" = \"%s\"", v.volume, v.options)]) + runners_services_volumes_tmpfs = join("\n", [for v in var.runner_worker_docker_services_volumes_tmpfs : format("\"%s\" = \"%s\"", v.volume, v.options)]) + runners_docker_services = local.runners_docker_services + runners_docker_options = local.runners_docker_options_toml + bucket_name = var.cache_bucket_name + shared_cache = var.runner_worker_cache.shared + auth_type = var.runner_worker_cache.authentication_type + runners_docker_autoscaler = var.runner_worker.type == "docker-autoscaler" ? local.template_runner_docker_autoscaler : "" + runners_docker_machine = var.runner_worker.type == "docker+machine" ? local.template_runner_docker_machine : "" + } + ) + + template_runner_docker_autoscaler = templatefile("${path.module}/template/runner-docker-autoscaler-config.tftpl", + { + docker_autoscaling_name = var.docker_autoscaler_asg_name + connector_config_user = var.runner_worker_docker_autoscaler.connector_config_user + runners_capacity_per_instance = var.runner_worker_docker_autoscaler.capacity_per_instance + runners_max_use_count = var.runner_worker_docker_autoscaler.max_use_count + runners_max_instances = var.runner_worker.max_jobs + + runners_update_interval = var.runner_worker_docker_autoscaler.update_interval + runners_update_interval_when_expecting = var.runner_worker_docker_autoscaler.update_interval_when_expecting + + runners_instance_ready_command = var.runner_worker_docker_autoscaler.instance_ready_command + + use_private_key = var.runner_worker.use_private_key && var.runner_worker.type == "docker-autoscaler" + + runners_autoscaling = [for config in var.runner_worker_docker_autoscaler_autoscaling_options : { + for key, value in config : + # Convert key from snake_case to PascalCase which is the casing for this section. + key => jsonencode(value) if value != null + }] + }) + + template_runner_docker_machine = templatefile("${path.module}/template/runner-docker-machine-config.tftpl", + { + runners_idle_count = var.runner_worker_docker_machine_instance.idle_count + runners_idle_time = var.runner_worker_docker_machine_instance.idle_time + runners_max_builds = local.runners_max_builds_string + docker_machine_name = format("%s-%s", var.docker_machine_runner_name, "%s") # the last %s is always needed + runners_instance_types = var.runner_worker_docker_machine_instance.types + aws_region = data.aws_region.current.name + runners_aws_zone = var.docker_machine_availability_zone_name + runners_userdata = var.runner_worker_docker_machine_instance.start_script + + runners_vpc_id = var.vpc_id + runners_subnet_id = var.subnet_id + runners_subnet_ids = length(var.runner_worker_docker_machine_instance.subnet_ids) > 0 ? var.runner_worker_docker_machine_instance.subnet_ids : [var.subnet_id] + runners_instance_profile = var.docker_machine_availability_zone_name + + runners_use_private_address_only = var.runner_worker_docker_machine_instance.private_address_only + runners_use_private_address = !var.runner_worker_docker_machine_instance.private_address_only + runners_request_spot_instance = var.runner_worker_docker_machine_instance_spot.enable + runners_spot_price_bid = var.runner_worker_docker_machine_instance_spot.max_price == "on-demand-price" || var.runner_worker_docker_machine_instance_spot.max_price == null ? "" : var.runner_worker_docker_machine_instance_spot.max_price + runners_security_group_name = var.docker_machine_security_group_name + + runners_tags = replace(replace(local.runner_tags_string, ",,", ","), "/,$/", "") + runners_ebs_optimized = var.runner_worker_docker_machine_instance.ebs_optimized + runners_monitoring = var.runner_worker_docker_machine_instance.monitoring + runners_iam_instance_profile_name = var.runner_worker_docker_machine_role.profile_name + runners_root_size = var.runner_worker_docker_machine_instance.root_size + runners_volume_type = var.runner_worker_docker_machine_instance.volume_type + runners_ami = var.runner_worker.type == "docker+machine" ? (length(var.runner_worker_docker_machine_ami_id) > 0 ? var.runner_worker_docker_machine_ami_id : var.docker_machine_ami_id) : "" + use_fleet = var.runner_worker_docker_machine_fleet.enable + launch_template = var.docker_machine_fleet_launch_template_name + docker_machine_options = length(local.docker_machine_options_string) == 1 ? "" : local.docker_machine_options_string + runners_max_growth_rate = var.runner_worker_docker_machine_instance.max_growth_rate + runners_volume_kms_key = var.kms_key_arn + }) + + runners_docker_services = templatefile("${path.module}/template/runners_docker_services.tftpl", { + runners_docker_services = var.runner_worker_docker_services + } + ) + + runners_docker_options_toml = templatefile("${path.module}/template/runners_docker_options.tftpl", { + options = merge({ + for key, value in var.runner_worker_docker_options : key => value if value != null && key != "volumes" && key != "pull_policies" + }, { + pull_policy = var.runner_worker_docker_options.pull_policies + volumes = local.runners_volumes + }) + } + ) + + # Convert list to a string separated and prepend by a comma + docker_machine_options_string = format( + ",\"amazonec2-metadata-token=${var.runner_worker_docker_machine_ec2_metadata_options.http_tokens}\", \"amazonec2-metadata-token-response-hop-limit=${var.runner_worker_docker_machine_ec2_metadata_options.http_put_response_hop_limit}\",%s", + join(",", formatlist("%q", concat(var.runner_worker_docker_machine_ec2_options, local.runners_docker_registry_mirror_option))), + ) + + runners_volumes = concat(var.runner_worker_docker_options.volumes, var.runner_worker_docker_add_dind_volumes ? ["/certs/client", "/builds", "/var/run/docker.sock:/var/run/docker.sock"] : []) + + runner_tags_string = join(",", flatten([ + for key in keys(local.runner_tags) : [key, local.runner_tags[key]] + ])) + + # remove the `Name` tag in addition if docker+machine adds one to avoid a failure due to a duplicate `Name` tag + runner_tags = local.docker_machine_adds_name_tag ? { for k, v in var.docker_machine_tags : k => v if !contains(concat(var.suppressed_tags, ["Name"]), k) } : var.docker_machine_tags + + # Ensure max builds is optional + runners_max_builds_string = var.runner_worker_docker_machine_instance.destroy_after_max_builds == 0 ? "" : format("MaxBuilds = %d", var.runner_worker_docker_machine_instance.destroy_after_max_builds) + + runners_docker_registry_mirror_option = var.runner_worker_docker_machine_instance.docker_registry_mirror_url == "" ? [] : ["engine-registry-mirror=${var.runner_worker_docker_machine_instance.docker_registry_mirror_url}"] + docker_machine_adds_name_tag = signum(sum(local.docker_machine_version_test)) <= 0 + docker_machine_version_test = [ + for i, j in reverse(range(length(local.docker_machine_version_used))) + : signum(local.docker_machine_version_with_name_tag[i] - local.docker_machine_version_used[i]) * pow(10, j) + ] + + /* determines if the docker machine executable adds the Name tag automatically (versions >= 0.16.2) */ + # make sure to skip pre-release stuff in the semver by ignoring everything after "-" + docker_machine_version_used = split(".", split("-", var.runner_install.docker_machine_version)[0]) + docker_machine_version_with_name_tag = split(".", "0.16.2") +} diff --git a/modules/runner-config/main.tf b/modules/runner-config/main.tf new file mode 100644 index 000000000..2502393bf --- /dev/null +++ b/modules/runner-config/main.tf @@ -0,0 +1 @@ +data "aws_region" "current" {} diff --git a/modules/runner-config/outputs.tf b/modules/runner-config/outputs.tf new file mode 100644 index 000000000..afd60804a --- /dev/null +++ b/modules/runner-config/outputs.tf @@ -0,0 +1,4 @@ +output "runner_config" { + value = "" + description = "Runner configuration in TOML format for the agent's configuration file" +} diff --git a/modules/runner-config/variables.tf b/modules/runner-config/variables.tf new file mode 100644 index 000000000..7c64c834e --- /dev/null +++ b/modules/runner-config/variables.tf @@ -0,0 +1,49 @@ +variable "docker_machine_tags" { + description = "The tags to apply to the docker machine." + type = map(string) +} + +variable "docker_machine_fleet_launch_template_name" { + description = "The name of the launch template for the docker machine fleet." + type = string +} + +variable "docker_machine_ami_id" { + description = "The AMI ID to use for the docker machine workers." + type = string +} + +variable "docker_machine_security_group_name" { + description = "The name of the security group for the docker machine." + type = string +} + +variable "docker_machine_instance_profile_name" { + description = "The name of the instance profile for the docker machine." + type = string +} + +variable "docker_machine_availability_zone_name" { + description = "The name of the availability zone for the docker machine." + type = string +} + +variable "docker_machine_runner_name" { + description = "The name of the instance." + type = string +} + +variable "docker_autoscaler_asg_name" { + description = "The name of the autoscaling group for the docker autoscaler." + type = string +} + +variable "cache_bucket_name" { + description = "The name of the S3 bucket to use for caching." + type = string +} + +variable "kms_key_arn" { + description = "The ARN of the KMS key to use for encrypting everything." + type = string +} diff --git a/tags.tf b/tags.tf index edde6d7c1..bad8bfe50 100644 --- a/tags.tf +++ b/tags.tf @@ -32,11 +32,4 @@ locals { # overwrites the `Name` key from `local.tags` var.runner_worker_docker_machine_instance.name_prefix == "" ? { Name = substr(format("%s", var.environment), 0, 16) } : { Name = var.runner_worker_docker_machine_instance.name_prefix }, ) - - # remove the `Name` tag in addition if docker+machine adds one to avoid a failure due to a duplicate `Name` tag - runner_tags = local.docker_machine_adds_name_tag ? { for k, v in local.runner_tags_merged : k => v if !contains(concat(var.suppressed_tags, ["Name"]), k) } : local.runner_tags_merged - - runner_tags_string = join(",", flatten([ - for key in keys(local.runner_tags) : [key, local.runner_tags[key]] - ])) } From 1a2633ebdd1aaa677245e7f5a16a70f296a22847 Mon Sep 17 00:00:00 2001 From: Matthias Kay Date: Sun, 9 Feb 2025 13:06:17 +0100 Subject: [PATCH 03/13] fix variables --- main.tf | 1 + modules/runner-config/locals.tf | 34 ++++++++--------- modules/runner-config/variables.tf | 60 ++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 17 deletions(-) diff --git a/main.tf b/main.tf index 151a0f12b..026315092 100644 --- a/main.tf +++ b/main.tf @@ -110,6 +110,7 @@ module "runner" { docker_machine_ami_id = data.aws_ami.docker_machine_by_filter[0].id docker_machine_fleet_launch_template_name = var.runner_worker_docker_machine_fleet.enable == true ? aws_launch_template.fleet_gitlab_runner[0].name : "" docker_machine_tags = local.runner_tags_merged + docker_machine_instance = var.runner_worker_docker_machine_instance } # ignores: Autoscaling Groups Supply Tags --> we use a "dynamic" block to create the tags diff --git a/modules/runner-config/locals.tf b/modules/runner-config/locals.tf index 20eda66f3..a7628ef08 100644 --- a/modules/runner-config/locals.tf +++ b/modules/runner-config/locals.tf @@ -1,4 +1,4 @@ -locals { + locals { template_runner_worker_config = templatefile("${path.module}/template/runner-worker-config.tftpl", { aws_region = data.aws_region.current.name @@ -57,37 +57,37 @@ locals { template_runner_docker_machine = templatefile("${path.module}/template/runner-docker-machine-config.tftpl", { - runners_idle_count = var.runner_worker_docker_machine_instance.idle_count - runners_idle_time = var.runner_worker_docker_machine_instance.idle_time + runners_idle_count = var.docker_machine_instance.idle_count + runners_idle_time = var.docker_machine_instance.idle_time runners_max_builds = local.runners_max_builds_string docker_machine_name = format("%s-%s", var.docker_machine_runner_name, "%s") # the last %s is always needed - runners_instance_types = var.runner_worker_docker_machine_instance.types + runners_instance_types = var.docker_machine_instance.types aws_region = data.aws_region.current.name runners_aws_zone = var.docker_machine_availability_zone_name - runners_userdata = var.runner_worker_docker_machine_instance.start_script + runners_userdata = var.docker_machine_instance.start_script runners_vpc_id = var.vpc_id runners_subnet_id = var.subnet_id - runners_subnet_ids = length(var.runner_worker_docker_machine_instance.subnet_ids) > 0 ? var.runner_worker_docker_machine_instance.subnet_ids : [var.subnet_id] + runners_subnet_ids = length(var.docker_machine_instance.subnet_ids) > 0 ? var.runner_worker_docker_machine_instance.subnet_ids : [var.subnet_id] runners_instance_profile = var.docker_machine_availability_zone_name - runners_use_private_address_only = var.runner_worker_docker_machine_instance.private_address_only - runners_use_private_address = !var.runner_worker_docker_machine_instance.private_address_only - runners_request_spot_instance = var.runner_worker_docker_machine_instance_spot.enable - runners_spot_price_bid = var.runner_worker_docker_machine_instance_spot.max_price == "on-demand-price" || var.runner_worker_docker_machine_instance_spot.max_price == null ? "" : var.runner_worker_docker_machine_instance_spot.max_price + runners_use_private_address_only = var.docker_machine_instance.private_address_only + runners_use_private_address = !var.docker_machine_instance.private_address_only + runners_request_spot_instance = var.docker_machine_instance_spot.enable + runners_spot_price_bid = var.docker_machine_instance_spot.max_price == "on-demand-price" || var.runner_worker_docker_machine_instance_spot.max_price == null ? "" : var.runner_worker_docker_machine_instance_spot.max_price runners_security_group_name = var.docker_machine_security_group_name runners_tags = replace(replace(local.runner_tags_string, ",,", ","), "/,$/", "") - runners_ebs_optimized = var.runner_worker_docker_machine_instance.ebs_optimized - runners_monitoring = var.runner_worker_docker_machine_instance.monitoring - runners_iam_instance_profile_name = var.runner_worker_docker_machine_role.profile_name - runners_root_size = var.runner_worker_docker_machine_instance.root_size - runners_volume_type = var.runner_worker_docker_machine_instance.volume_type + runners_ebs_optimized = var.docker_machine_instance.ebs_optimized + runners_monitoring = var.docker_machine_instance.monitoring + runners_iam_instance_profile_name = var.docker_machine_role.profile_name + runners_root_size = var.docker_machine_instance.root_size + runners_volume_type = var.docker_machine_instance.volume_type runners_ami = var.runner_worker.type == "docker+machine" ? (length(var.runner_worker_docker_machine_ami_id) > 0 ? var.runner_worker_docker_machine_ami_id : var.docker_machine_ami_id) : "" - use_fleet = var.runner_worker_docker_machine_fleet.enable + use_fleet = var.docker_machine_fleet.enable launch_template = var.docker_machine_fleet_launch_template_name docker_machine_options = length(local.docker_machine_options_string) == 1 ? "" : local.docker_machine_options_string - runners_max_growth_rate = var.runner_worker_docker_machine_instance.max_growth_rate + runners_max_growth_rate = var.docker_machine_instance.max_growth_rate runners_volume_kms_key = var.kms_key_arn }) diff --git a/modules/runner-config/variables.tf b/modules/runner-config/variables.tf index 7c64c834e..4a462122a 100644 --- a/modules/runner-config/variables.tf +++ b/modules/runner-config/variables.tf @@ -47,3 +47,63 @@ variable "kms_key_arn" { description = "The ARN of the KMS key to use for encrypting everything." type = string } + +variable "docker_machine_instance" { + description = <<-EOT + For detailed documentation check https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersmachine-section + + docker_registry_mirror_url = The URL of the Docker registry mirror to use for the Runner Worker. + destroy_after_max_builds = Destroy the instance after the maximum number of builds has been reached. + ebs_optimized = Enable EBS optimization for the Runner Worker. + idle_count = Number of idle Runner Worker instances (not working for the Docker Runner Worker) (IdleCount). + idle_time = Idle time of the Runner Worker before they are destroyed (not working for the Docker Runner Worker) (IdleTime). + max_growth_rate = The maximum number of machines that can be added to the runner in parallel. + monitoring = Enable detailed monitoring for the Runner Worker. + name_prefix = Set the name prefix and override the `Name` tag for the Runner Worker. + private_address_only = Restrict Runner Worker to the use of a private IP address. If `runner_instance.use_private_address_only` is set to `true` (default), `runner_worker_docker_machine_instance.private_address_only` will also apply for the Runner. + root_device_name = The name of the root volume for the Runner Worker. + root_size = The size of the root volume for the Runner Worker. + start_script = Cloud-init user data that will be passed to the Runner Worker. Should not be base64 encrypted. + subnet_ids = The list of subnet IDs to use for the Runner Worker when the fleet mode is enabled. + types = The type of instance to use for the Runner Worker. In case of fleet mode, multiple instance types are supported. + volume_type = The type of volume to use for the Runner Worker. `gp2`, `gp3`, `io1` or `io2` are supported. + volume_throughput = Throughput in MB/s for the volume. Only supported when using `gp3` as `volume_type`. + volume_iops = Guaranteed IOPS for the volume. Only supported when using `gp3`, `io1` or `io2` as `volume_type`. Works for fleeting only. See `runner_worker_docker_machine_fleet`. + EOT + type = object({ + destroy_after_max_builds = optional(number, 0) + docker_registry_mirror_url = optional(string, "") + ebs_optimized = optional(bool, true) + idle_count = optional(number, 0) + idle_time = optional(number, 600) + max_growth_rate = optional(number, 0) + monitoring = optional(bool, false) + name_prefix = optional(string, "") + private_address_only = optional(bool, true) + root_device_name = optional(string, "/dev/sda1") + root_size = optional(number, 8) + start_script = optional(string, "") + subnet_ids = optional(list(string), []) + types = optional(list(string), ["m5.large"]) + volume_type = optional(string, "gp2") + volume_throughput = optional(number, 125) + volume_iops = optional(number, 3000) + }) + default = { + } + + validation { + condition = length(var.docker_machine_instance.name_prefix) <= 28 + error_message = "Maximum length for docker+machine executor name is 28 characters!" + } + + validation { + condition = var.docker_machine_instance.name_prefix == "" || can(regex("^[a-zA-Z0-9\\.-]+$", var.docker_machine_instance.name_prefix)) + error_message = "Valid characters for the docker+machine executor name are: [a-zA-Z0-9\\.-]." + } + + validation { + condition = contains(["gp2", "gp3", "io1", "io2"], var.docker_machine_instance.volume_type) + error_message = "Supported volume types: gp2, gp3, io1 and io2" + } +} From d4e5cd5df1452269697d8927ec33ce586db2b760 Mon Sep 17 00:00:00 2001 From: Matthias Kay Date: Sun, 9 Feb 2025 13:15:29 +0100 Subject: [PATCH 04/13] fix variables --- main.tf | 5 ++ modules/runner-config/variables.tf | 92 ++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/main.tf b/main.tf index 026315092..731fdcca7 100644 --- a/main.tf +++ b/main.tf @@ -111,6 +111,11 @@ module "runner" { docker_machine_fleet_launch_template_name = var.runner_worker_docker_machine_fleet.enable == true ? aws_launch_template.fleet_gitlab_runner[0].name : "" docker_machine_tags = local.runner_tags_merged docker_machine_instance = var.runner_worker_docker_machine_instance + + runner_worker = var.runner_worker + runner_worker_docker_autoscaler = var.runner_worker_docker_autoscaler + runner_worker_gitlab_pipeline = var.runner_worker_gitlab_pipeline + runner_gitlab = var.runner_gitlab } # ignores: Autoscaling Groups Supply Tags --> we use a "dynamic" block to create the tags diff --git a/modules/runner-config/variables.tf b/modules/runner-config/variables.tf index 4a462122a..0277b0c0d 100644 --- a/modules/runner-config/variables.tf +++ b/modules/runner-config/variables.tf @@ -107,3 +107,95 @@ variable "docker_machine_instance" { error_message = "Supported volume types: gp2, gp3, io1 and io2" } } + +variable "runner_worker" { + description = <<-EOT + For detailed information, check https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section. + + environment_variables = List of environment variables to add to the Runner Worker (environment). + max_jobs = Number of jobs which can be processed in parallel by the Runner Worker. + output_limit = Sets the maximum build log size in kilobytes. Default is 4MB (output_limit). + request_concurrency = Limit number of concurrent requests for new jobs from GitLab (default 1) (request_concurrency). + ssm_access = Allows to connect to the Runner Worker via SSM. + type = The Runner Worker type to use. Currently supports `docker+machine` or `docker` or `docker-autoscaler`. + use_private_key = Use a private key to connect the Runner Manager to the Runner Workers. Ignored when fleeting is enabled (defaults to `true`). + EOT + type = object({ + environment_variables = optional(list(string), []) + max_jobs = optional(number, 0) + output_limit = optional(number, 4096) + request_concurrency = optional(number, 1) + ssm_access = optional(bool, false) + type = optional(string, "docker+machine") + # false positive, use_private_key is not a secret + # kics-scan ignore-line + use_private_key = optional(bool, false) + }) + default = {} + + validation { + condition = contains(["docker+machine", "docker", "docker-autoscaler"], var.runner_worker.type) + error_message = "The executor currently supports `docker+machine` and `docker`." + } +} + +variable "runner_worker_docker_autoscaler" { + description = <<-EOT + fleeting_plugin_version = The version of aws fleeting plugin. + connector_config_user = User to connect to worker machine. + key_pair_name = The name of the key pair used by the Runner to connect to the docker-machine Runner Workers. This variable is only supported when `enables` is set to `true`. + capacity_per_instance = The number of jobs that can be executed concurrently by a single instance. + max_use_count = Max job number that can run on a worker. + update_interval = The interval to check with the fleeting plugin for instance updates. + update_interval_when_expecting = The interval to check with the fleeting plugin for instance updates when expecting a state change. + instance_ready_command = Executes this command on each instance provisioned by the autoscaler to ensure that it is ready for use. A failure results in the instance being removed. + EOT + type = object({ + fleeting_plugin_version = optional(string, "1.0.0") + connector_config_user = optional(string, "ec2-user") + key_pair_name = optional(string, "runner-worker-key") + capacity_per_instance = optional(number, 1) + max_use_count = optional(number, 100) + update_interval = optional(string, "1m") + update_interval_when_expecting = optional(string, "2s") + instance_ready_command = optional(string, "") + }) + default = {} +} + +variable "runner_worker_gitlab_pipeline" { + description = <<-EOT + post_build_script = Script to execute in the pipeline just after the build, but before executing after_script. + pre_build_script = Script to execute in the pipeline just before the build. + pre_clone_script = Script to execute in the pipeline before cloning the Git repository. this can be used to adjust the Git client configuration first, for example. + EOT + type = object({ + post_build_script = optional(string, "\"\"") + pre_build_script = optional(string, "\"\"") + pre_clone_script = optional(string, "\"\"") + }) + default = {} +} + +variable "runner_gitlab" { + description = <<-EOT + ca_certificate = Trusted CA certificate bundle (PEM format). + certificate = Certificate of the GitLab instance to connect to (PEM format). + registration_token = (deprecated, This is replaced by the `registration_token` in `runner_gitlab_registration_config`.) Registration token to use to register the Runner. + runner_version = Version of the [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner/-/releases). Make sure that it is available for your AMI. See https://packages.gitlab.com/app/runner/gitlab-runner/search?dist=amazon%2F2023&filter=rpms&page=1&q= + url = URL of the GitLab instance to connect to. + url_clone = URL of the GitLab instance to clone from. Use only if the agent can’t connect to the GitLab URL. + access_token_secure_parameter_store_name = (deprecated) The name of the SSM parameter to read the GitLab access token from. It must have the `api` scope and be pre created. + preregistered_runner_token_ssm_parameter_name = The name of the SSM parameter to read the preregistered GitLab Runner token from. + EOT + type = object({ + ca_certificate = optional(string, "") + certificate = optional(string, "") + registration_token = optional(string, "__REPLACED_BY_USER_DATA__") # deprecated, removed in 8.0.0 + runner_version = optional(string, "16.0.3") + url = optional(string, "") + url_clone = optional(string, "") + access_token_secure_parameter_store_name = optional(string, "gitlab-runner-access-token") # deprecated, removed in 8.0.0 + preregistered_runner_token_ssm_parameter_name = optional(string, "") + }) +} From 529c3638459feaaec8335d150da29b193ce96abc Mon Sep 17 00:00:00 2001 From: Matthias Kay Date: Thu, 20 Feb 2025 21:43:44 +0100 Subject: [PATCH 05/13] add more variables --- modules/runner-config/locals.tf | 2 +- modules/runner-config/variables.tf | 292 ++++++++++++++++++++++++++++- 2 files changed, 285 insertions(+), 9 deletions(-) diff --git a/modules/runner-config/locals.tf b/modules/runner-config/locals.tf index a7628ef08..782225dc0 100644 --- a/modules/runner-config/locals.tf +++ b/modules/runner-config/locals.tf @@ -74,7 +74,7 @@ runners_use_private_address_only = var.docker_machine_instance.private_address_only runners_use_private_address = !var.docker_machine_instance.private_address_only runners_request_spot_instance = var.docker_machine_instance_spot.enable - runners_spot_price_bid = var.docker_machine_instance_spot.max_price == "on-demand-price" || var.runner_worker_docker_machine_instance_spot.max_price == null ? "" : var.runner_worker_docker_machine_instance_spot.max_price + runners_spot_price_bid = var.docker_machine_instance_spot.max_price == "on-demand-price" || var.docker_machine_instance_spot.max_price == null ? "" : var.docker_machine_instance_spot.max_price runners_security_group_name = var.docker_machine_security_group_name runners_tags = replace(replace(local.runner_tags_string, ",,", ","), "/,$/", "") diff --git a/modules/runner-config/variables.tf b/modules/runner-config/variables.tf index 0277b0c0d..3e9d7da32 100644 --- a/modules/runner-config/variables.tf +++ b/modules/runner-config/variables.tf @@ -179,23 +179,299 @@ variable "runner_worker_gitlab_pipeline" { variable "runner_gitlab" { description = <<-EOT - ca_certificate = Trusted CA certificate bundle (PEM format). certificate = Certificate of the GitLab instance to connect to (PEM format). registration_token = (deprecated, This is replaced by the `registration_token` in `runner_gitlab_registration_config`.) Registration token to use to register the Runner. - runner_version = Version of the [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner/-/releases). Make sure that it is available for your AMI. See https://packages.gitlab.com/app/runner/gitlab-runner/search?dist=amazon%2F2023&filter=rpms&page=1&q= url = URL of the GitLab instance to connect to. url_clone = URL of the GitLab instance to clone from. Use only if the agent can’t connect to the GitLab URL. - access_token_secure_parameter_store_name = (deprecated) The name of the SSM parameter to read the GitLab access token from. It must have the `api` scope and be pre created. - preregistered_runner_token_ssm_parameter_name = The name of the SSM parameter to read the preregistered GitLab Runner token from. EOT type = object({ - ca_certificate = optional(string, "") certificate = optional(string, "") registration_token = optional(string, "__REPLACED_BY_USER_DATA__") # deprecated, removed in 8.0.0 - runner_version = optional(string, "16.0.3") url = optional(string, "") url_clone = optional(string, "") - access_token_secure_parameter_store_name = optional(string, "gitlab-runner-access-token") # deprecated, removed in 8.0.0 - preregistered_runner_token_ssm_parameter_name = optional(string, "") }) } + +variable "runner_worker_docker_machine_autoscaling_options" { + description = "Set autoscaling parameters based on periods, see https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersmachine-section" + type = list(object({ + periods = list(string) + idle_count = optional(number) + idle_scale_factor = optional(number) + idle_count_min = optional(number) + idle_time = optional(number) + timezone = optional(string, "UTC") + })) + default = [] +} + +variable "runner_instance" { + description = <<-EOT + name = Name of the Runner instance. + EOT + type = object({ + name = string + }) + default = { + name = "gitlab-runner" + } +} + +variable "runner_worker_docker_volumes_tmpfs" { + description = "Mount a tmpfs in Executor container. https://docs.gitlab.com/runner/executors/docker.html#mounting-a-directory-in-ram" + type = list(object({ + volume = string + options = string + })) + default = [] +} + +variable "runner_worker_docker_services_volumes_tmpfs" { + description = "Mount a tmpfs in gitlab service container. https://docs.gitlab.com/runner/executors/docker.html#mounting-a-directory-in-ram" + type = list(object({ + volume = string + options = string + })) + default = [] +} + +variable "runner_worker_cache" { + description = <<-EOT + Configuration to control the creation of the cache bucket. By default the bucket will be created and used as shared + cache. To use the same cache across multiple Runner Worker disable the creation of the cache and provide a policy and + bucket name. See the public runner example for more details." + + For detailed documentation check https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnerscaches3-section. + + authentication_type = A string that declares the AuthenticationType for [runners.cache.s3]. Can either be 'iam' or 'credentials'. + shared = Boolean used to enable or disable the use of the cache bucket as shared cache. + EOT + type = object({ + authentication_type = optional(string, "iam") + shared = optional(bool, false) + }) + default = {} +} + +variable "runner_worker_docker_autoscaler_autoscaling_options" { + description = "Set autoscaling parameters based on periods, see https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersautoscalerpolicy-sections" + type = list(object({ + periods = list(string) + timezone = optional(string, "UTC") + idle_count = optional(number) + idle_time = optional(string) + scale_factor = optional(number) + scale_factor_limit = optional(number, 0) + })) + default = [] +} + +variable "docker_machine_instance_spot" { + description = <<-EOT + enable = Enable spot instances for the Runner Worker. + max_price = The maximum price willing to pay. By default the price is limited by the current on demand price for the instance type chosen. + EOT + type = object({ + enable = optional(bool, true) + max_price = optional(string, "on-demand-price") + }) + default = {} +} + +variable "docker_machine_role" { + description = <<-EOT + profile_name = Name of the IAM profile to attach to the Runner Workers. + EOT + type = object({ + profile_name = optional(string, "") + }) + default = {} +} + +variable "docker_machine_fleet" { + description = <<-EOT + enable = Activates the fleet mode on the Runner. https://gitlab.com/cki-project/docker-machine/-/blob/v0.16.2-gitlab.19-cki.2/docs/drivers/aws.md#fleet-mode + key_pair_name = The name of the key pair used by the Runner to connect to the docker-machine Runner Workers. This variable is only supported when `enables` is set to `true`. + EOT + type = object({ + enable = bool + }) + default = { + enable = false + } +} + +variable "runner_worker_docker_services" { + description = "Starts additional services with the Docker container. All fields must be set (examine the Dockerfile of the service image for the entrypoint - see ./examples/runner-default/main.tf)" + type = list(object({ + name = string + alias = string + entrypoint = list(string) + command = list(string) + })) + default = [] +} + +variable "runner_worker_docker_options" { + description = < Date: Thu, 20 Feb 2025 21:47:59 +0100 Subject: [PATCH 06/13] remove runner_worker prefix --- main.tf | 4 +- modules/runner-config/locals.tf | 50 +++++++-------- modules/runner-config/variables.tf | 99 +++++------------------------- 3 files changed, 44 insertions(+), 109 deletions(-) diff --git a/main.tf b/main.tf index 731fdcca7..72f25eee7 100644 --- a/main.tf +++ b/main.tf @@ -113,8 +113,8 @@ module "runner" { docker_machine_instance = var.runner_worker_docker_machine_instance runner_worker = var.runner_worker - runner_worker_docker_autoscaler = var.runner_worker_docker_autoscaler - runner_worker_gitlab_pipeline = var.runner_worker_gitlab_pipeline + docker_autoscaler = var.runner_worker_docker_autoscaler + gitlab_pipeline = var.runner_worker_gitlab_pipeline runner_gitlab = var.runner_gitlab } diff --git a/modules/runner-config/locals.tf b/modules/runner-config/locals.tf index 782225dc0..a24b87538 100644 --- a/modules/runner-config/locals.tf +++ b/modules/runner-config/locals.tf @@ -5,7 +5,7 @@ gitlab_url = var.runner_gitlab.url gitlab_clone_url = var.runner_gitlab.url_clone tls_ca_file = length(var.runner_gitlab.certificate) > 0 ? "tls-ca-file=\"/etc/gitlab-runner/certs/gitlab.crt\"" : "" - runners_machine_autoscaling = [for config in var.runner_worker_docker_machine_autoscaling_options : { + runners_machine_autoscaling = [for config in var.docker_machine_autoscaling_options : { for key, value in config : # Convert key from snake_case to PascalCase which is the casing for this section. join("", [for subkey in split("_", key) : title(subkey)]) => jsonencode(value) if value != null @@ -16,18 +16,18 @@ runners_executor = var.runner_worker.type runners_limit = var.runner_worker.max_jobs runners_environment_vars = jsonencode(var.runner_worker.environment_variables) - runners_pre_build_script = var.runner_worker_gitlab_pipeline.pre_build_script - runners_post_build_script = var.runner_worker_gitlab_pipeline.post_build_script - runners_pre_clone_script = var.runner_worker_gitlab_pipeline.pre_clone_script + runners_pre_build_script = var.gitlab_pipeline.pre_build_script + runners_post_build_script = var.gitlab_pipeline.post_build_script + runners_pre_clone_script = var.gitlab_pipeline.pre_clone_script runners_request_concurrency = var.runner_worker.request_concurrency runners_output_limit = var.runner_worker.output_limit - runners_volumes_tmpfs = join("\n", [for v in var.runner_worker_docker_volumes_tmpfs : format("\"%s\" = \"%s\"", v.volume, v.options)]) - runners_services_volumes_tmpfs = join("\n", [for v in var.runner_worker_docker_services_volumes_tmpfs : format("\"%s\" = \"%s\"", v.volume, v.options)]) + runners_volumes_tmpfs = join("\n", [for v in var.docker_volumes_tmpfs : format("\"%s\" = \"%s\"", v.volume, v.options)]) + runners_services_volumes_tmpfs = join("\n", [for v in var.docker_services_volumes_tmpfs : format("\"%s\" = \"%s\"", v.volume, v.options)]) runners_docker_services = local.runners_docker_services runners_docker_options = local.runners_docker_options_toml bucket_name = var.cache_bucket_name - shared_cache = var.runner_worker_cache.shared - auth_type = var.runner_worker_cache.authentication_type + shared_cache = var.cache.shared + auth_type = var.cache.authentication_type runners_docker_autoscaler = var.runner_worker.type == "docker-autoscaler" ? local.template_runner_docker_autoscaler : "" runners_docker_machine = var.runner_worker.type == "docker+machine" ? local.template_runner_docker_machine : "" } @@ -36,19 +36,19 @@ template_runner_docker_autoscaler = templatefile("${path.module}/template/runner-docker-autoscaler-config.tftpl", { docker_autoscaling_name = var.docker_autoscaler_asg_name - connector_config_user = var.runner_worker_docker_autoscaler.connector_config_user - runners_capacity_per_instance = var.runner_worker_docker_autoscaler.capacity_per_instance - runners_max_use_count = var.runner_worker_docker_autoscaler.max_use_count + connector_config_user = var.docker_autoscaler.connector_config_user + runners_capacity_per_instance = var.docker_autoscaler.capacity_per_instance + runners_max_use_count = var.docker_autoscaler.max_use_count runners_max_instances = var.runner_worker.max_jobs - runners_update_interval = var.runner_worker_docker_autoscaler.update_interval - runners_update_interval_when_expecting = var.runner_worker_docker_autoscaler.update_interval_when_expecting + runners_update_interval = var.docker_autoscaler.update_interval + runners_update_interval_when_expecting = var.docker_autoscaler.update_interval_when_expecting - runners_instance_ready_command = var.runner_worker_docker_autoscaler.instance_ready_command + runners_instance_ready_command = var.docker_autoscaler.instance_ready_command use_private_key = var.runner_worker.use_private_key && var.runner_worker.type == "docker-autoscaler" - runners_autoscaling = [for config in var.runner_worker_docker_autoscaler_autoscaling_options : { + runners_autoscaling = [for config in var.docker_autoscaler_autoscaling_options : { for key, value in config : # Convert key from snake_case to PascalCase which is the casing for this section. key => jsonencode(value) if value != null @@ -68,7 +68,7 @@ runners_vpc_id = var.vpc_id runners_subnet_id = var.subnet_id - runners_subnet_ids = length(var.docker_machine_instance.subnet_ids) > 0 ? var.runner_worker_docker_machine_instance.subnet_ids : [var.subnet_id] + runners_subnet_ids = length(var.docker_machine_instance.subnet_ids) > 0 ? var.docker_machine_instance.subnet_ids : [var.subnet_id] runners_instance_profile = var.docker_machine_availability_zone_name runners_use_private_address_only = var.docker_machine_instance.private_address_only @@ -83,7 +83,7 @@ runners_iam_instance_profile_name = var.docker_machine_role.profile_name runners_root_size = var.docker_machine_instance.root_size runners_volume_type = var.docker_machine_instance.volume_type - runners_ami = var.runner_worker.type == "docker+machine" ? (length(var.runner_worker_docker_machine_ami_id) > 0 ? var.runner_worker_docker_machine_ami_id : var.docker_machine_ami_id) : "" + runners_ami = var.runner_worker.type == "docker+machine" ? (length(var.docker_machine_ami_id) > 0 ? var.docker_machine_ami_id : var.docker_machine_ami_id) : "" use_fleet = var.docker_machine_fleet.enable launch_template = var.docker_machine_fleet_launch_template_name docker_machine_options = length(local.docker_machine_options_string) == 1 ? "" : local.docker_machine_options_string @@ -92,15 +92,15 @@ }) runners_docker_services = templatefile("${path.module}/template/runners_docker_services.tftpl", { - runners_docker_services = var.runner_worker_docker_services + runners_docker_services = var.docker_services } ) runners_docker_options_toml = templatefile("${path.module}/template/runners_docker_options.tftpl", { options = merge({ - for key, value in var.runner_worker_docker_options : key => value if value != null && key != "volumes" && key != "pull_policies" + for key, value in var.docker_options : key => value if value != null && key != "volumes" && key != "pull_policies" }, { - pull_policy = var.runner_worker_docker_options.pull_policies + pull_policy = var.docker_options.pull_policies volumes = local.runners_volumes }) } @@ -108,11 +108,11 @@ # Convert list to a string separated and prepend by a comma docker_machine_options_string = format( - ",\"amazonec2-metadata-token=${var.runner_worker_docker_machine_ec2_metadata_options.http_tokens}\", \"amazonec2-metadata-token-response-hop-limit=${var.runner_worker_docker_machine_ec2_metadata_options.http_put_response_hop_limit}\",%s", - join(",", formatlist("%q", concat(var.runner_worker_docker_machine_ec2_options, local.runners_docker_registry_mirror_option))), + ",\"amazonec2-metadata-token=${var.docker_machine_ec2_metadata_options.http_tokens}\", \"amazonec2-metadata-token-response-hop-limit=${var.docker_machine_ec2_metadata_options.http_put_response_hop_limit}\",%s", + join(",", formatlist("%q", concat(var.docker_machine_ec2_options, local.runners_docker_registry_mirror_option))), ) - runners_volumes = concat(var.runner_worker_docker_options.volumes, var.runner_worker_docker_add_dind_volumes ? ["/certs/client", "/builds", "/var/run/docker.sock:/var/run/docker.sock"] : []) + runners_volumes = concat(var.docker_options.volumes, var.docker_add_dind_volumes ? ["/certs/client", "/builds", "/var/run/docker.sock:/var/run/docker.sock"] : []) runner_tags_string = join(",", flatten([ for key in keys(local.runner_tags) : [key, local.runner_tags[key]] @@ -122,9 +122,9 @@ runner_tags = local.docker_machine_adds_name_tag ? { for k, v in var.docker_machine_tags : k => v if !contains(concat(var.suppressed_tags, ["Name"]), k) } : var.docker_machine_tags # Ensure max builds is optional - runners_max_builds_string = var.runner_worker_docker_machine_instance.destroy_after_max_builds == 0 ? "" : format("MaxBuilds = %d", var.runner_worker_docker_machine_instance.destroy_after_max_builds) + runners_max_builds_string = var.docker_machine_instance.destroy_after_max_builds == 0 ? "" : format("MaxBuilds = %d", var.docker_machine_instance.destroy_after_max_builds) - runners_docker_registry_mirror_option = var.runner_worker_docker_machine_instance.docker_registry_mirror_url == "" ? [] : ["engine-registry-mirror=${var.runner_worker_docker_machine_instance.docker_registry_mirror_url}"] + runners_docker_registry_mirror_option = var.docker_machine_instance.docker_registry_mirror_url == "" ? [] : ["engine-registry-mirror=${var.docker_machine_instance.docker_registry_mirror_url}"] docker_machine_adds_name_tag = signum(sum(local.docker_machine_version_test)) <= 0 docker_machine_version_test = [ for i, j in reverse(range(length(local.docker_machine_version_used))) diff --git a/modules/runner-config/variables.tf b/modules/runner-config/variables.tf index 3e9d7da32..253f27997 100644 --- a/modules/runner-config/variables.tf +++ b/modules/runner-config/variables.tf @@ -8,11 +8,6 @@ variable "docker_machine_fleet_launch_template_name" { type = string } -variable "docker_machine_ami_id" { - description = "The AMI ID to use for the docker machine workers." - type = string -} - variable "docker_machine_security_group_name" { description = "The name of the security group for the docker machine." type = string @@ -48,66 +43,6 @@ variable "kms_key_arn" { type = string } -variable "docker_machine_instance" { - description = <<-EOT - For detailed documentation check https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersmachine-section - - docker_registry_mirror_url = The URL of the Docker registry mirror to use for the Runner Worker. - destroy_after_max_builds = Destroy the instance after the maximum number of builds has been reached. - ebs_optimized = Enable EBS optimization for the Runner Worker. - idle_count = Number of idle Runner Worker instances (not working for the Docker Runner Worker) (IdleCount). - idle_time = Idle time of the Runner Worker before they are destroyed (not working for the Docker Runner Worker) (IdleTime). - max_growth_rate = The maximum number of machines that can be added to the runner in parallel. - monitoring = Enable detailed monitoring for the Runner Worker. - name_prefix = Set the name prefix and override the `Name` tag for the Runner Worker. - private_address_only = Restrict Runner Worker to the use of a private IP address. If `runner_instance.use_private_address_only` is set to `true` (default), `runner_worker_docker_machine_instance.private_address_only` will also apply for the Runner. - root_device_name = The name of the root volume for the Runner Worker. - root_size = The size of the root volume for the Runner Worker. - start_script = Cloud-init user data that will be passed to the Runner Worker. Should not be base64 encrypted. - subnet_ids = The list of subnet IDs to use for the Runner Worker when the fleet mode is enabled. - types = The type of instance to use for the Runner Worker. In case of fleet mode, multiple instance types are supported. - volume_type = The type of volume to use for the Runner Worker. `gp2`, `gp3`, `io1` or `io2` are supported. - volume_throughput = Throughput in MB/s for the volume. Only supported when using `gp3` as `volume_type`. - volume_iops = Guaranteed IOPS for the volume. Only supported when using `gp3`, `io1` or `io2` as `volume_type`. Works for fleeting only. See `runner_worker_docker_machine_fleet`. - EOT - type = object({ - destroy_after_max_builds = optional(number, 0) - docker_registry_mirror_url = optional(string, "") - ebs_optimized = optional(bool, true) - idle_count = optional(number, 0) - idle_time = optional(number, 600) - max_growth_rate = optional(number, 0) - monitoring = optional(bool, false) - name_prefix = optional(string, "") - private_address_only = optional(bool, true) - root_device_name = optional(string, "/dev/sda1") - root_size = optional(number, 8) - start_script = optional(string, "") - subnet_ids = optional(list(string), []) - types = optional(list(string), ["m5.large"]) - volume_type = optional(string, "gp2") - volume_throughput = optional(number, 125) - volume_iops = optional(number, 3000) - }) - default = { - } - - validation { - condition = length(var.docker_machine_instance.name_prefix) <= 28 - error_message = "Maximum length for docker+machine executor name is 28 characters!" - } - - validation { - condition = var.docker_machine_instance.name_prefix == "" || can(regex("^[a-zA-Z0-9\\.-]+$", var.docker_machine_instance.name_prefix)) - error_message = "Valid characters for the docker+machine executor name are: [a-zA-Z0-9\\.-]." - } - - validation { - condition = contains(["gp2", "gp3", "io1", "io2"], var.docker_machine_instance.volume_type) - error_message = "Supported volume types: gp2, gp3, io1 and io2" - } -} - variable "runner_worker" { description = <<-EOT For detailed information, check https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section. @@ -139,7 +74,7 @@ variable "runner_worker" { } } -variable "runner_worker_docker_autoscaler" { +variable "docker_autoscaler" { description = <<-EOT fleeting_plugin_version = The version of aws fleeting plugin. connector_config_user = User to connect to worker machine. @@ -163,7 +98,7 @@ variable "runner_worker_docker_autoscaler" { default = {} } -variable "runner_worker_gitlab_pipeline" { +variable "gitlab_pipeline" { description = <<-EOT post_build_script = Script to execute in the pipeline just after the build, but before executing after_script. pre_build_script = Script to execute in the pipeline just before the build. @@ -192,7 +127,7 @@ variable "runner_gitlab" { }) } -variable "runner_worker_docker_machine_autoscaling_options" { +variable "docker_machine_autoscaling_options" { description = "Set autoscaling parameters based on periods, see https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersmachine-section" type = list(object({ periods = list(string) @@ -217,7 +152,7 @@ variable "runner_instance" { } } -variable "runner_worker_docker_volumes_tmpfs" { +variable "docker_volumes_tmpfs" { description = "Mount a tmpfs in Executor container. https://docs.gitlab.com/runner/executors/docker.html#mounting-a-directory-in-ram" type = list(object({ volume = string @@ -226,7 +161,7 @@ variable "runner_worker_docker_volumes_tmpfs" { default = [] } -variable "runner_worker_docker_services_volumes_tmpfs" { +variable "docker_services_volumes_tmpfs" { description = "Mount a tmpfs in gitlab service container. https://docs.gitlab.com/runner/executors/docker.html#mounting-a-directory-in-ram" type = list(object({ volume = string @@ -235,7 +170,7 @@ variable "runner_worker_docker_services_volumes_tmpfs" { default = [] } -variable "runner_worker_cache" { +variable "cache" { description = <<-EOT Configuration to control the creation of the cache bucket. By default the bucket will be created and used as shared cache. To use the same cache across multiple Runner Worker disable the creation of the cache and provide a policy and @@ -253,7 +188,7 @@ variable "runner_worker_cache" { default = {} } -variable "runner_worker_docker_autoscaler_autoscaling_options" { +variable "docker_autoscaler_autoscaling_options" { description = "Set autoscaling parameters based on periods, see https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersautoscalerpolicy-sections" type = list(object({ periods = list(string) @@ -301,7 +236,7 @@ variable "docker_machine_fleet" { } } -variable "runner_worker_docker_services" { +variable "docker_services" { description = "Starts additional services with the Docker container. All fields must be set (examine the Dockerfile of the service image for the entrypoint - see ./examples/runner-default/main.tf)" type = list(object({ name = string @@ -312,7 +247,7 @@ variable "runner_worker_docker_services" { default = [] } -variable "runner_worker_docker_options" { +variable "docker_options" { description = < Date: Thu, 20 Feb 2025 21:57:19 +0100 Subject: [PATCH 07/13] match variables --- main.tf | 34 +++++++++++++++--- modules/runner-config/variables.tf | 58 ------------------------------ 2 files changed, 29 insertions(+), 63 deletions(-) diff --git a/main.tf b/main.tf index 72f25eee7..55e9752a0 100644 --- a/main.tf +++ b/main.tf @@ -100,9 +100,26 @@ locals { module "runner" { source = "./modules/runner-config" + vpc_id = var.vpc_id + subnet_id = var.subnet_id + + suppressed_tags = var.suppressed_tags kms_key_arn = local.kms_key_arn + + runner_instance = var.runner_instance + runner_worker = var.runner_worker + runner_install = var.runner_install + runner_gitlab = var.runner_gitlab + + cache = var.runner_worker_cache cache_bucket_name = local.bucket_name + + gitlab_pipeline = var.runner_worker_gitlab_pipeline + + docker_autoscaler = var.runner_worker_docker_autoscaler docker_autoscaler_asg_name = var.runner_worker.type == "docker-autoscaler" ? aws_autoscaling_group.autoscaler[0].name : "" + docker_autoscaler_autoscaling_options = var.runner_worker_docker_autoscaler_autoscaling_options + docker_machine_runner_name = local.runner_tags_merged["Name"] docker_machine_availability_zone_name = data.aws_availability_zone.runners.name_suffix docker_machine_instance_profile_name = var.runner_worker.type == "docker+machine" ? aws_iam_instance_profile.docker_machine[0].name : "" @@ -111,11 +128,18 @@ module "runner" { docker_machine_fleet_launch_template_name = var.runner_worker_docker_machine_fleet.enable == true ? aws_launch_template.fleet_gitlab_runner[0].name : "" docker_machine_tags = local.runner_tags_merged docker_machine_instance = var.runner_worker_docker_machine_instance - - runner_worker = var.runner_worker - docker_autoscaler = var.runner_worker_docker_autoscaler - gitlab_pipeline = var.runner_worker_gitlab_pipeline - runner_gitlab = var.runner_gitlab + docker_machine_ec2_options = var.runner_worker_docker_machine_ec2_options + docker_machine_ec2_metadata_options = var.runner_worker_docker_machine_ec2_metadata_options + docker_machine_fleet = var.runner_worker_docker_machine_fleet + docker_machine_role = var.runner_worker_docker_machine_role + docker_machine_instance_spot = var.runner_worker_docker_machine_instance_spot + docker_machine_autoscaling_options = var.runner_worker_docker_machine_autoscaling_options + + docker_add_dind_volumes = var.runner_worker_docker_add_dind_volumes + docker_options = var.runner_worker_docker_options + docker_services = var.runner_worker_docker_services + docker_services_volumes_tmpfs = var.runner_worker_docker_services_volumes_tmpfs + docker_volumes_tmpfs = var.runner_worker_docker_volumes_tmpfs } # ignores: Autoscaling Groups Supply Tags --> we use a "dynamic" block to create the tags diff --git a/modules/runner-config/variables.tf b/modules/runner-config/variables.tf index 253f27997..de5de38b0 100644 --- a/modules/runner-config/variables.tf +++ b/modules/runner-config/variables.tf @@ -66,12 +66,6 @@ variable "runner_worker" { # kics-scan ignore-line use_private_key = optional(bool, false) }) - default = {} - - validation { - condition = contains(["docker+machine", "docker", "docker-autoscaler"], var.runner_worker.type) - error_message = "The executor currently supports `docker+machine` and `docker`." - } } variable "docker_autoscaler" { @@ -95,7 +89,6 @@ variable "docker_autoscaler" { update_interval_when_expecting = optional(string, "2s") instance_ready_command = optional(string, "") }) - default = {} } variable "gitlab_pipeline" { @@ -109,7 +102,6 @@ variable "gitlab_pipeline" { pre_build_script = optional(string, "\"\"") pre_clone_script = optional(string, "\"\"") }) - default = {} } variable "runner_gitlab" { @@ -137,7 +129,6 @@ variable "docker_machine_autoscaling_options" { idle_time = optional(number) timezone = optional(string, "UTC") })) - default = [] } variable "runner_instance" { @@ -147,9 +138,6 @@ variable "runner_instance" { type = object({ name = string }) - default = { - name = "gitlab-runner" - } } variable "docker_volumes_tmpfs" { @@ -158,7 +146,6 @@ variable "docker_volumes_tmpfs" { volume = string options = string })) - default = [] } variable "docker_services_volumes_tmpfs" { @@ -167,7 +154,6 @@ variable "docker_services_volumes_tmpfs" { volume = string options = string })) - default = [] } variable "cache" { @@ -185,7 +171,6 @@ variable "cache" { authentication_type = optional(string, "iam") shared = optional(bool, false) }) - default = {} } variable "docker_autoscaler_autoscaling_options" { @@ -198,7 +183,6 @@ variable "docker_autoscaler_autoscaling_options" { scale_factor = optional(number) scale_factor_limit = optional(number, 0) })) - default = [] } variable "docker_machine_instance_spot" { @@ -210,7 +194,6 @@ variable "docker_machine_instance_spot" { enable = optional(bool, true) max_price = optional(string, "on-demand-price") }) - default = {} } variable "docker_machine_role" { @@ -220,7 +203,6 @@ variable "docker_machine_role" { type = object({ profile_name = optional(string, "") }) - default = {} } variable "docker_machine_fleet" { @@ -231,9 +213,6 @@ variable "docker_machine_fleet" { type = object({ enable = bool }) - default = { - enable = false - } } variable "docker_services" { @@ -244,7 +223,6 @@ variable "docker_services" { entrypoint = list(string) command = list(string) })) - default = [] } variable "docker_options" { @@ -310,16 +288,6 @@ variable "docker_options" { volume_driver = optional(string) wait_for_services_timeout = optional(number) }) - - default = { - disable_cache = "false" - image = "docker:18.03.1-ce" - privileged = "true" - pull_policies = ["always"] - shm_size = 0 - tls_verify = "false" - volumes = ["/cache"] - } } variable "vpc_id" { @@ -346,29 +314,11 @@ variable "docker_machine_instance" { destroy_after_max_builds = optional(number, 0) docker_registry_mirror_url = optional(string, "") }) - default = { - } - - validation { - condition = length(var.docker_machine_instance.name_prefix) <= 28 - error_message = "Maximum length for docker+machine executor name is 28 characters!" - } - - validation { - condition = var.docker_machine_instance.name_prefix == "" || can(regex("^[a-zA-Z0-9\\.-]+$", var.docker_machine_instance.name_prefix)) - error_message = "Valid characters for the docker+machine executor name are: [a-zA-Z0-9\\.-]." - } - - validation { - condition = contains(["gp2", "gp3", "io1", "io2"], var.docker_machine_instance.volume_type) - error_message = "Supported volume types: gp2, gp3, io1 and io2" - } } variable "docker_machine_ami_id" { description = "The ID of the AMI to use for the Runner Worker (docker-machine)." type = string - default = "" } variable "docker_machine_ec2_metadata_options" { @@ -377,28 +327,21 @@ variable "docker_machine_ec2_metadata_options" { http_tokens = string http_put_response_hop_limit = number }) - default = { - http_tokens = "required" - http_put_response_hop_limit = 2 - } } variable "docker_machine_ec2_options" { description = "List of additional options for the docker+machine config. Each element of this list must be a key=value pair. E.g. '[\"amazonec2-zone=a\"]'" type = list(string) - default = [] } variable "docker_add_dind_volumes" { description = "Add certificates and docker.sock to the volumes to support docker-in-docker (dind)" type = bool - default = false } variable "suppressed_tags" { description = "List of tag keys which are automatically removed and never added as default tag by the module." type = list(string) - default = [] } variable "runner_install" { @@ -408,5 +351,4 @@ variable "runner_install" { type = object({ docker_machine_version = optional(string, "0.16.2-gitlab.19-cki.5") }) - default = {} } From e5d3971581a5c2743636cee69eb0f64c3cd35ace Mon Sep 17 00:00:00 2001 From: Matthias Kay Date: Thu, 20 Feb 2025 22:00:06 +0100 Subject: [PATCH 08/13] format code --- locals.tf | 2 +- main.tf | 60 ++--- modules/runner-config/locals.tf | 14 +- modules/runner-config/outputs.tf | 2 +- modules/runner-config/variables.tf | 372 ++++++++++++++--------------- 5 files changed, 225 insertions(+), 225 deletions(-) diff --git a/locals.tf b/locals.tf index 538ee7bad..455048d2c 100644 --- a/locals.tf +++ b/locals.tf @@ -44,7 +44,7 @@ locals { ) aws_iam_role_instance_arn = "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role/${local.aws_iam_role_instance_name}" - # Define key for runner token for SSM + # Define key for runner token for SSM secure_parameter_store_runner_token_key = "${var.environment}-${var.runner_gitlab_token_secure_parameter_store}" secure_parameter_store_runner_sentry_dsn = "${var.environment}-${var.runner_sentry_secure_parameter_store_name}" diff --git a/main.tf b/main.tf index 55e9752a0..82c892217 100644 --- a/main.tf +++ b/main.tf @@ -87,10 +87,10 @@ locals { template_runner_config = templatefile("runner-agent.tftpl", { - prometheus_listen_address = var.runner_manager.prometheus_listen_address - runners_check_interval = var.runner_manager.gitlab_check_interval - runners_concurrent = var.runner_manager.maximum_concurrent_jobs - sentry_dsn = var.runner_manager.sentry_dsn + prometheus_listen_address = var.runner_manager.prometheus_listen_address + runners_check_interval = var.runner_manager.gitlab_check_interval + runners_concurrent = var.runner_manager.maximum_concurrent_jobs + sentry_dsn = var.runner_manager.sentry_dsn runners = [module.runner.runner_config] } @@ -100,46 +100,46 @@ locals { module "runner" { source = "./modules/runner-config" - vpc_id = var.vpc_id + vpc_id = var.vpc_id subnet_id = var.subnet_id suppressed_tags = var.suppressed_tags - kms_key_arn = local.kms_key_arn + kms_key_arn = local.kms_key_arn runner_instance = var.runner_instance - runner_worker = var.runner_worker - runner_install = var.runner_install - runner_gitlab = var.runner_gitlab + runner_worker = var.runner_worker + runner_install = var.runner_install + runner_gitlab = var.runner_gitlab - cache = var.runner_worker_cache + cache = var.runner_worker_cache cache_bucket_name = local.bucket_name gitlab_pipeline = var.runner_worker_gitlab_pipeline - docker_autoscaler = var.runner_worker_docker_autoscaler - docker_autoscaler_asg_name = var.runner_worker.type == "docker-autoscaler" ? aws_autoscaling_group.autoscaler[0].name : "" + docker_autoscaler = var.runner_worker_docker_autoscaler + docker_autoscaler_asg_name = var.runner_worker.type == "docker-autoscaler" ? aws_autoscaling_group.autoscaler[0].name : "" docker_autoscaler_autoscaling_options = var.runner_worker_docker_autoscaler_autoscaling_options - docker_machine_runner_name = local.runner_tags_merged["Name"] - docker_machine_availability_zone_name = data.aws_availability_zone.runners.name_suffix - docker_machine_instance_profile_name = var.runner_worker.type == "docker+machine" ? aws_iam_instance_profile.docker_machine[0].name : "" - docker_machine_security_group_name = var.runner_worker.type == "docker+machine" ? aws_security_group.docker_machine[0].name : "" - docker_machine_ami_id = data.aws_ami.docker_machine_by_filter[0].id + docker_machine_runner_name = local.runner_tags_merged["Name"] + docker_machine_availability_zone_name = data.aws_availability_zone.runners.name_suffix + docker_machine_instance_profile_name = var.runner_worker.type == "docker+machine" ? aws_iam_instance_profile.docker_machine[0].name : "" + docker_machine_security_group_name = var.runner_worker.type == "docker+machine" ? aws_security_group.docker_machine[0].name : "" + docker_machine_ami_id = data.aws_ami.docker_machine_by_filter[0].id docker_machine_fleet_launch_template_name = var.runner_worker_docker_machine_fleet.enable == true ? aws_launch_template.fleet_gitlab_runner[0].name : "" - docker_machine_tags = local.runner_tags_merged - docker_machine_instance = var.runner_worker_docker_machine_instance - docker_machine_ec2_options = var.runner_worker_docker_machine_ec2_options - docker_machine_ec2_metadata_options = var.runner_worker_docker_machine_ec2_metadata_options - docker_machine_fleet = var.runner_worker_docker_machine_fleet - docker_machine_role = var.runner_worker_docker_machine_role - docker_machine_instance_spot = var.runner_worker_docker_machine_instance_spot - docker_machine_autoscaling_options = var.runner_worker_docker_machine_autoscaling_options - - docker_add_dind_volumes = var.runner_worker_docker_add_dind_volumes - docker_options = var.runner_worker_docker_options - docker_services = var.runner_worker_docker_services + docker_machine_tags = local.runner_tags_merged + docker_machine_instance = var.runner_worker_docker_machine_instance + docker_machine_ec2_options = var.runner_worker_docker_machine_ec2_options + docker_machine_ec2_metadata_options = var.runner_worker_docker_machine_ec2_metadata_options + docker_machine_fleet = var.runner_worker_docker_machine_fleet + docker_machine_role = var.runner_worker_docker_machine_role + docker_machine_instance_spot = var.runner_worker_docker_machine_instance_spot + docker_machine_autoscaling_options = var.runner_worker_docker_machine_autoscaling_options + + docker_add_dind_volumes = var.runner_worker_docker_add_dind_volumes + docker_options = var.runner_worker_docker_options + docker_services = var.runner_worker_docker_services docker_services_volumes_tmpfs = var.runner_worker_docker_services_volumes_tmpfs - docker_volumes_tmpfs = var.runner_worker_docker_volumes_tmpfs + docker_volumes_tmpfs = var.runner_worker_docker_volumes_tmpfs } # ignores: Autoscaling Groups Supply Tags --> we use a "dynamic" block to create the tags diff --git a/modules/runner-config/locals.tf b/modules/runner-config/locals.tf index a24b87538..a3efe7371 100644 --- a/modules/runner-config/locals.tf +++ b/modules/runner-config/locals.tf @@ -1,4 +1,4 @@ - locals { +locals { template_runner_worker_config = templatefile("${path.module}/template/runner-worker-config.tftpl", { aws_region = data.aws_region.current.name @@ -53,7 +53,7 @@ # Convert key from snake_case to PascalCase which is the casing for this section. key => jsonencode(value) if value != null }] - }) + }) template_runner_docker_machine = templatefile("${path.module}/template/runner-docker-machine-config.tftpl", { @@ -89,21 +89,21 @@ docker_machine_options = length(local.docker_machine_options_string) == 1 ? "" : local.docker_machine_options_string runners_max_growth_rate = var.docker_machine_instance.max_growth_rate runners_volume_kms_key = var.kms_key_arn - }) + }) runners_docker_services = templatefile("${path.module}/template/runners_docker_services.tftpl", { runners_docker_services = var.docker_services - } + } ) runners_docker_options_toml = templatefile("${path.module}/template/runners_docker_options.tftpl", { options = merge({ for key, value in var.docker_options : key => value if value != null && key != "volumes" && key != "pull_policies" - }, { + }, { pull_policy = var.docker_options.pull_policies volumes = local.runners_volumes }) - } + } ) # Convert list to a string separated and prepend by a comma @@ -125,7 +125,7 @@ runners_max_builds_string = var.docker_machine_instance.destroy_after_max_builds == 0 ? "" : format("MaxBuilds = %d", var.docker_machine_instance.destroy_after_max_builds) runners_docker_registry_mirror_option = var.docker_machine_instance.docker_registry_mirror_url == "" ? [] : ["engine-registry-mirror=${var.docker_machine_instance.docker_registry_mirror_url}"] - docker_machine_adds_name_tag = signum(sum(local.docker_machine_version_test)) <= 0 + docker_machine_adds_name_tag = signum(sum(local.docker_machine_version_test)) <= 0 docker_machine_version_test = [ for i, j in reverse(range(length(local.docker_machine_version_used))) : signum(local.docker_machine_version_with_name_tag[i] - local.docker_machine_version_used[i]) * pow(10, j) diff --git a/modules/runner-config/outputs.tf b/modules/runner-config/outputs.tf index afd60804a..e0c47c7e1 100644 --- a/modules/runner-config/outputs.tf +++ b/modules/runner-config/outputs.tf @@ -1,4 +1,4 @@ output "runner_config" { - value = "" + value = "" description = "Runner configuration in TOML format for the agent's configuration file" } diff --git a/modules/runner-config/variables.tf b/modules/runner-config/variables.tf index de5de38b0..379d259a4 100644 --- a/modules/runner-config/variables.tf +++ b/modules/runner-config/variables.tf @@ -1,50 +1,50 @@ variable "docker_machine_tags" { - description = "The tags to apply to the docker machine." - type = map(string) + description = "The tags to apply to the docker machine." + type = map(string) } variable "docker_machine_fleet_launch_template_name" { - description = "The name of the launch template for the docker machine fleet." - type = string + description = "The name of the launch template for the docker machine fleet." + type = string } variable "docker_machine_security_group_name" { - description = "The name of the security group for the docker machine." - type = string + description = "The name of the security group for the docker machine." + type = string } variable "docker_machine_instance_profile_name" { - description = "The name of the instance profile for the docker machine." - type = string + description = "The name of the instance profile for the docker machine." + type = string } variable "docker_machine_availability_zone_name" { - description = "The name of the availability zone for the docker machine." - type = string + description = "The name of the availability zone for the docker machine." + type = string } variable "docker_machine_runner_name" { - description = "The name of the instance." - type = string + description = "The name of the instance." + type = string } variable "docker_autoscaler_asg_name" { - description = "The name of the autoscaling group for the docker autoscaler." - type = string + description = "The name of the autoscaling group for the docker autoscaler." + type = string } variable "cache_bucket_name" { - description = "The name of the S3 bucket to use for caching." - type = string + description = "The name of the S3 bucket to use for caching." + type = string } variable "kms_key_arn" { - description = "The ARN of the KMS key to use for encrypting everything." - type = string + description = "The ARN of the KMS key to use for encrypting everything." + type = string } variable "runner_worker" { - description = <<-EOT + description = <<-EOT For detailed information, check https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section. environment_variables = List of environment variables to add to the Runner Worker (environment). @@ -55,21 +55,21 @@ variable "runner_worker" { type = The Runner Worker type to use. Currently supports `docker+machine` or `docker` or `docker-autoscaler`. use_private_key = Use a private key to connect the Runner Manager to the Runner Workers. Ignored when fleeting is enabled (defaults to `true`). EOT - type = object({ - environment_variables = optional(list(string), []) - max_jobs = optional(number, 0) - output_limit = optional(number, 4096) - request_concurrency = optional(number, 1) - ssm_access = optional(bool, false) - type = optional(string, "docker+machine") - # false positive, use_private_key is not a secret - # kics-scan ignore-line - use_private_key = optional(bool, false) - }) + type = object({ + environment_variables = optional(list(string), []) + max_jobs = optional(number, 0) + output_limit = optional(number, 4096) + request_concurrency = optional(number, 1) + ssm_access = optional(bool, false) + type = optional(string, "docker+machine") + # false positive, use_private_key is not a secret + # kics-scan ignore-line + use_private_key = optional(bool, false) + }) } variable "docker_autoscaler" { - description = <<-EOT + description = <<-EOT fleeting_plugin_version = The version of aws fleeting plugin. connector_config_user = User to connect to worker machine. key_pair_name = The name of the key pair used by the Runner to connect to the docker-machine Runner Workers. This variable is only supported when `enables` is set to `true`. @@ -79,85 +79,85 @@ variable "docker_autoscaler" { update_interval_when_expecting = The interval to check with the fleeting plugin for instance updates when expecting a state change. instance_ready_command = Executes this command on each instance provisioned by the autoscaler to ensure that it is ready for use. A failure results in the instance being removed. EOT - type = object({ - fleeting_plugin_version = optional(string, "1.0.0") - connector_config_user = optional(string, "ec2-user") - key_pair_name = optional(string, "runner-worker-key") - capacity_per_instance = optional(number, 1) - max_use_count = optional(number, 100) - update_interval = optional(string, "1m") - update_interval_when_expecting = optional(string, "2s") - instance_ready_command = optional(string, "") - }) + type = object({ + fleeting_plugin_version = optional(string, "1.0.0") + connector_config_user = optional(string, "ec2-user") + key_pair_name = optional(string, "runner-worker-key") + capacity_per_instance = optional(number, 1) + max_use_count = optional(number, 100) + update_interval = optional(string, "1m") + update_interval_when_expecting = optional(string, "2s") + instance_ready_command = optional(string, "") + }) } variable "gitlab_pipeline" { - description = <<-EOT + description = <<-EOT post_build_script = Script to execute in the pipeline just after the build, but before executing after_script. pre_build_script = Script to execute in the pipeline just before the build. pre_clone_script = Script to execute in the pipeline before cloning the Git repository. this can be used to adjust the Git client configuration first, for example. EOT - type = object({ - post_build_script = optional(string, "\"\"") - pre_build_script = optional(string, "\"\"") - pre_clone_script = optional(string, "\"\"") - }) + type = object({ + post_build_script = optional(string, "\"\"") + pre_build_script = optional(string, "\"\"") + pre_clone_script = optional(string, "\"\"") + }) } variable "runner_gitlab" { - description = <<-EOT + description = <<-EOT certificate = Certificate of the GitLab instance to connect to (PEM format). registration_token = (deprecated, This is replaced by the `registration_token` in `runner_gitlab_registration_config`.) Registration token to use to register the Runner. url = URL of the GitLab instance to connect to. url_clone = URL of the GitLab instance to clone from. Use only if the agent can’t connect to the GitLab URL. EOT - type = object({ - certificate = optional(string, "") - registration_token = optional(string, "__REPLACED_BY_USER_DATA__") # deprecated, removed in 8.0.0 - url = optional(string, "") - url_clone = optional(string, "") - }) + type = object({ + certificate = optional(string, "") + registration_token = optional(string, "__REPLACED_BY_USER_DATA__") # deprecated, removed in 8.0.0 + url = optional(string, "") + url_clone = optional(string, "") + }) } variable "docker_machine_autoscaling_options" { - description = "Set autoscaling parameters based on periods, see https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersmachine-section" - type = list(object({ - periods = list(string) - idle_count = optional(number) - idle_scale_factor = optional(number) - idle_count_min = optional(number) - idle_time = optional(number) - timezone = optional(string, "UTC") - })) + description = "Set autoscaling parameters based on periods, see https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersmachine-section" + type = list(object({ + periods = list(string) + idle_count = optional(number) + idle_scale_factor = optional(number) + idle_count_min = optional(number) + idle_time = optional(number) + timezone = optional(string, "UTC") + })) } variable "runner_instance" { - description = <<-EOT + description = <<-EOT name = Name of the Runner instance. EOT - type = object({ - name = string - }) + type = object({ + name = string + }) } variable "docker_volumes_tmpfs" { - description = "Mount a tmpfs in Executor container. https://docs.gitlab.com/runner/executors/docker.html#mounting-a-directory-in-ram" - type = list(object({ - volume = string - options = string - })) + description = "Mount a tmpfs in Executor container. https://docs.gitlab.com/runner/executors/docker.html#mounting-a-directory-in-ram" + type = list(object({ + volume = string + options = string + })) } variable "docker_services_volumes_tmpfs" { - description = "Mount a tmpfs in gitlab service container. https://docs.gitlab.com/runner/executors/docker.html#mounting-a-directory-in-ram" - type = list(object({ - volume = string - options = string - })) + description = "Mount a tmpfs in gitlab service container. https://docs.gitlab.com/runner/executors/docker.html#mounting-a-directory-in-ram" + type = list(object({ + volume = string + options = string + })) } variable "cache" { - description = <<-EOT + description = <<-EOT Configuration to control the creation of the cache bucket. By default the bucket will be created and used as shared cache. To use the same cache across multiple Runner Worker disable the creation of the cache and provide a policy and bucket name. See the public runner example for more details." @@ -167,66 +167,66 @@ variable "cache" { authentication_type = A string that declares the AuthenticationType for [runners.cache.s3]. Can either be 'iam' or 'credentials'. shared = Boolean used to enable or disable the use of the cache bucket as shared cache. EOT - type = object({ - authentication_type = optional(string, "iam") - shared = optional(bool, false) - }) + type = object({ + authentication_type = optional(string, "iam") + shared = optional(bool, false) + }) } variable "docker_autoscaler_autoscaling_options" { - description = "Set autoscaling parameters based on periods, see https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersautoscalerpolicy-sections" - type = list(object({ - periods = list(string) - timezone = optional(string, "UTC") - idle_count = optional(number) - idle_time = optional(string) - scale_factor = optional(number) - scale_factor_limit = optional(number, 0) - })) + description = "Set autoscaling parameters based on periods, see https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersautoscalerpolicy-sections" + type = list(object({ + periods = list(string) + timezone = optional(string, "UTC") + idle_count = optional(number) + idle_time = optional(string) + scale_factor = optional(number) + scale_factor_limit = optional(number, 0) + })) } variable "docker_machine_instance_spot" { - description = <<-EOT + description = <<-EOT enable = Enable spot instances for the Runner Worker. max_price = The maximum price willing to pay. By default the price is limited by the current on demand price for the instance type chosen. EOT - type = object({ - enable = optional(bool, true) - max_price = optional(string, "on-demand-price") - }) + type = object({ + enable = optional(bool, true) + max_price = optional(string, "on-demand-price") + }) } variable "docker_machine_role" { - description = <<-EOT + description = <<-EOT profile_name = Name of the IAM profile to attach to the Runner Workers. EOT - type = object({ - profile_name = optional(string, "") - }) + type = object({ + profile_name = optional(string, "") + }) } variable "docker_machine_fleet" { - description = <<-EOT + description = <<-EOT enable = Activates the fleet mode on the Runner. https://gitlab.com/cki-project/docker-machine/-/blob/v0.16.2-gitlab.19-cki.2/docs/drivers/aws.md#fleet-mode key_pair_name = The name of the key pair used by the Runner to connect to the docker-machine Runner Workers. This variable is only supported when `enables` is set to `true`. EOT - type = object({ - enable = bool - }) + type = object({ + enable = bool + }) } variable "docker_services" { - description = "Starts additional services with the Docker container. All fields must be set (examine the Dockerfile of the service image for the entrypoint - see ./examples/runner-default/main.tf)" - type = list(object({ - name = string - alias = string - entrypoint = list(string) - command = list(string) - })) + description = "Starts additional services with the Docker container. All fields must be set (examine the Dockerfile of the service image for the entrypoint - see ./examples/runner-default/main.tf)" + type = list(object({ + name = string + alias = string + entrypoint = list(string) + command = list(string) + })) } variable "docker_options" { - description = < Date: Thu, 20 Feb 2025 22:05:48 +0100 Subject: [PATCH 09/13] move templates --- modules/runner-config/locals.tf | 2 +- .../runner-config/template}/runner-definition.tftpl | 0 .../template}/runner-docker-autoscaler-config.tftpl | 0 .../runner-config/template}/runner-docker-machine-config.tftpl | 0 .../runner-config/template}/runners_docker_options.tftpl | 0 .../runner-config/template}/runners_docker_services.tftpl | 0 6 files changed, 1 insertion(+), 1 deletion(-) rename {template => modules/runner-config/template}/runner-definition.tftpl (100%) rename {template => modules/runner-config/template}/runner-docker-autoscaler-config.tftpl (100%) rename {template => modules/runner-config/template}/runner-docker-machine-config.tftpl (100%) rename {template => modules/runner-config/template}/runners_docker_options.tftpl (100%) rename {template => modules/runner-config/template}/runners_docker_services.tftpl (100%) diff --git a/modules/runner-config/locals.tf b/modules/runner-config/locals.tf index a3efe7371..7674127db 100644 --- a/modules/runner-config/locals.tf +++ b/modules/runner-config/locals.tf @@ -1,5 +1,5 @@ locals { - template_runner_worker_config = templatefile("${path.module}/template/runner-worker-config.tftpl", + template_runner_worker_config = templatefile("${path.module}/template/runner-definition.tftpl", { aws_region = data.aws_region.current.name gitlab_url = var.runner_gitlab.url diff --git a/template/runner-definition.tftpl b/modules/runner-config/template/runner-definition.tftpl similarity index 100% rename from template/runner-definition.tftpl rename to modules/runner-config/template/runner-definition.tftpl diff --git a/template/runner-docker-autoscaler-config.tftpl b/modules/runner-config/template/runner-docker-autoscaler-config.tftpl similarity index 100% rename from template/runner-docker-autoscaler-config.tftpl rename to modules/runner-config/template/runner-docker-autoscaler-config.tftpl diff --git a/template/runner-docker-machine-config.tftpl b/modules/runner-config/template/runner-docker-machine-config.tftpl similarity index 100% rename from template/runner-docker-machine-config.tftpl rename to modules/runner-config/template/runner-docker-machine-config.tftpl diff --git a/template/runners_docker_options.tftpl b/modules/runner-config/template/runners_docker_options.tftpl similarity index 100% rename from template/runners_docker_options.tftpl rename to modules/runner-config/template/runners_docker_options.tftpl diff --git a/template/runners_docker_services.tftpl b/modules/runner-config/template/runners_docker_services.tftpl similarity index 100% rename from template/runners_docker_services.tftpl rename to modules/runner-config/template/runners_docker_services.tftpl From 98e13afcffd56c95a34bfe840e0d2a12456b9f7c Mon Sep 17 00:00:00 2001 From: Matthias Kay Date: Thu, 20 Feb 2025 22:12:28 +0100 Subject: [PATCH 10/13] add missing attributes --- main.tf | 2 +- modules/runner-config/variables.tf | 34 ++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/main.tf b/main.tf index 82c892217..c371acc9e 100644 --- a/main.tf +++ b/main.tf @@ -85,7 +85,7 @@ locals { fleeting_plugin_version = var.runner_worker_docker_autoscaler.fleeting_plugin_version }) - template_runner_config = templatefile("runner-agent.tftpl", + template_runner_config = templatefile("${path.module}/template/runner-agent.tftpl", { prometheus_listen_address = var.runner_manager.prometheus_listen_address runners_check_interval = var.runner_manager.gitlab_check_interval diff --git a/modules/runner-config/variables.tf b/modules/runner-config/variables.tf index 379d259a4..b73219bcc 100644 --- a/modules/runner-config/variables.tf +++ b/modules/runner-config/variables.tf @@ -309,10 +309,40 @@ variable "docker_machine_instance" { docker_registry_mirror_url = The URL of the Docker registry mirror to use for the Runner Worker. destroy_after_max_builds = Destroy the instance after the maximum number of builds has been reached. + ebs_optimized = Enable EBS optimization for the Runner Worker. + idle_count = Number of idle Runner Worker instances (not working for the Docker Runner Worker) (IdleCount). + idle_time = Idle time of the Runner Worker before they are destroyed (not working for the Docker Runner Worker) (IdleTime). + max_growth_rate = The maximum number of machines that can be added to the runner in parallel. + monitoring = Enable detailed monitoring for the Runner Worker. + name_prefix = Set the name prefix and override the `Name` tag for the Runner Worker. + private_address_only = Restrict Runner Worker to the use of a private IP address. If `runner_instance.use_private_address_only` is set to `true` (default), `runner_worker_docker_machine_instance.private_address_only` will also apply for the Runner. + root_device_name = The name of the root volume for the Runner Worker. + root_size = The size of the root volume for the Runner Worker. + start_script = Cloud-init user data that will be passed to the Runner Worker. Should not be base64 encrypted. + subnet_ids = The list of subnet IDs to use for the Runner Worker when the fleet mode is enabled. + types = The type of instance to use for the Runner Worker. In case of fleet mode, multiple instance types are supported. + volume_type = The type of volume to use for the Runner Worker. `gp2`, `gp3`, `io1` or `io2` are supported. + volume_throughput = Throughput in MB/s for the volume. Only supported when using `gp3` as `volume_type`. + volume_iops = Guaranteed IOPS for the volume. Only supported when using `gp3`, `io1` or `io2` as `volume_type`. Works for fleeting only. See `runner_worker_docker_machine_fleet`. EOT type = object({ - destroy_after_max_builds = optional(number, 0) - docker_registry_mirror_url = optional(string, "") + destroy_after_max_builds = optional(number, 0) + docker_registry_mirror_url = optional(string, "") + ebs_optimized = optional(bool, true) + idle_count = optional(number, 0) + idle_time = optional(number, 600) + max_growth_rate = optional(number, 0) + monitoring = optional(bool, false) + name_prefix = optional(string, "") + private_address_only = optional(bool, true) + root_device_name = optional(string, "/dev/sda1") + root_size = optional(number, 8) + start_script = optional(string, "") + subnet_ids = optional(list(string), []) + types = optional(list(string), ["m5.large"]) + volume_type = optional(string, "gp2") + volume_throughput = optional(number, 125) + volume_iops = optional(number, 3000) }) } From 6c9ee5d7bc304ebed035f700c826a4b0e1f0d970 Mon Sep 17 00:00:00 2001 From: Matthias Kay Date: Thu, 20 Feb 2025 22:14:01 +0100 Subject: [PATCH 11/13] format code --- modules/runner-config/variables.tf | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/modules/runner-config/variables.tf b/modules/runner-config/variables.tf index b73219bcc..c9dd31162 100644 --- a/modules/runner-config/variables.tf +++ b/modules/runner-config/variables.tf @@ -326,23 +326,23 @@ variable "docker_machine_instance" { volume_iops = Guaranteed IOPS for the volume. Only supported when using `gp3`, `io1` or `io2` as `volume_type`. Works for fleeting only. See `runner_worker_docker_machine_fleet`. EOT type = object({ - destroy_after_max_builds = optional(number, 0) - docker_registry_mirror_url = optional(string, "") - ebs_optimized = optional(bool, true) - idle_count = optional(number, 0) - idle_time = optional(number, 600) - max_growth_rate = optional(number, 0) - monitoring = optional(bool, false) - name_prefix = optional(string, "") - private_address_only = optional(bool, true) - root_device_name = optional(string, "/dev/sda1") - root_size = optional(number, 8) - start_script = optional(string, "") - subnet_ids = optional(list(string), []) - types = optional(list(string), ["m5.large"]) - volume_type = optional(string, "gp2") - volume_throughput = optional(number, 125) - volume_iops = optional(number, 3000) + destroy_after_max_builds = optional(number, 0) + docker_registry_mirror_url = optional(string, "") + ebs_optimized = optional(bool, true) + idle_count = optional(number, 0) + idle_time = optional(number, 600) + max_growth_rate = optional(number, 0) + monitoring = optional(bool, false) + name_prefix = optional(string, "") + private_address_only = optional(bool, true) + root_device_name = optional(string, "/dev/sda1") + root_size = optional(number, 8) + start_script = optional(string, "") + subnet_ids = optional(list(string), []) + types = optional(list(string), ["m5.large"]) + volume_type = optional(string, "gp2") + volume_throughput = optional(number, 125) + volume_iops = optional(number, 3000) }) } From fe5f6b013227b7ca310b3e6f8c7a3fa1c9581580 Mon Sep 17 00:00:00 2001 From: Matthias Kay Date: Thu, 20 Feb 2025 22:19:59 +0100 Subject: [PATCH 12/13] fix checkov --- main.tf | 2 ++ modules/terminate-agent-hook/main.tf | 1 + 2 files changed, 3 insertions(+) diff --git a/main.tf b/main.tf index c371acc9e..b9e0ffb2f 100644 --- a/main.tf +++ b/main.tf @@ -1,5 +1,6 @@ # Parameter value is managed by the user-data script of the gitlab runner instance resource "aws_ssm_parameter" "runner_registration_token" { + # checkov:skip=CKV_AWS_337:KMS key can be enabled by the user name = local.secure_parameter_store_runner_token_key type = "SecureString" value = "null" @@ -14,6 +15,7 @@ resource "aws_ssm_parameter" "runner_registration_token" { } resource "aws_ssm_parameter" "runner_sentry_dsn" { + # checkov:skip=CKV_AWS_337:KMS key can be enabled by the user name = local.secure_parameter_store_runner_sentry_dsn type = "SecureString" value = "null" diff --git a/modules/terminate-agent-hook/main.tf b/modules/terminate-agent-hook/main.tf index c7dc06a27..e66e10a66 100644 --- a/modules/terminate-agent-hook/main.tf +++ b/modules/terminate-agent-hook/main.tf @@ -25,6 +25,7 @@ resource "aws_lambda_function" "terminate_runner_instances" { # checkov:skip=CKV_AWS_115:We do not assign a reserved concurrency as this function can't be called by users # checkov:skip=CKV_AWS_116:We should think about having a dead letter queue for this lambda # checkov:skip=CKV_AWS_117:There is no need to run this lambda in our VPC + # checkov:skip=CKV_AWS_173:false-positive, kms_key_arn is set # checkov:skip=CKV_AWS_272:Code signing would be a nice enhancement, but I guess we can live without it here architectures = ["x86_64"] description = "Lifecycle hook for terminating GitLab runner agent instances" From 820d316b24a1a109c665e37c0b4d20c88abb4e38 Mon Sep 17 00:00:00 2001 From: Matthias Kay Date: Thu, 20 Feb 2025 22:23:49 +0100 Subject: [PATCH 13/13] fix kics --- modules/runner-config/variables.tf | 8 +++++--- variables.tf | 4 +--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/runner-config/variables.tf b/modules/runner-config/variables.tf index c9dd31162..cd68b3147 100644 --- a/modules/runner-config/variables.tf +++ b/modules/runner-config/variables.tf @@ -43,6 +43,8 @@ variable "kms_key_arn" { type = string } +# false positive, use_private_key is not a secret +# kics-scan ignore-block variable "runner_worker" { description = <<-EOT For detailed information, check https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section. @@ -62,9 +64,7 @@ variable "runner_worker" { request_concurrency = optional(number, 1) ssm_access = optional(bool, false) type = optional(string, "docker+machine") - # false positive, use_private_key is not a secret - # kics-scan ignore-line - use_private_key = optional(bool, false) + use_private_key = optional(bool, false) }) } @@ -104,6 +104,8 @@ variable "gitlab_pipeline" { }) } +# false positive, registration_token has no secret value here +# kics-scan ignore-block variable "runner_gitlab" { description = <<-EOT certificate = Certificate of the GitLab instance to connect to (PEM format). diff --git a/variables.tf b/variables.tf index 3092ce92e..91950cec8 100644 --- a/variables.tf +++ b/variables.tf @@ -471,9 +471,7 @@ variable "runner_worker" { request_concurrency = optional(number, 1) ssm_access = optional(bool, false) type = optional(string, "docker+machine") - # false positive, use_private_key is not a secret - # kics-scan ignore-line - use_private_key = optional(bool, false) + use_private_key = optional(bool, false) }) default = {}