diff --git a/README.md b/README.md index c67c50b..b90a88c 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,7 @@ If you have many remote repositories that you need to manage via this pattern, y | [spacelift_stack_destructor.default](https://registry.terraform.io/providers/spacelift-io/spacelift/latest/docs/resources/stack_destructor) | resource | | [jsonschema_validator.runtime_overrides](https://registry.terraform.io/providers/bpedman/jsonschema/latest/docs/data-sources/validator) | data source | | [spacelift_spaces.all](https://registry.terraform.io/providers/spacelift-io/spacelift/latest/docs/data-sources/spaces) | data source | +| [spacelift_worker_pools.all](https://registry.terraform.io/providers/spacelift-io/spacelift/latest/docs/data-sources/worker_pools) | data source | ## Inputs @@ -381,7 +382,8 @@ If you have many remote repositories that you need to manage via this pattern, y | [terraform\_smart\_sanitization](#input\_terraform\_smart\_sanitization) | Indicates whether runs on this will use terraform's sensitive value system to sanitize
the outputs of Terraform state and plans in spacelift instead of sanitizing all fields. | `bool` | `false` | no | | [terraform\_version](#input\_terraform\_version) | OpenTofu/Terraform version to use. Defaults to the latest available version of the `terraform_workflow_tool`. | `string` | `null` | no | | [terraform\_workflow\_tool](#input\_terraform\_workflow\_tool) | Defines the tool that will be used to execute the workflow.
This can be one of OPEN\_TOFU, TERRAFORM\_FOSS or CUSTOM. | `string` | `"OPEN_TOFU"` | no | -| [worker\_pool\_id](#input\_worker\_pool\_id) | ID of the worker pool to use.
NOTE: worker\_pool\_id is required when using a self-hosted instance of Spacelift. | `string` | `null` | no | +| [worker\_pool\_id](#input\_worker\_pool\_id) | ID of the worker pool to use. Mutually exclusive with worker\_pool\_name.
NOTE: worker\_pool\_name or worker\_pool\_id is required when using a self-hosted instance of Spacelift. | `string` | `null` | no | +| [worker\_pool\_name](#input\_worker\_pool\_name) | Name of the worker pool to use. Mutually exclusive with worker\_pool\_id.
NOTE: worker\_pool\_name or worker\_pool\_id is required when using a self-hosted instance of Spacelift. | `string` | `null` | no | ## Outputs diff --git a/data.tf b/data.tf index 982c7f8..95c1ba0 100644 --- a/data.tf +++ b/data.tf @@ -1,6 +1,9 @@ # Look up all spaces in order to map space names to space IDs data "spacelift_spaces" "all" {} +# Look up all worker pools in order to map worker pool names to IDs +data "spacelift_worker_pools" "all" {} + # Validate the runtime overrides against the schema # Frustrating that we have to do this, but this successfully validates the typing # of the given runtime overrides since we need to use `any` for the variable type :( diff --git a/main.tf b/main.tf index 533b82c..9956d40 100644 --- a/main.tf +++ b/main.tf @@ -297,6 +297,13 @@ locals { space.name => space.space_id } + ## Handle worker pool names + # Allow usage of worker_pool_name along with worker_pool_id. + worker_pool_name_to_id = { + for pool in data.spacelift_worker_pools.all.worker_pools : + pool.name => pool.worker_pool_id + } + # Helper for property resolution with fallback to defaults stack_property_resolver = { for stack in local.stacks : stack => { @@ -357,6 +364,16 @@ locals { ) } + # Resolve worker_pool_id if worker_pool_name is provided + resolved_worker_pool_ids = { + for stack in local.stacks : stack => try(coalesce( + try(local.stack_configs[stack].worker_pool_id, null), # worker_pool_id always takes precedence since it's the most explicit + try(local.worker_pool_name_to_id[local.stack_configs[stack].worker_pool_name], null), # Then try to look up worker_pool_name from the stack.yaml to ID + var.worker_pool_id, # Then try to use the global variable worker_pool_id + try(local.worker_pool_name_to_id[var.worker_pool_name], null), # Then try to look up the global variable worker_pool_name to ID + ), null) # If no worker_pool_id or worker_pool_name is provided, default to null + } + ## Filter integration + drift detection stacks aws_integration_stacks = { @@ -435,7 +452,7 @@ resource "spacelift_stack" "default" { terraform_version = local.stack_property_resolver[each.key].terraform_version terraform_workflow_tool = var.terraform_workflow_tool terraform_workspace = local.configs[each.key].terraform_workspace - worker_pool_id = local.stack_property_resolver[each.key].worker_pool_id + worker_pool_id = local.resolved_worker_pool_ids[each.key] # Usage of `templatestring` requires OpenTofu 1.7 and Terraform 1.9 or later. description = coalesce( diff --git a/stack-config.schema.json b/stack-config.schema.json index f57e0fb..53b8f20 100644 --- a/stack-config.schema.json +++ b/stack-config.schema.json @@ -197,6 +197,10 @@ "type": "string", "description": "Worker pool ID" }, + "worker_pool_name": { + "type": "string", + "description": "Worker pool name, this will be translated to a worker_pool_id. Mutually exclusive with worker_pool_id" + }, "aws_integration_enabled": { "type": "boolean", "description": "Whether to enable AWS integration" diff --git a/tests/fixtures/multi-instance/root-module-a/stacks/test.yaml b/tests/fixtures/multi-instance/root-module-a/stacks/test.yaml index 82a2ffb..77ba164 100644 --- a/tests/fixtures/multi-instance/root-module-a/stacks/test.yaml +++ b/tests/fixtures/multi-instance/root-module-a/stacks/test.yaml @@ -1,5 +1,6 @@ kind: StackConfigV1 stack_settings: space_id: direct-space-id-stack-yaml # Tests direct space_id precedence over global variable space_id + worker_pool_name: mp-ue1-automation-spft-priv-workers # Tests worker_pool_name gets translated to worker_pool_id labels: - test_label diff --git a/tests/main.tftest.hcl b/tests/main.tftest.hcl index 0093e4a..c8fb1dc 100644 --- a/tests/main.tftest.hcl +++ b/tests/main.tftest.hcl @@ -1004,3 +1004,26 @@ run "test_destructor_states" { } } +# Test that worker_pool_name from stack settings resolves to correct ID +run "test_worker_pool_name_resolves_to_correct_id" { + command = plan + + assert { + condition = local.resolved_worker_pool_ids["root-module-a-test"] == "01K3VABYB4FBXNV24KN4A4EKC8" # For the `mp-ue1-automation-spft-priv-workers` in our `mp-infra` Spacelift account + error_message = "Worker pool name not resolving to correct ID: ${jsonencode(local.resolved_worker_pool_ids)}" + } +} + +# Test that worker_pool_name from stack settings takes precedence over worker_pool_name global variable +run "test_worker_pool_name_takes_precedence_over_worker_pool_name_global_variable" { + command = plan + + variables { + worker_pool_name = "some-other-worker-pool" + } + + assert { + condition = local.resolved_worker_pool_ids["root-module-a-test"] == "01K3VABYB4FBXNV24KN4A4EKC8" # For the `mp-ue1-automation-spft-priv-workers` in our `mp-infra` Spacelift account + error_message = "Worker pool name from stack settings not taking precedence over global variable worker_pool_name: ${jsonencode(local.resolved_worker_pool_ids)}" + } +} diff --git a/variables.tf b/variables.tf index ee67be0..0e5b428 100644 --- a/variables.tf +++ b/variables.tf @@ -350,8 +350,17 @@ variable "terraform_version" { variable "worker_pool_id" { type = string description = <<-EOT - ID of the worker pool to use. - NOTE: worker_pool_id is required when using a self-hosted instance of Spacelift. + ID of the worker pool to use. Mutually exclusive with worker_pool_name. + NOTE: worker_pool_name or worker_pool_id is required when using a self-hosted instance of Spacelift. + EOT + default = null +} + +variable "worker_pool_name" { + type = string + description = <<-EOT + Name of the worker pool to use. Mutually exclusive with worker_pool_id. + NOTE: worker_pool_name or worker_pool_id is required when using a self-hosted instance of Spacelift. EOT default = null }