diff --git a/modules/multi-runner/ami-housekeeper.tf b/modules/multi-runner/ami-housekeeper.tf index 385e6010c9..88d82b7f0b 100644 --- a/modules/multi-runner/ami-housekeeper.tf +++ b/modules/multi-runner/ami-housekeeper.tf @@ -1,35 +1,35 @@ module "ami_housekeeper" { - count = var.enable_ami_housekeeper ? 1 : 0 + count = try(local.effective_config.compute_provider.aws.ec2.ami.housekeeper.enabled, false) ? 1 : 0 source = "../ami-housekeeper" prefix = var.prefix tags = local.tags aws_partition = var.aws_partition - lambda_zip = var.ami_housekeeper_lambda_zip - lambda_s3_bucket = var.lambda_s3_bucket - lambda_s3_key = var.ami_housekeeper_lambda_s3_key - lambda_s3_object_version = var.ami_housekeeper_lambda_s3_object_version + lambda_zip = try(local.effective_config.compute_provider.aws.ec2.ami.housekeeper.artifact.zip, null) + lambda_s3_bucket = try(local.effective_config.lambda.artifact.s3.bucket, null) + lambda_s3_key = try(local.effective_config.compute_provider.aws.ec2.ami.housekeeper.artifact.s3.key, null) + lambda_s3_object_version = try(local.effective_config.compute_provider.aws.ec2.ami.housekeeper.artifact.s3.object_version, null) - lambda_architecture = var.lambda_architecture - lambda_principals = var.lambda_principals - lambda_runtime = var.lambda_runtime - lambda_security_group_ids = var.lambda_security_group_ids - lambda_subnet_ids = var.lambda_subnet_ids - lambda_memory_size = var.ami_housekeeper_lambda_memory_size - lambda_timeout = var.ami_housekeeper_lambda_timeout - lambda_tags = var.lambda_tags - tracing_config = var.tracing_config + lambda_architecture = local.effective_config.lambda.architecture + lambda_principals = local.effective_config.lambda.principals + lambda_runtime = local.effective_config.lambda.runtime + lambda_security_group_ids = local.effective_config.lambda.security_group_ids + lambda_subnet_ids = local.effective_config.lambda.subnet_ids + lambda_memory_size = local.effective_config.compute_provider.aws.ec2.ami.housekeeper.lambda.memory_size + lambda_timeout = local.effective_config.compute_provider.aws.ec2.ami.housekeeper.lambda.timeout + lambda_tags = local.effective_config.lambda.tags + tracing_config = local.effective_config.observability.tracing - logging_retention_in_days = var.logging_retention_in_days - logging_kms_key_id = var.logging_kms_key_id - log_class = var.log_class - log_level = var.log_level + logging_retention_in_days = local.effective_config.observability.logs.retention_in_days + logging_kms_key_id = local.effective_config.observability.logs.kms_key_id + log_class = local.effective_config.observability.logs.class + log_level = local.effective_config.observability.logs.level - role_path = var.role_path - role_permissions_boundary = var.role_permissions_boundary + role_path = local.effective_config.roles.path + role_permissions_boundary = local.effective_config.roles.permissions_boundary - cleanup_config = var.ami_housekeeper_cleanup_config - lambda_schedule_expression = var.ami_housekeeper_lambda_schedule_expression + cleanup_config = local.effective_config.compute_provider.aws.ec2.ami.housekeeper.cleanup_config + lambda_schedule_expression = local.effective_config.compute_provider.aws.ec2.ami.housekeeper.schedule.expression } diff --git a/modules/multi-runner/config.experimental.effective.tf b/modules/multi-runner/config.experimental.effective.tf index 28831a0033..1a53a16520 100644 --- a/modules/multi-runner/config.experimental.effective.tf +++ b/modules/multi-runner/config.experimental.effective.tf @@ -10,7 +10,7 @@ locals { v.runner.os, v.runner.architecture, ]), - v.orchestration_provider.webhook == null ? [] : flatten(v.orchestration_provider.webhook.matcherConfig.labelMatchers), + try(flatten(v.orchestration_provider.webhook.matcherConfig.labelMatchers), []), compact(v.runner.extra_labels), )) }) diff --git a/modules/multi-runner/main.tf b/modules/multi-runner/main.tf index 7f3cc88d35..b9dbf243a3 100644 --- a/modules/multi-runner/main.tf +++ b/modules/multi-runner/main.tf @@ -1,10 +1,10 @@ locals { - tags = merge(var.tags, { + tags = merge(local.effective_config.tags, { "ghr:environment" = var.prefix }) - primary_app_id = coalesce(var.github_app.id_ssm, module.ssm.parameters.github_app_id) - primary_app_key_base64 = coalesce(var.github_app.key_base64_ssm, module.ssm.parameters.github_app_key_base64) + primary_app_id = coalesce(local.effective_config.github.app.id_ssm, module.ssm.parameters.github_app_id) + primary_app_key_base64 = coalesce(local.effective_config.github.app.key_base64_ssm, module.ssm.parameters.github_app_key_base64) github_app_parameters = { id = concat( @@ -19,24 +19,13 @@ locals { [null], [for p in module.ssm.additional_app_parameters : p.installation_id] ) - webhook_secret = coalesce(var.github_app.webhook_secret_ssm, module.ssm.parameters.github_app_webhook_secret) + webhook_secret = coalesce(local.effective_config.github.app.webhook_secret_ssm, module.ssm.parameters.github_app_webhook_secret) } - runner_extra_labels = { for k, v in local.legacy_multi_runner_config : k => sort(setunion(flatten(v.matcherConfig.labelMatchers), compact(v.runner_config.runner_extra_labels))) } - - runner_config = { for k, v in local.legacy_multi_runner_config : k => merge( - { - id = aws_sqs_queue.queued_builds[k].id - arn = aws_sqs_queue.queued_builds[k].arn - url = aws_sqs_queue.queued_builds[k].url - }, - merge(v, { runner_config = merge(v.runner_config, { runner_extra_labels = local.runner_extra_labels[k] }) }), - ) } - - tmp_distinct_list_unique_os_and_arch = distinct([for i, config in local.runner_config : { "os_type" : config.runner_config.runner_os, "architecture" : config.runner_config.runner_architecture } if config.runner_config.enable_runner_binaries_syncer]) - unique_os_and_arch = { for i, v in local.tmp_distinct_list_unique_os_and_arch : "${v.os_type}_${v.architecture}" => v } - - ssm_root_path = "/${var.ssm_paths.root}/${var.prefix}" + ssm_root_path = trimsuffix(coalesce( + local.effective_config.ssm.paths.root, + "/github-action-runners/${var.prefix}", + ), "/") } resource "random_string" "random" { diff --git a/modules/multi-runner/outputs.tf b/modules/multi-runner/outputs.tf index 50adb7fe46..7c4a9807d1 100644 --- a/modules/multi-runner/outputs.tf +++ b/modules/multi-runner/outputs.tf @@ -39,8 +39,8 @@ output "webhook" { lambda_role = module.webhook.role endpoint = "${module.webhook.gateway.api_endpoint}/${module.webhook.endpoint_relative_path}" webhook = module.webhook.webhook - dispatcher = var.eventbridge.enable ? module.webhook.dispatcher : null - eventbridge = var.eventbridge.enable ? module.webhook.eventbridge : null + dispatcher = local.effective_config.orchestration_provider.webhook.eventbridge.enabled ? module.webhook.dispatcher : null + eventbridge = local.effective_config.orchestration_provider.webhook.eventbridge.enabled ? module.webhook.eventbridge : null } } @@ -67,7 +67,7 @@ output "ssm_parameters" { } output "instance_termination_watcher" { - value = var.instance_termination_watcher.enable && var.instance_termination_watcher.features.enable_spot_termination_notification_watcher ? { + value = try(local.effective_config.compute_provider.aws.ec2.instance_termination_watcher.enabled, false) && local.effective_config.compute_provider.aws.ec2.instance_termination_watcher.features.spot_termination_notification_watcher.enabled ? { lambda = module.instance_termination_watcher[0].spot_termination_notification.lambda lambda_log_group = module.instance_termination_watcher[0].spot_termination_notification.lambda_log_group lambda_role = module.instance_termination_watcher[0].spot_termination_notification.lambda_role @@ -75,7 +75,7 @@ output "instance_termination_watcher" { } output "instance_termination_handler" { - value = var.instance_termination_watcher.enable && var.instance_termination_watcher.features.enable_spot_termination_handler ? { + value = try(local.effective_config.compute_provider.aws.ec2.instance_termination_watcher.enabled, false) && local.effective_config.compute_provider.aws.ec2.instance_termination_watcher.features.spot_termination_handler.enabled ? { lambda = module.instance_termination_watcher[0].spot_termination_handler.lambda lambda_log_group = module.instance_termination_watcher[0].spot_termination_handler.lambda_log_group lambda_role = module.instance_termination_watcher[0].spot_termination_handler.lambda_role diff --git a/modules/multi-runner/queues.tf b/modules/multi-runner/queues.tf index 5cceaf0d63..0f57020571 100644 --- a/modules/multi-runner/queues.tf +++ b/modules/multi-runner/queues.tf @@ -27,42 +27,56 @@ data "aws_iam_policy_document" "deny_insecure_transport" { } resource "aws_sqs_queue" "queued_builds" { - for_each = local.legacy_multi_runner_config + for_each = local.effective_config.multi_runner_config name = "${var.prefix}-${each.key}-queued-builds" - delay_seconds = each.value.runner_config.delay_webhook_event - visibility_timeout_seconds = var.runners_scale_up_lambda_timeout - message_retention_seconds = each.value.runner_config.job_queue_retention_in_seconds + delay_seconds = each.value.orchestration_provider.webhook.queue.delay_webhook_event + visibility_timeout_seconds = each.value.orchestration_provider.webhook.queue.visibility_timeout_seconds + message_retention_seconds = each.value.orchestration_provider.webhook.queue.job_queue_retention_in_seconds receive_wait_time_seconds = 0 - redrive_policy = each.value.redrive_build_queue.enabled ? jsonencode({ + redrive_policy = each.value.orchestration_provider.webhook.queue.redrive_build_queue.enabled ? jsonencode({ deadLetterTargetArn = aws_sqs_queue.queued_builds_dlq[each.key].arn, - maxReceiveCount = each.value.redrive_build_queue.maxReceiveCount + maxReceiveCount = each.value.orchestration_provider.webhook.queue.redrive_build_queue.maxReceiveCount }) : null - sqs_managed_sse_enabled = var.queue_encryption.sqs_managed_sse_enabled - kms_master_key_id = var.queue_encryption.kms_master_key_id - kms_data_key_reuse_period_seconds = var.queue_encryption.kms_data_key_reuse_period_seconds + sqs_managed_sse_enabled = local.effective_config.orchestration_provider.webhook.queue.encryption.sqs_managed_sse_enabled + kms_master_key_id = local.effective_config.orchestration_provider.webhook.queue.encryption.kms_master_key_id + kms_data_key_reuse_period_seconds = local.effective_config.orchestration_provider.webhook.queue.encryption.kms_data_key_reuse_period_seconds - tags = var.tags + tags = merge( + local.effective_config.tags, + each.value.tags, + each.value.orchestration_provider.webhook.queue.tags, + ) } resource "aws_sqs_queue_policy" "build_queue_policy" { - for_each = local.legacy_multi_runner_config + for_each = local.effective_config.multi_runner_config queue_url = aws_sqs_queue.queued_builds[each.key].id policy = data.aws_iam_policy_document.deny_insecure_transport.json } resource "aws_sqs_queue" "queued_builds_dlq" { - for_each = { for config, values in local.legacy_multi_runner_config : config => values if values.redrive_build_queue.enabled } - name = "${var.prefix}-${each.key}-queued-builds_dead_letter" + for_each = { + for config, values in local.effective_config.multi_runner_config : config => values + if values.orchestration_provider.webhook.queue.redrive_build_queue.enabled + } + name = "${var.prefix}-${each.key}-queued-builds_dead_letter" - sqs_managed_sse_enabled = var.queue_encryption.sqs_managed_sse_enabled - kms_master_key_id = var.queue_encryption.kms_master_key_id - kms_data_key_reuse_period_seconds = var.queue_encryption.kms_data_key_reuse_period_seconds - tags = var.tags + sqs_managed_sse_enabled = local.effective_config.orchestration_provider.webhook.queue.encryption.sqs_managed_sse_enabled + kms_master_key_id = local.effective_config.orchestration_provider.webhook.queue.encryption.kms_master_key_id + kms_data_key_reuse_period_seconds = local.effective_config.orchestration_provider.webhook.queue.encryption.kms_data_key_reuse_period_seconds + tags = merge( + local.effective_config.tags, + each.value.tags, + each.value.orchestration_provider.webhook.queue.tags, + ) } resource "aws_sqs_queue_policy" "build_queue_dlq_policy" { - for_each = { for config, values in local.legacy_multi_runner_config : config => values if values.redrive_build_queue.enabled } + for_each = { + for config, values in local.effective_config.multi_runner_config : config => values + if values.orchestration_provider.webhook.queue.redrive_build_queue.enabled + } queue_url = aws_sqs_queue.queued_builds_dlq[each.key].id policy = data.aws_iam_policy_document.deny_insecure_transport.json } diff --git a/modules/multi-runner/runners.tf b/modules/multi-runner/runners.tf index 892113dcc7..61c5f57583 100644 --- a/modules/multi-runner/runners.tf +++ b/modules/multi-runner/runners.tf @@ -1,130 +1,171 @@ module "runners" { source = "../runners" - for_each = local.runner_config + for_each = local.effective_config.multi_runner_config aws_region = var.aws_region aws_partition = var.aws_partition - vpc_id = coalesce(each.value.runner_config.vpc_id, var.vpc_id) - subnet_ids = coalesce(each.value.runner_config.subnet_ids, var.subnet_ids) + vpc_id = each.value.compute_provider.aws.ec2.vpc_id + subnet_ids = each.value.compute_provider.aws.ec2.subnet_ids prefix = "${var.prefix}-${each.key}" - tags = merge(local.tags, { + tags = merge(local.effective_config.tags, each.value.tags, { "ghr:environment" = "${var.prefix}-${each.key}" }) - s3_runner_binaries = each.value.runner_config.enable_runner_binaries_syncer ? local.runner_binaries_by_os_and_arch_map["${each.value.runner_config.runner_os}_${each.value.runner_config.runner_architecture}"] : null + s3_runner_binaries = try(each.value.compute_provider.aws.ec2.binaries_syncer.enabled, false) ? local.runner_binaries_by_os_and_arch_map["${each.value.runner.os}_${each.value.runner.architecture}"] : null ssm_paths = { - root = "${local.ssm_root_path}/${each.key}" - tokens = "${var.ssm_paths.runners}/tokens" - config = "${var.ssm_paths.runners}/config" + root = each.value.ssm.paths.root + tokens = each.value.ssm.paths.tokens + config = each.value.ssm.paths.config } - runner_os = each.value.runner_config.runner_os - instance_types = each.value.runner_config.instance_types - instance_target_capacity_type = each.value.runner_config.instance_target_capacity_type - instance_allocation_strategy = each.value.runner_config.instance_allocation_strategy - instance_type_priorities = each.value.runner_config.instance_type_priorities - instance_max_spot_price = each.value.runner_config.instance_max_spot_price - block_device_mappings = each.value.runner_config.block_device_mappings + runner_os = each.value.runner.os + instance_types = each.value.compute_provider.aws.ec2.instance_types + instance_target_capacity_type = each.value.compute_provider.aws.ec2.instance_target_capacity_type + instance_allocation_strategy = each.value.compute_provider.aws.ec2.instance_allocation_strategy + instance_type_priorities = each.value.compute_provider.aws.ec2.instance_type_priorities + instance_max_spot_price = each.value.compute_provider.aws.ec2.instance_max_spot_price + block_device_mappings = each.value.compute_provider.aws.ec2.block_device_mappings + + runner_architecture = each.value.runner.architecture + ami = try(each.value.compute_provider.aws.ec2.ami == null ? null : { + filter = each.value.compute_provider.aws.ec2.ami.filter + owners = each.value.compute_provider.aws.ec2.ami.owners + id_ssm_parameter_arn = try(each.value.compute_provider.aws.ec2.ami.id_ssm_parameter.arn, null) + kms_key_arn = try(each.value.compute_provider.aws.ec2.ami.kms_key.arn, null) + }, null) + + sqs_build_queue = { "arn" : aws_sqs_queue.queued_builds[each.key].arn, "url" : aws_sqs_queue.queued_builds[each.key].url } + github_app_parameters = local.github_app_parameters + ebs_optimized = each.value.compute_provider.aws.ec2.ebs_optimized + enable_on_demand_failover_for_errors = each.value.compute_provider.aws.ec2.on_demand_failover_for_errors + scale_errors = each.value.compute_provider.aws.ec2.scale_errors + enable_organization_runners = each.value.orchestration_provider.webhook.github.organization_runners + enable_ephemeral_runners = each.value.orchestration_provider.webhook.runner.ephemeral + enable_jit_config = each.value.orchestration_provider.webhook.runner.jit_config_enabled + enable_job_queued_check = each.value.orchestration_provider.webhook.lambda.scale.up.job_queued_check_enabled + disable_runner_autoupdate = each.value.runner.auto_update_disabled + enable_managed_runner_security_group = each.value.compute_provider.aws.ec2.managed_security_group_enabled + enable_runner_detailed_monitoring = each.value.compute_provider.aws.ec2.detailed_monitoring_enabled + scale_down_schedule_expression = each.value.orchestration_provider.webhook.lambda.scale.down.schedule_expression + minimum_running_time_in_minutes = each.value.orchestration_provider.webhook.lambda.scale.down.minimum_running_time_in_minutes + runner_boot_time_in_minutes = each.value.orchestration_provider.webhook.runner.boot_time_in_minutes + runner_disable_default_labels = each.value.runner.disable_default_labels + runner_labels = each.value.runner.disable_default_labels ? sort(distinct(each.value.runner.extra_labels)) : sort(distinct(concat(["self-hosted", each.value.runner.os, each.value.runner.architecture], each.value.runner.extra_labels))) + runner_as_root = each.value.runner.run_as_root + runner_run_as = each.value.runner.run_as + runners_maximum_count = each.value.orchestration_provider.webhook.runner.maximum_count + idle_config = each.value.orchestration_provider.webhook.lambda.scale.down.idle_config + enable_ssm_on_runners = each.value.compute_provider.aws.ec2.ssm_enabled + egress_rules = each.value.compute_provider.aws.ec2.egress_rules + runner_additional_security_group_ids = each.value.compute_provider.aws.ec2.additional_security_group_ids + metadata_options = each.value.compute_provider.aws.ec2.metadata_options + credit_specification = each.value.compute_provider.aws.ec2.credit_specification + cpu_options = each.value.compute_provider.aws.ec2.cpu_options + placement = each.value.compute_provider.aws.ec2.placement + license_specifications = each.value.compute_provider.aws.ec2.license_specifications + use_dedicated_host = each.value.compute_provider.aws.ec2.use_dedicated_host + + enable_runner_binaries_syncer = each.value.compute_provider.aws.ec2.binaries_syncer.enabled + lambda_s3_bucket = try(local.effective_config.lambda.artifact.s3.bucket, null) + runners_lambda_s3_key = try(local.effective_config.orchestration_provider.webhook.lambda.artifact.s3.key, null) + runners_lambda_s3_object_version = try(local.effective_config.orchestration_provider.webhook.lambda.artifact.s3.object_version, null) + lambda_runtime = each.value.lambda.runtime + lambda_architecture = each.value.lambda.architecture + lambda_zip = local.effective_config.orchestration_provider.webhook.lambda.artifact.zip + lambda_scale_up_memory_size = each.value.orchestration_provider.webhook.lambda.scale.up.memory_size + lambda_event_source_mapping_batch_size = each.value.orchestration_provider.webhook.lambda.scale.up.event_source_mapping.batch_size + lambda_event_source_mapping_maximum_batching_window_in_seconds = each.value.orchestration_provider.webhook.lambda.scale.up.event_source_mapping.maximum_batching_window_in_seconds + lambda_timeout_scale_up = each.value.orchestration_provider.webhook.lambda.scale.up.timeout + lambda_scale_down_memory_size = each.value.orchestration_provider.webhook.lambda.scale.down.memory_size + lambda_timeout_scale_down = each.value.orchestration_provider.webhook.lambda.scale.down.timeout + lambda_subnet_ids = each.value.lambda.subnet_ids + lambda_security_group_ids = each.value.lambda.security_group_ids + lambda_tags = each.value.lambda.tags + tracing_config = each.value.observability.tracing + logging_retention_in_days = each.value.observability.logs.retention_in_days + logging_kms_key_id = each.value.observability.logs.kms_key_id + log_class = each.value.observability.logs.class + enable_cloudwatch_agent = each.value.compute_provider.aws.ec2.cloudwatch_agent.enabled + cloudwatch_config = each.value.compute_provider.aws.ec2.cloudwatch_agent.config + runner_log_files = each.value.compute_provider.aws.ec2.log_files + runner_group_name = each.value.runner.group_name + runner_name_prefix = each.value.runner.name_prefix + parameter_store_tags = each.value.ssm.parameters.tags + + scale_up_reserved_concurrent_executions = each.value.orchestration_provider.webhook.lambda.scale.up.reserved_concurrent_executions + + instance_profile_path = each.value.compute_provider.aws.ec2.instance_profile_path + role_path = each.value.runner.iam.path + role_permissions_boundary = each.value.runner.iam.permissions_boundary + + enable_userdata = each.value.compute_provider.aws.ec2.user_data.enabled + userdata_template = each.value.compute_provider.aws.ec2.user_data.template + userdata_content = each.value.compute_provider.aws.ec2.user_data.content + userdata_pre_install = each.value.compute_provider.aws.ec2.user_data.pre_install + userdata_post_install = each.value.compute_provider.aws.ec2.user_data.post_install + enable_user_data_debug_logging = each.value.compute_provider.aws.ec2.user_data.debug_logging_enabled + runner_hook_job_started = each.value.runner.hooks.job_started + runner_hook_job_completed = each.value.runner.hooks.job_completed + key_name = each.value.compute_provider.aws.ec2.key_name + runner_ec2_tags = each.value.compute_provider.aws.ec2.tags + + create_service_linked_role_spot = each.value.compute_provider.aws.ec2.create_service_linked_role_spot + + runner_iam_role_managed_policy_arns = values(each.value.runner.iam.managed_policy_arns) + iam_overrides = { + override_instance_profile = each.value.compute_provider.aws.ec2.instance_profile != null + instance_profile_name = try(each.value.compute_provider.aws.ec2.instance_profile.name, null) + override_runner_role = each.value.runner.iam.role != null + runner_role_arn = try(each.value.runner.iam.role.arn, null) + } - runner_architecture = each.value.runner_config.runner_architecture - ami = each.value.runner_config.ami + ghes_url = local.effective_config.github.enterprise_server.url + ghes_ssl_verify = local.effective_config.github.enterprise_server.ssl_verify + user_agent = local.effective_config.github.user_agent + + kms_key_arn = local.effective_config.ssm.kms_key_id + + log_level = each.value.observability.logs.level + + pool_config = each.value.orchestration_provider.webhook.lambda.pool.config + pool_lambda_memory_size = each.value.orchestration_provider.webhook.lambda.pool.memory_size + pool_lambda_timeout = each.value.orchestration_provider.webhook.lambda.pool.timeout + pool_runner_owner = each.value.orchestration_provider.webhook.lambda.pool.runner_owner + pool_lambda_reserved_concurrent_executions = each.value.orchestration_provider.webhook.lambda.pool.reserved_concurrent_executions + pool_include_busy_runners = each.value.orchestration_provider.webhook.lambda.pool.include_busy_runners + associate_public_ipv4_address = each.value.compute_provider.aws.ec2.associate_public_ipv4_address + + ssm_housekeeper = { + schedule_expression = each.value.ssm.housekeeper.schedule_expression + state = each.value.ssm.housekeeper.state + artifact = { + zip = each.value.ssm.housekeeper.lambda.artifact.zip + s3_bucket = try(local.effective_config.lambda.artifact.s3.bucket, null) + s3_key = try(each.value.ssm.housekeeper.lambda.artifact.s3.key, null) + s3_object_version = try(each.value.ssm.housekeeper.lambda.artifact.s3.object_version, null) + } + lambda_memory_size = each.value.ssm.housekeeper.lambda.memory_size + lambda_timeout = each.value.ssm.housekeeper.lambda.timeout + config = each.value.ssm.housekeeper.config + } - sqs_build_queue = { "arn" : each.value.arn, "url" : each.value.url } - github_app_parameters = local.github_app_parameters - ebs_optimized = each.value.runner_config.ebs_optimized - enable_on_demand_failover_for_errors = each.value.runner_config.enable_on_demand_failover_for_errors - scale_errors = each.value.runner_config.scale_errors - enable_organization_runners = each.value.runner_config.enable_organization_runners - enable_ephemeral_runners = each.value.runner_config.enable_ephemeral_runners - enable_jit_config = each.value.runner_config.enable_jit_config - enable_job_queued_check = each.value.runner_config.enable_job_queued_check - disable_runner_autoupdate = each.value.runner_config.disable_runner_autoupdate - enable_managed_runner_security_group = var.enable_managed_runner_security_group - enable_runner_detailed_monitoring = each.value.runner_config.enable_runner_detailed_monitoring - scale_down_schedule_expression = each.value.runner_config.scale_down_schedule_expression - minimum_running_time_in_minutes = each.value.runner_config.minimum_running_time_in_minutes - runner_boot_time_in_minutes = each.value.runner_config.runner_boot_time_in_minutes - runner_disable_default_labels = each.value.runner_config.runner_disable_default_labels - runner_labels = each.value.runner_config.runner_disable_default_labels ? sort(distinct(each.value.runner_config.runner_extra_labels)) : sort(distinct(concat(["self-hosted", each.value.runner_config.runner_os, each.value.runner_config.runner_architecture], each.value.runner_config.runner_extra_labels))) - runner_as_root = each.value.runner_config.runner_as_root - runner_run_as = each.value.runner_config.runner_run_as - runners_maximum_count = each.value.runner_config.runners_maximum_count - idle_config = each.value.runner_config.idle_config - enable_ssm_on_runners = each.value.runner_config.enable_ssm_on_runners - egress_rules = var.runner_egress_rules - runner_additional_security_group_ids = try(coalescelist(each.value.runner_config.runner_additional_security_group_ids, var.runner_additional_security_group_ids), []) - metadata_options = each.value.runner_config.runner_metadata_options - credit_specification = each.value.runner_config.credit_specification - cpu_options = each.value.runner_config.cpu_options - placement = each.value.runner_config.placement - license_specifications = each.value.runner_config.license_specifications - use_dedicated_host = each.value.runner_config.use_dedicated_host - - enable_runner_binaries_syncer = each.value.runner_config.enable_runner_binaries_syncer - lambda_s3_bucket = var.lambda_s3_bucket - runners_lambda_s3_key = var.runners_lambda_s3_key - runners_lambda_s3_object_version = var.runners_lambda_s3_object_version - lambda_runtime = var.lambda_runtime - lambda_architecture = var.lambda_architecture - lambda_zip = var.runners_lambda_zip - lambda_scale_up_memory_size = var.scale_up_lambda_memory_size - lambda_event_source_mapping_batch_size = coalesce(each.value.runner_config.lambda_event_source_mapping_batch_size, var.lambda_event_source_mapping_batch_size) - lambda_event_source_mapping_maximum_batching_window_in_seconds = coalesce(each.value.runner_config.lambda_event_source_mapping_maximum_batching_window_in_seconds, var.lambda_event_source_mapping_maximum_batching_window_in_seconds) - lambda_timeout_scale_up = var.runners_scale_up_lambda_timeout - lambda_scale_down_memory_size = var.scale_down_lambda_memory_size - lambda_timeout_scale_down = var.runners_scale_down_lambda_timeout - lambda_subnet_ids = var.lambda_subnet_ids - lambda_security_group_ids = var.lambda_security_group_ids - lambda_tags = var.lambda_tags - tracing_config = var.tracing_config - logging_retention_in_days = var.logging_retention_in_days - logging_kms_key_id = var.logging_kms_key_id - log_class = var.log_class - enable_cloudwatch_agent = each.value.runner_config.enable_cloudwatch_agent - cloudwatch_config = try(coalesce(each.value.runner_config.cloudwatch_config, var.cloudwatch_config), null) - runner_log_files = each.value.runner_config.runner_log_files - runner_group_name = each.value.runner_config.runner_group_name - runner_name_prefix = each.value.runner_config.runner_name_prefix - parameter_store_tags = var.parameter_store_tags - - scale_up_reserved_concurrent_executions = each.value.runner_config.scale_up_reserved_concurrent_executions - - instance_profile_path = var.instance_profile_path - role_path = var.role_path - role_permissions_boundary = var.role_permissions_boundary - - enable_userdata = each.value.runner_config.enable_userdata - userdata_template = each.value.runner_config.userdata_template - userdata_content = each.value.runner_config.userdata_content - userdata_pre_install = each.value.runner_config.userdata_pre_install - userdata_post_install = each.value.runner_config.userdata_post_install - runner_hook_job_started = each.value.runner_config.runner_hook_job_started - runner_hook_job_completed = each.value.runner_config.runner_hook_job_completed - key_name = var.key_name - runner_ec2_tags = each.value.runner_config.runner_ec2_tags - - create_service_linked_role_spot = each.value.runner_config.create_service_linked_role_spot - - runner_iam_role_managed_policy_arns = each.value.runner_config.runner_iam_role_managed_policy_arns - iam_overrides = each.value.runner_config.iam_overrides - - ghes_url = var.ghes_url - ghes_ssl_verify = var.ghes_ssl_verify - user_agent = var.user_agent - - kms_key_arn = var.kms_key_arn - - log_level = var.log_level - - pool_config = each.value.runner_config.pool_config - pool_lambda_timeout = var.pool_lambda_timeout - pool_runner_owner = each.value.runner_config.pool_runner_owner - pool_lambda_reserved_concurrent_executions = var.pool_lambda_reserved_concurrent_executions - associate_public_ipv4_address = var.associate_public_ipv4_address - - ssm_housekeeper = var.runners_ssm_housekeeper - - job_retry = each.value.runner_config.job_retry - - metrics = var.metrics + job_retry = { + enable = each.value.orchestration_provider.webhook.job_retry.enabled + delay_in_seconds = each.value.orchestration_provider.webhook.job_retry.delay_in_seconds + delay_backoff = each.value.orchestration_provider.webhook.job_retry.delay_backoff + lambda_memory_size = each.value.orchestration_provider.webhook.job_retry.lambda.memory_size + lambda_reserved_concurrent_executions = each.value.orchestration_provider.webhook.job_retry.lambda.reserved_concurrent_executions + lambda_timeout = each.value.orchestration_provider.webhook.job_retry.lambda.timeout + max_attempts = each.value.orchestration_provider.webhook.job_retry.max_attempts + } + + metrics = { + enable = each.value.observability.metrics.enabled + namespace = each.value.observability.metrics.namespace + metric = { + enable_github_app_rate_limit = each.value.observability.metrics.metric.github_app_rate_limit.enabled + enable_job_retry = each.value.observability.metrics.metric.job_retry.enabled + enable_spot_termination_warning = each.value.observability.metrics.metric.spot_termination_warning.enabled + } + } } diff --git a/modules/multi-runner/ssm.tf b/modules/multi-runner/ssm.tf index 3e4b740fdd..4c27495b8d 100644 --- a/modules/multi-runner/ssm.tf +++ b/modules/multi-runner/ssm.tf @@ -1,8 +1,11 @@ module "ssm" { source = "../ssm" - kms_key_arn = var.kms_key_arn - path_prefix = "${local.ssm_root_path}/${var.ssm_paths.app}" - github_app = var.github_app - additional_github_apps = var.additional_github_apps - tags = local.tags + kms_key_arn = local.effective_config.ssm.kms_key_id + path_prefix = "${local.ssm_root_path}/${local.effective_config.ssm.paths.app}" + github_app = local.effective_config.github.app + additional_github_apps = local.effective_config.github.additional_apps + tags = merge( + local.tags, + local.effective_config.ssm.tags, + ) } diff --git a/modules/multi-runner/termination-watcher.tf b/modules/multi-runner/termination-watcher.tf index 750db361bf..a710ae9620 100644 --- a/modules/multi-runner/termination-watcher.tf +++ b/modules/multi-runner/termination-watcher.tf @@ -1,36 +1,51 @@ locals { lambda_instance_termination_watcher = { - prefix = var.prefix - tags = local.tags - aws_partition = var.aws_partition - architecture = var.lambda_architecture - principals = var.lambda_principals - runtime = var.lambda_runtime - security_group_ids = var.lambda_security_group_ids - subnet_ids = var.lambda_subnet_ids - log_level = var.log_level - log_class = var.log_class - logging_kms_key_id = var.logging_kms_key_id - logging_retention_in_days = var.logging_retention_in_days - role_path = var.role_path - role_permissions_boundary = var.role_permissions_boundary - s3_bucket = var.lambda_s3_bucket - tracing_config = var.tracing_config - lambda_tags = var.lambda_tags - metrics = var.metrics - enable_runner_deregistration = var.instance_termination_watcher.enable_runner_deregistration - github_app_parameters = var.instance_termination_watcher.enable_runner_deregistration ? { + prefix = var.prefix + tags = local.tags + aws_partition = var.aws_partition + architecture = local.effective_config.lambda.architecture + principals = local.effective_config.lambda.principals + runtime = local.effective_config.lambda.runtime + security_group_ids = local.effective_config.lambda.security_group_ids + subnet_ids = local.effective_config.lambda.subnet_ids + log_level = local.effective_config.observability.logs.level + log_class = local.effective_config.observability.logs.class + logging_kms_key_id = local.effective_config.observability.logs.kms_key_id + logging_retention_in_days = local.effective_config.observability.logs.retention_in_days + role_path = local.effective_config.roles.path + role_permissions_boundary = local.effective_config.roles.permissions_boundary + s3_bucket = try(local.effective_config.lambda.artifact.s3.bucket, null) + s3_key = try(local.effective_config.compute_provider.aws.ec2.instance_termination_watcher.artifact.s3.key, null) + s3_object_version = try(local.effective_config.compute_provider.aws.ec2.instance_termination_watcher.artifact.s3.object_version, null) + zip = local.effective_config.compute_provider.aws.ec2.instance_termination_watcher.artifact.zip + tracing_config = local.effective_config.observability.tracing + lambda_tags = local.effective_config.lambda.tags + metrics = { + enable = local.effective_config.observability.metrics.enabled + namespace = local.effective_config.observability.metrics.namespace + metric = { + enable_github_app_rate_limit = local.effective_config.observability.metrics.metric.github_app_rate_limit.enabled + enable_job_retry = local.effective_config.observability.metrics.metric.job_retry.enabled + enable_spot_termination_warning = local.effective_config.observability.metrics.metric.spot_termination_warning.enabled + } + } + features = { + enable_spot_termination_handler = local.effective_config.compute_provider.aws.ec2.instance_termination_watcher.features.spot_termination_handler.enabled + enable_spot_termination_notification_watcher = local.effective_config.compute_provider.aws.ec2.instance_termination_watcher.features.spot_termination_notification_watcher.enabled + } + enable_runner_deregistration = local.effective_config.compute_provider.aws.ec2.instance_termination_watcher.features.runner_deregistration.enabled + github_app_parameters = local.effective_config.compute_provider.aws.ec2.instance_termination_watcher.features.runner_deregistration.enabled ? { id = local.github_app_parameters.id[0] key_base64 = local.github_app_parameters.key_base64[0] } : null - ghes_url = var.ghes_url - environment_variables = var.instance_termination_watcher.environment_variables + ghes_url = local.effective_config.github.enterprise_server.url + environment_variables = local.effective_config.compute_provider.aws.ec2.instance_termination_watcher.environment_variables } } module "instance_termination_watcher" { source = "../termination-watcher" - count = var.instance_termination_watcher.enable ? 1 : 0 + count = try(local.effective_config.compute_provider.aws.ec2.instance_termination_watcher.enabled, false) ? 1 : 0 - config = merge(local.lambda_instance_termination_watcher, var.instance_termination_watcher) + config = local.lambda_instance_termination_watcher } diff --git a/modules/multi-runner/tests/config-effective.tftest.hcl b/modules/multi-runner/tests/config-effective.tftest.hcl index b13fd6d337..6ddac1cfd3 100644 --- a/modules/multi-runner/tests/config-effective.tftest.hcl +++ b/modules/multi-runner/tests/config-effective.tftest.hcl @@ -130,26 +130,45 @@ run "v2_effective_config_contains_derived_values" { } } + global_config_github = { + app = { + key_base64 = "experimental-app-key" + id = "experimental-app-id" + webhook_secret = "experimental-webhook-secret" + } + } + global_config_lambda = { artifact = { s3 = { bucket = "global-lambda-artifacts" } } + subnet_ids = ["subnet-lambda"] + security_group_ids = ["sg-lambda"] } global_config_orchestration_provider = { webhook = { lambda = { artifact = { - zip = "global-webhook.zip" + s3 = { + key = "global-runners.zip" + } + } + webhook = { + artifact = { + s3 = { + key = "global-webhook.zip" + } + } } } queue = { encryption = { kms_data_key_reuse_period_seconds = 300 kms_master_key_id = "kms-global-queue" - sqs_managed_sse_enabled = false + sqs_managed_sse_enabled = null } } } @@ -157,11 +176,22 @@ run "v2_effective_config_contains_derived_values" { global_config_ssm = { kms_key_id = "kms-global-ssm" + housekeeper = { + lambda = { + artifact = { + s3 = { + key = "global-housekeeper.zip" + } + } + } + } } global_config_compute_provider = { aws = { ec2 = { + vpc_id = "vpc-global" + subnet_ids = ["subnet-global"] runner_binaries = { enabled = true syncer = { @@ -212,7 +242,7 @@ run "v2_effective_config_contains_derived_values" { "x64", ]) && local.effective_config.multi_runner_config["lane"].lambda.artifact.s3.bucket == "global-lambda-artifacts" - && local.effective_config.multi_runner_config["lane"].orchestration_provider.webhook.lambda.artifact.zip == "global-webhook.zip" + && local.effective_config.multi_runner_config["lane"].orchestration_provider.webhook.lambda.artifact.s3.key == "global-runners.zip" && local.effective_config.multi_runner_config["lane"].orchestration_provider.webhook.queue.kms_key_id == "kms-global-queue" && local.effective_config.multi_runner_config["lane"].ssm.kms_key_id == "kms-global-ssm" && toset(keys(local.resolved_runner_binary_targets_by_key)) == toset(["linux_x64"]) diff --git a/modules/multi-runner/tests/config-resolution.tftest.hcl b/modules/multi-runner/tests/config-resolution.tftest.hcl index ecc2670315..efb117ed7f 100644 --- a/modules/multi-runner/tests/config-resolution.tftest.hcl +++ b/modules/multi-runner/tests/config-resolution.tftest.hcl @@ -83,6 +83,69 @@ variables { runners_lambda_s3_key = "runners.zip" webhook_lambda_s3_key = "webhook.zip" syncer_lambda_s3_key = "runner-binaries-syncer.zip" + + global_config_github = { + app = { + key_base64 = "experimental-app-key" + id = "experimental-app-id" + webhook_secret = "experimental-webhook-secret" + } + } + + global_config_lambda = { + artifact = { + s3 = { + bucket = "test-lambda-artifacts" + } + } + } + + global_config_orchestration_provider = { + webhook = { + lambda = { + artifact = { + s3 = { + key = "runners.zip" + } + } + webhook = { + artifact = { + s3 = { + key = "webhook.zip" + } + } + } + } + } + } + + global_config_ssm = { + housekeeper = { + lambda = { + artifact = { + s3 = { + key = "runners.zip" + } + } + } + } + } + + global_config_compute_provider = { + aws = { + ec2 = { + runner_binaries = { + syncer = { + artifact = { + s3 = { + key = "runner-binaries-syncer.zip" + } + } + } + } + } + } + } } run "v1_stable_inputs_translate_into_effective_base" { @@ -158,9 +221,6 @@ run "v2_inputs_resolve_lane_over_global" { ec2 = { vpc_id = "vpc-global" subnet_ids = ["subnet-global"] - runner_binaries = { - enabled = false - } instance_termination_watcher = { features = { runner_deregistration = { @@ -174,6 +234,16 @@ run "v2_inputs_resolve_lane_over_global" { } } } + runner_binaries = { + enabled = false + syncer = { + artifact = { + s3 = { + key = "runner-binaries-syncer.zip" + } + } + } + } } } } @@ -197,6 +267,20 @@ run "v2_inputs_resolve_lane_over_global" { eventbridge = { enabled = false } + lambda = { + artifact = { + s3 = { + key = "global-runners.zip" + } + } + webhook = { + artifact = { + s3 = { + key = "global-webhook.zip" + } + } + } + } } } @@ -204,7 +288,9 @@ run "v2_inputs_resolve_lane_over_global" { housekeeper = { lambda = { artifact = { - zip = "global-housekeeper.zip" + s3 = { + key = "global-housekeeper.zip" + } } } } diff --git a/modules/multi-runner/tests/config-translation.tftest.hcl b/modules/multi-runner/tests/config-translation.tftest.hcl index 8ee5e326ba..132814b156 100644 --- a/modules/multi-runner/tests/config-translation.tftest.hcl +++ b/modules/multi-runner/tests/config-translation.tftest.hcl @@ -85,6 +85,71 @@ variables { runners_lambda_s3_key = "runners.zip" webhook_lambda_s3_key = "webhook.zip" syncer_lambda_s3_key = "runner-binaries-syncer.zip" + + global_config_github = { + app = { + key_base64 = "experimental-app-key" + id = "experimental-app-id" + webhook_secret = "experimental-webhook-secret" + } + } + + global_config_lambda = { + artifact = { + s3 = { + bucket = "test-lambda-artifacts" + } + } + } + + global_config_orchestration_provider = { + webhook = { + lambda = { + artifact = { + s3 = { + key = "runners.zip" + } + } + webhook = { + artifact = { + s3 = { + key = "webhook.zip" + } + } + } + } + } + } + + global_config_ssm = { + housekeeper = { + lambda = { + artifact = { + s3 = { + key = "runners.zip" + } + } + } + } + } + + global_config_compute_provider = { + aws = { + ec2 = { + vpc_id = "vpc-experimental-default" + subnet_ids = ["subnet-experimental-default"] + runner_binaries = { + syncer = { + artifact = { + s3 = { + key = "runner-binaries-syncer.zip" + } + } + } + } + } + } + } } run "empty_v2_map_translates_stable_inputs" { @@ -228,6 +293,20 @@ run "empty_v2_map_translates_stable_inputs" { github = { repository_white_list = ["ignored/repository"] } + lambda = { + artifact = { + s3 = { + key = "runners.zip" + } + } + webhook = { + artifact = { + s3 = { + key = "webhook.zip" + } + } + } + } } } @@ -236,6 +315,15 @@ run "empty_v2_map_translates_stable_inputs" { ec2 = { vpc_id = "vpc-experimental-ignored" subnet_ids = ["subnet-experimental-ignored"] + runner_binaries = { + syncer = { + artifact = { + s3 = { + key = "runner-binaries-syncer.zip" + } + } + } + } } } } @@ -363,8 +451,16 @@ run "non_empty_v2_map_is_authoritative" { global_config_compute_provider = { aws = { ec2 = { + vpc_id = "vpc-experimental-default" + subnet_ids = ["subnet-experimental-default"] runner_binaries = { - enabled = false + syncer = { + artifact = { + s3 = { + key = "runner-binaries-syncer.zip" + } + } + } } } } @@ -430,9 +526,14 @@ run "v2_entry_without_matcher_config_is_authoritative" { os = "linux" architecture = "x64" } + orchestration_provider = { + webhook = {} + } compute_provider = { aws = { ec2 = { + vpc_id = "vpc-no-matcher" + subnet_ids = ["subnet-no-matcher"] instance_types = ["m5.large"] } } @@ -481,6 +582,20 @@ run "lane_values_override_experimental_globals" { runner = { maximum_count = 4 } + lambda = { + artifact = { + s3 = { + key = "runners.zip" + } + } + webhook = { + artifact = { + s3 = { + key = "webhook.zip" + } + } + } + } } } @@ -495,7 +610,9 @@ run "lane_values_override_experimental_globals" { housekeeper = { lambda = { artifact = { - zip = "global-housekeeper.zip" + s3 = { + key = "global-housekeeper.zip" + } } } } @@ -507,7 +624,13 @@ run "lane_values_override_experimental_globals" { vpc_id = "vpc-experimental" subnet_ids = ["subnet-global"] runner_binaries = { - enabled = false + syncer = { + artifact = { + s3 = { + key = "runner-binaries-syncer.zip" + } + } + } } tags = { precedence = "global" @@ -646,7 +769,13 @@ run "global_external_runner_role_suppresses_inherited_iam_overrides" { vpc_id = "vpc-global" subnet_ids = ["subnet-global"] runner_binaries = { - enabled = false + syncer = { + artifact = { + s3 = { + key = "runner-binaries-syncer.zip" + } + } + } } } } diff --git a/modules/multi-runner/webhook.tf b/modules/multi-runner/webhook.tf index 6ee9b4b2ec..f8d16406fe 100644 --- a/modules/multi-runner/webhook.tf +++ b/modules/multi-runner/webhook.tf @@ -1,44 +1,70 @@ +locals { + webhook_runner_config = { + for k, v in local.effective_config.multi_runner_config : k => v + if try(v.orchestration_provider.webhook.matcherConfig, null) != null + } + + runner_matcher_config = { + for k, v in local.webhook_runner_config : k => { + id = aws_sqs_queue.queued_builds[k].id + arn = aws_sqs_queue.queued_builds[k].arn + computeProvider = "ec2" + matcherConfig = { + labelMatchers = v.orchestration_provider.webhook.matcherConfig.labelMatchers + exactMatch = v.orchestration_provider.webhook.matcherConfig.exactMatch + bidirectionalLabelMatch = v.orchestration_provider.webhook.matcherConfig.bidirectionalLabelMatch + priority = v.orchestration_provider.webhook.matcherConfig.priority + enableDynamicLabels = v.orchestration_provider.webhook.matcherConfig.dynamic_labels_enabled + awsDynamicLabelsPolicy = v.orchestration_provider.webhook.matcherConfig.awsDynamicLabelsPolicy + } + } + } +} + module "webhook" { - source = "../webhook" - prefix = var.prefix - tags = local.tags - kms_key_arn = var.kms_key_arn - eventbridge = var.eventbridge - runner_matcher_config = local.runner_config - matcher_config_parameter_store_tier = var.matcher_config_parameter_store_tier + source = "../webhook" + prefix = var.prefix + tags = local.tags + kms_key_arn = local.effective_config.ssm.kms_key_id + eventbridge = { + enable = local.effective_config.orchestration_provider.webhook.eventbridge.enabled + accept_events = local.effective_config.orchestration_provider.webhook.eventbridge.accept_events + } + runner_matcher_config = local.runner_matcher_config + matcher_config_parameter_store_tier = local.effective_config.orchestration_provider.webhook.matcher_config_parameter_store_tier ssm_paths = { root = local.ssm_root_path - webhook = var.ssm_paths.webhook + webhook = local.effective_config.ssm.paths.webhook } github_app_parameters = { webhook_secret = local.github_app_parameters.webhook_secret } - lambda_s3_bucket = var.lambda_s3_bucket - webhook_lambda_s3_key = var.webhook_lambda_s3_key - webhook_lambda_s3_object_version = var.webhook_lambda_s3_object_version - webhook_lambda_apigateway_access_log_settings = var.webhook_lambda_apigateway_access_log_settings - lambda_runtime = var.lambda_runtime - lambda_architecture = var.lambda_architecture - lambda_zip = var.webhook_lambda_zip - lambda_timeout = var.webhook_lambda_timeout - lambda_memory_size = var.webhook_lambda_memory_size - lambda_tags = var.lambda_tags - tracing_config = var.tracing_config - logging_retention_in_days = var.logging_retention_in_days - logging_kms_key_id = var.logging_kms_key_id - log_class = var.log_class - - role_path = var.role_path - role_permissions_boundary = var.role_permissions_boundary - repository_white_list = var.repository_white_list - queue_selection_strategy = var.queue_selection_strategy - - lambda_subnet_ids = var.lambda_subnet_ids - lambda_security_group_ids = var.lambda_security_group_ids + lambda_s3_bucket = try(local.effective_config.lambda.artifact.s3.bucket, null) + webhook_lambda_s3_key = try(local.effective_config.orchestration_provider.webhook.lambda.webhook.artifact.s3.key, null) + webhook_lambda_s3_object_version = try(local.effective_config.orchestration_provider.webhook.lambda.webhook.artifact.s3.object_version, null) + webhook_lambda_apigateway_access_log_settings = local.effective_config.orchestration_provider.webhook.lambda.webhook.api_gateway_access_log_settings + lambda_runtime = local.effective_config.lambda.runtime + lambda_architecture = local.effective_config.lambda.architecture + lambda_zip = local.effective_config.orchestration_provider.webhook.lambda.webhook.artifact.zip + lambda_timeout = local.effective_config.orchestration_provider.webhook.lambda.webhook.timeout + lambda_memory_size = local.effective_config.orchestration_provider.webhook.lambda.webhook.memory_size + lambda_tags = local.effective_config.orchestration_provider.webhook.lambda.webhook.tags + tracing_config = local.effective_config.observability.tracing + logging_retention_in_days = local.effective_config.observability.logs.retention_in_days + logging_kms_key_id = local.effective_config.observability.logs.kms_key_id + log_class = local.effective_config.observability.logs.class + + role_path = local.effective_config.roles.path + role_permissions_boundary = local.effective_config.roles.permissions_boundary + repository_white_list = local.effective_config.orchestration_provider.webhook.github.repository_white_list + queue_selection_strategy = local.effective_config.orchestration_provider.webhook.queue_selection_strategy + + lambda_subnet_ids = local.effective_config.lambda.subnet_ids + lambda_security_group_ids = local.effective_config.lambda.security_group_ids aws_partition = var.aws_partition - log_level = var.log_level + log_level = local.effective_config.observability.logs.level }