From 09dd9f3b83924baf789b14420c864546ea524b7e Mon Sep 17 00:00:00 2001 From: Dmitrij Nikitenko Date: Thu, 25 Jun 2026 17:32:19 +0300 Subject: [PATCH 1/3] feat(docker-autoscaler): expose on_demand_allocation_strategy for mixed instances policy --- docker_autoscaler.tf | 1 + variables.tf | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/docker_autoscaler.tf b/docker_autoscaler.tf index 2e678fec4..512e74c6e 100644 --- a/docker_autoscaler.tf +++ b/docker_autoscaler.tf @@ -98,6 +98,7 @@ resource "aws_autoscaling_group" "autoscaler" { content { instances_distribution { + on_demand_allocation_strategy = var.runner_worker_docker_autoscaler_asg.on_demand_allocation_strategy on_demand_base_capacity = var.runner_worker_docker_autoscaler_asg.on_demand_base_capacity on_demand_percentage_above_base_capacity = var.runner_worker_docker_autoscaler_asg.on_demand_percentage_above_base_capacity spot_allocation_strategy = var.runner_worker_docker_autoscaler_asg.spot_allocation_strategy diff --git a/variables.tf b/variables.tf index b1c845706..f542620f7 100644 --- a/variables.tf +++ b/variables.tf @@ -813,6 +813,7 @@ variable "runner_worker_docker_autoscaler_asg" { health_check_type = Controls how health checking is done. Values are - EC2 and ELB. instance_refresh_min_healthy_percentage = The amount of capacity in the Auto Scaling group that must remain healthy during an instance refresh to allow the operation to continue, as a percentage of the desired capacity of the Auto Scaling group. instance_refresh_triggers = Set of additional property names that will trigger an Instance Refresh. A refresh will always be triggered by a change in any of launch_configuration, launch_template, or mixed_instances_policy. + on_demand_allocation_strategy = Strategy for allocating on-demand instances. Valid values: 'prioritized' (by override order) or 'lowest-price'. Must be set to 'lowest-price' when instance_requirements is used — AWS rejects any other value with attribute-based instance selection. Defaults to null (AWS uses 'prioritized' when types are used). on_demand_base_capacity = Absolute minimum amount of desired capacity that must be fulfilled by on-demand instances. on_demand_percentage_above_base_capacity = Percentage split between on-demand and Spot instances above the base on-demand capacity. spot_allocation_strategy = How to allocate capacity across the Spot pools. 'lowest-price' to optimize cost, 'capacity-optimized' to reduce interruptions. @@ -830,6 +831,7 @@ variable "runner_worker_docker_autoscaler_asg" { health_check_type = optional(string, "EC2") instance_refresh_min_healthy_percentage = optional(number, 90) instance_refresh_triggers = optional(list(string), []) + on_demand_allocation_strategy = optional(string, null) on_demand_base_capacity = optional(number, 0) on_demand_percentage_above_base_capacity = optional(number, 100) spot_allocation_strategy = optional(string, "lowest-price") @@ -857,6 +859,16 @@ variable "runner_worker_docker_autoscaler_asg" { condition = length(var.runner_worker_docker_autoscaler_asg.types) == 0 || length(var.runner_worker_docker_autoscaler_asg.instance_requirements) == 0 error_message = "AWS does not allow setting both 'types' and 'instance_requirements' at the same time. Set only one." } + + validation { + condition = var.runner_worker_docker_autoscaler_asg.on_demand_allocation_strategy == null || contains(["prioritized", "lowest-price"], var.runner_worker_docker_autoscaler_asg.on_demand_allocation_strategy) + error_message = "on_demand_allocation_strategy must be 'prioritized', 'lowest-price', or null." + } + + validation { + condition = length(var.runner_worker_docker_autoscaler_asg.instance_requirements) == 0 || var.runner_worker_docker_autoscaler_asg.on_demand_allocation_strategy == "lowest-price" + error_message = "on_demand_allocation_strategy must be set to 'lowest-price' when instance_requirements is used — AWS rejects any other value with attribute-based instance selection." + } } variable "runner_worker_docker_machine_role" { From 5808c3b9295e18d34d9a2ea67678ea146349510b Mon Sep 17 00:00:00 2001 From: Dmitrij Nikitenko Date: Thu, 25 Jun 2026 17:42:28 +0300 Subject: [PATCH 2/3] chore(docker-autoscaler): default on_demand_allocation_strategy to lowest-price --- variables.tf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/variables.tf b/variables.tf index f542620f7..8b388d666 100644 --- a/variables.tf +++ b/variables.tf @@ -813,7 +813,7 @@ variable "runner_worker_docker_autoscaler_asg" { health_check_type = Controls how health checking is done. Values are - EC2 and ELB. instance_refresh_min_healthy_percentage = The amount of capacity in the Auto Scaling group that must remain healthy during an instance refresh to allow the operation to continue, as a percentage of the desired capacity of the Auto Scaling group. instance_refresh_triggers = Set of additional property names that will trigger an Instance Refresh. A refresh will always be triggered by a change in any of launch_configuration, launch_template, or mixed_instances_policy. - on_demand_allocation_strategy = Strategy for allocating on-demand instances. Valid values: 'prioritized' (by override order) or 'lowest-price'. Must be set to 'lowest-price' when instance_requirements is used — AWS rejects any other value with attribute-based instance selection. Defaults to null (AWS uses 'prioritized' when types are used). + on_demand_allocation_strategy = Strategy for allocating on-demand instances. Valid values: 'prioritized' (by override order) or 'lowest-price'. Must be 'lowest-price' when instance_requirements is used — AWS rejects any other value with attribute-based instance selection. Defaults to 'lowest-price'. on_demand_base_capacity = Absolute minimum amount of desired capacity that must be fulfilled by on-demand instances. on_demand_percentage_above_base_capacity = Percentage split between on-demand and Spot instances above the base on-demand capacity. spot_allocation_strategy = How to allocate capacity across the Spot pools. 'lowest-price' to optimize cost, 'capacity-optimized' to reduce interruptions. @@ -831,7 +831,7 @@ variable "runner_worker_docker_autoscaler_asg" { health_check_type = optional(string, "EC2") instance_refresh_min_healthy_percentage = optional(number, 90) instance_refresh_triggers = optional(list(string), []) - on_demand_allocation_strategy = optional(string, null) + on_demand_allocation_strategy = optional(string, "lowest-price") on_demand_base_capacity = optional(number, 0) on_demand_percentage_above_base_capacity = optional(number, 100) spot_allocation_strategy = optional(string, "lowest-price") @@ -861,8 +861,8 @@ variable "runner_worker_docker_autoscaler_asg" { } validation { - condition = var.runner_worker_docker_autoscaler_asg.on_demand_allocation_strategy == null || contains(["prioritized", "lowest-price"], var.runner_worker_docker_autoscaler_asg.on_demand_allocation_strategy) - error_message = "on_demand_allocation_strategy must be 'prioritized', 'lowest-price', or null." + condition = contains(["prioritized", "lowest-price"], var.runner_worker_docker_autoscaler_asg.on_demand_allocation_strategy) + error_message = "on_demand_allocation_strategy must be 'prioritized' or 'lowest-price'." } validation { From 1322ff9407286eba4e66bc3cc68b4445888ef77d Mon Sep 17 00:00:00 2001 From: Dmitrij Nikitenko Date: Thu, 25 Jun 2026 18:00:10 +0300 Subject: [PATCH 3/3] chore(docker-autoscaler): remove unneeded validation --- variables.tf | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/variables.tf b/variables.tf index 8b388d666..0c8fcba74 100644 --- a/variables.tf +++ b/variables.tf @@ -816,7 +816,7 @@ variable "runner_worker_docker_autoscaler_asg" { on_demand_allocation_strategy = Strategy for allocating on-demand instances. Valid values: 'prioritized' (by override order) or 'lowest-price'. Must be 'lowest-price' when instance_requirements is used — AWS rejects any other value with attribute-based instance selection. Defaults to 'lowest-price'. on_demand_base_capacity = Absolute minimum amount of desired capacity that must be fulfilled by on-demand instances. on_demand_percentage_above_base_capacity = Percentage split between on-demand and Spot instances above the base on-demand capacity. - spot_allocation_strategy = How to allocate capacity across the Spot pools. 'lowest-price' to optimize cost, 'capacity-optimized' to reduce interruptions. + spot_allocation_strategy = How to allocate capacity across the Spot pools. 'lowest-price' to optimize cost, 'capacity-optimized' to reduce interruptions, 'price-capacity-optimized' to balance both price and capacity availability (recommended for most workloads). spot_instance_pools = Number of Spot pools per availability zone to allocate capacity. EC2 Auto Scaling selects the cheapest Spot pools and evenly allocates Spot capacity across the number of Spot pools that you specify. subnet_ids = The list of subnet IDs to use for the Runner Worker when the fleet mode is enabled. default_instance_type = Default instance type for the launch template @@ -860,11 +860,6 @@ variable "runner_worker_docker_autoscaler_asg" { error_message = "AWS does not allow setting both 'types' and 'instance_requirements' at the same time. Set only one." } - validation { - condition = contains(["prioritized", "lowest-price"], var.runner_worker_docker_autoscaler_asg.on_demand_allocation_strategy) - error_message = "on_demand_allocation_strategy must be 'prioritized' or 'lowest-price'." - } - validation { condition = length(var.runner_worker_docker_autoscaler_asg.instance_requirements) == 0 || var.runner_worker_docker_autoscaler_asg.on_demand_allocation_strategy == "lowest-price" error_message = "on_demand_allocation_strategy must be set to 'lowest-price' when instance_requirements is used — AWS rejects any other value with attribute-based instance selection."