diff --git a/README.md b/README.md index d2f808a..c8740f5 100644 --- a/README.md +++ b/README.md @@ -229,14 +229,14 @@ This is to support easy local and outside-spacelift operations. Keeping variable | Name | Version | | ------------------------------------------------------------------------ | ------- | -| [terraform](#requirement_terraform) | >= 1.6 | +| [terraform](#requirement_terraform) | >= 1.9 | | [spacelift](#requirement_spacelift) | >= 1.14 | ## Providers | Name | Version | | ------------------------------------------------------------------ | ------- | -| [spacelift](#provider_spacelift) | 1.19.0 | +| [spacelift](#provider_spacelift) | 1.19.1 | ## Modules @@ -255,60 +255,60 @@ This is to support easy local and outside-spacelift operations. Keeping variable ## Inputs -| Name | Description | Type | Default | Required | -| --------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------- | :------: | -| [additional_project_globs](#input_additional_project_globs) | Project globs is an optional list of paths to track stack changes of outside of the project root. Push policies are another alternative to track changes in additional paths. | `set(string)` | `[]` | no | -| [administrative](#input_administrative) | Flag to mark the stack as administrative | `bool` | `false` | no | -| [after_apply](#input_after_apply) | List of after-apply scripts | `list(string)` | `[]` | no | -| [after_destroy](#input_after_destroy) | List of after-destroy scripts | `list(string)` | `[]` | no | -| [after_init](#input_after_init) | List of after-init scripts | `list(string)` | `[]` | no | -| [after_perform](#input_after_perform) | List of after-perform scripts | `list(string)` | `[]` | no | -| [after_plan](#input_after_plan) | List of after-plan scripts | `list(string)` | `[]` | no | -| [all_root_modules_enabled](#input_all_root_modules_enabled) | When set to true, all subdirectories in root_modules_path will be treated as root modules. | `bool` | `false` | no | -| [autodeploy](#input_autodeploy) | Flag to enable/disable automatic deployment of the stack | `bool` | `true` | no | -| [autoretry](#input_autoretry) | Flag to enable/disable automatic retry of the stack | `bool` | `false` | no | -| [aws_integration_attachment_read](#input_aws_integration_attachment_read) | Indicates whether this attachment is used for read operations. | `bool` | `true` | no | -| [aws_integration_attachment_write](#input_aws_integration_attachment_write) | Indicates whether this attachment is used for write operations. | `bool` | `true` | no | -| [aws_integration_enabled](#input_aws_integration_enabled) | Indicates whether the AWS integration is enabled. | `bool` | `false` | no | -| [aws_integration_id](#input_aws_integration_id) | ID of the AWS integration to attach. | `string` | `null` | no | -| [before_apply](#input_before_apply) | List of before-apply scripts | `list(string)` | `[]` | no | -| [before_destroy](#input_before_destroy) | List of before-destroy scripts | `list(string)` | `[]` | no | -| [before_init](#input_before_init) | List of before-init scripts | `list(string)` | `[]` | no | -| [before_perform](#input_before_perform) | List of before-perform scripts | `list(string)` | `[]` | no | -| [before_plan](#input_before_plan) | List of before-plan scripts | `list(string)` | `[]` | no | -| [branch](#input_branch) | Specify which branch to use within the infrastructure repository. | `string` | `"main"` | no | -| [common_config_file](#input_common_config_file) | Name of the common configuration file for the stack across a root module. | `string` | `"common.yaml"` | no | -| [default_tf_workspace_enabled](#input_default_tf_workspace_enabled) | Enables the use of `default` Terraform workspace instead of managing multiple workspaces within a root module.

NOTE: We encourage the use of Terraform workspaces to manage multiple environments.
However, you will want to disable this behavior if you're utilizing different backends for each instance
of your root modules (we call this "Dynamic Backends"). | `bool` | `false` | no | -| [description](#input_description) | Description of the stack | `string` | `"Managed by spacelift-automation Terraform root module."` | no | -| [destructor_enabled](#input_destructor_enabled) | Flag to enable/disable the destructor for the Stack. | `bool` | `false` | no | -| [drift_detection_enabled](#input_drift_detection_enabled) | Flag to enable/disable Drift Detection configuration for a Stack. | `bool` | `false` | no | -| [drift_detection_ignore_state](#input_drift_detection_ignore_state) | Controls whether drift detection should be performed on a stack
in any final state instead of just 'Finished'. | `bool` | `false` | no | -| [drift_detection_reconcile](#input_drift_detection_reconcile) | Flag to enable/disable automatic reconciliation of drifts. | `bool` | `false` | no | -| [drift_detection_schedule](#input_drift_detection_schedule) | The schedule for drift detection. | `list(string)` |
[
"0 4 * * *"
]
| no | -| [drift_detection_timezone](#input_drift_detection_timezone) | The timezone for drift detection. | `string` | `"UTC"` | no | -| [enable_local_preview](#input_enable_local_preview) | Indicates whether local preview runs can be triggered on this Stack. | `bool` | `false` | no | -| [enable_well_known_secret_masking](#input_enable_well_known_secret_masking) | Indicates whether well-known secret masking is enabled. | `bool` | `true` | no | -| [enabled_root_modules](#input_enabled_root_modules) | List of root modules where to look for stack config files.
Ignored when all_root_modules_enabled is true.
Example: ["spacelift-automation", "k8s-cluster"] | `list(string)` | `[]` | no | -| [github_action_deploy](#input_github_action_deploy) | Indicates whether GitHub users can deploy from the Checks API. | `bool` | `true` | no | -| [github_enterprise](#input_github_enterprise) | The GitHub VCS settings |
object({
namespace = string
id = optional(string)
})
| `null` | no | -| [labels](#input_labels) | List of labels to apply to the stacks. | `list(string)` | `[]` | no | -| [manage_state](#input_manage_state) | Determines if Spacelift should manage state for this stack. | `bool` | `false` | no | -| [protect_from_deletion](#input_protect_from_deletion) | Protect this stack from accidental deletion. If set, attempts to delete this stack will fail. | `bool` | `false` | no | -| [repository](#input_repository) | The name of your infrastructure repo | `string` | n/a | yes | -| [root_module_structure](#input_root_module_structure) | The root module structure of the Stacks that you're reading in. See README for full details.

MultiInstance - You're using Workspaces or Dynamic Backend configuration to create multiple instances of the same root module code.
SingleInstance - You're using copies of a root module and your directory structure to create multiple instances of the same Terraform code. | `string` | `"MultiInstance"` | no | -| [root_modules_path](#input_root_modules_path) | The path, relative to the root of the repository, where the root module can be found. | `string` | `"root-modules"` | no | -| [runner_image](#input_runner_image) | URL of the Docker image used to process Runs. Defaults to `null` which is Spacelift's standard (Alpine) runner image. | `string` | `null` | no | -| [space_id](#input_space_id) | Place the created stacks in the specified space_id. | `string` | `"root"` | no | -| [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) | Terraform version to use. | `string` | `"1.7.2"` | 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 | +| Name | Description | Type | Default | Required | +| --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | :------: | +| [additional_project_globs](#input_additional_project_globs) | Project globs is an optional list of paths to track stack changes of outside of the project root. Push policies are another alternative to track changes in additional paths. | `set(string)` | `[]` | no | +| [administrative](#input_administrative) | Flag to mark the stack as administrative | `bool` | `false` | no | +| [after_apply](#input_after_apply) | List of after-apply scripts | `list(string)` | `[]` | no | +| [after_destroy](#input_after_destroy) | List of after-destroy scripts | `list(string)` | `[]` | no | +| [after_init](#input_after_init) | List of after-init scripts | `list(string)` | `[]` | no | +| [after_perform](#input_after_perform) | List of after-perform scripts | `list(string)` | `[]` | no | +| [after_plan](#input_after_plan) | List of after-plan scripts | `list(string)` | `[]` | no | +| [all_root_modules_enabled](#input_all_root_modules_enabled) | When set to true, all subdirectories in root_modules_path will be treated as root modules. | `bool` | `false` | no | +| [autodeploy](#input_autodeploy) | Flag to enable/disable automatic deployment of the stack | `bool` | `true` | no | +| [autoretry](#input_autoretry) | Flag to enable/disable automatic retry of the stack | `bool` | `false` | no | +| [aws_integration_attachment_read](#input_aws_integration_attachment_read) | Indicates whether this attachment is used for read operations. | `bool` | `true` | no | +| [aws_integration_attachment_write](#input_aws_integration_attachment_write) | Indicates whether this attachment is used for write operations. | `bool` | `true` | no | +| [aws_integration_enabled](#input_aws_integration_enabled) | Indicates whether the AWS integration is enabled. | `bool` | `false` | no | +| [aws_integration_id](#input_aws_integration_id) | ID of the AWS integration to attach. | `string` | `null` | no | +| [before_apply](#input_before_apply) | List of before-apply scripts | `list(string)` | `[]` | no | +| [before_destroy](#input_before_destroy) | List of before-destroy scripts | `list(string)` | `[]` | no | +| [before_init](#input_before_init) | List of before-init scripts | `list(string)` | `[]` | no | +| [before_perform](#input_before_perform) | List of before-perform scripts | `list(string)` | `[]` | no | +| [before_plan](#input_before_plan) | List of before-plan scripts | `list(string)` | `[]` | no | +| [branch](#input_branch) | Specify which branch to use within the infrastructure repository. | `string` | `"main"` | no | +| [common_config_file](#input_common_config_file) | Name of the common configuration file for the stack across a root module. | `string` | `"common.yaml"` | no | +| [default_tf_workspace_enabled](#input_default_tf_workspace_enabled) | Enables the use of `default` Terraform workspace instead of managing multiple workspaces within a root module.

NOTE: We encourage the use of Terraform workspaces to manage multiple environments.
However, you will want to disable this behavior if you're utilizing different backends for each instance
of your root modules (we call this "Dynamic Backends"). | `bool` | `false` | no | +| [description](#input_description) | A description for the created Stacks. This is a template string that will be rendered with the final config object for the stack.
See the main.tf for full internals of that object and the documentation on templatestring for usage.
https://opentofu.org/docs/language/functions/templatestring/ | `string` | `"Root Module: ${root_module}\nProject Root: ${project_root}\nWorkspace: ${terraform_workspace}\nManaged by spacelift-automation Terraform root module."` | no | +| [destructor_enabled](#input_destructor_enabled) | Flag to enable/disable the destructor for the Stack. | `bool` | `false` | no | +| [drift_detection_enabled](#input_drift_detection_enabled) | Flag to enable/disable Drift Detection configuration for a Stack. | `bool` | `false` | no | +| [drift_detection_ignore_state](#input_drift_detection_ignore_state) | Controls whether drift detection should be performed on a stack
in any final state instead of just 'Finished'. | `bool` | `false` | no | +| [drift_detection_reconcile](#input_drift_detection_reconcile) | Flag to enable/disable automatic reconciliation of drifts. | `bool` | `false` | no | +| [drift_detection_schedule](#input_drift_detection_schedule) | The schedule for drift detection. | `list(string)` |
[
"0 4 * * *"
]
| no | +| [drift_detection_timezone](#input_drift_detection_timezone) | The timezone for drift detection. | `string` | `"UTC"` | no | +| [enable_local_preview](#input_enable_local_preview) | Indicates whether local preview runs can be triggered on this Stack. | `bool` | `false` | no | +| [enable_well_known_secret_masking](#input_enable_well_known_secret_masking) | Indicates whether well-known secret masking is enabled. | `bool` | `true` | no | +| [enabled_root_modules](#input_enabled_root_modules) | List of root modules where to look for stack config files.
Ignored when all_root_modules_enabled is true.
Example: ["spacelift-automation", "k8s-cluster"] | `list(string)` | `[]` | no | +| [github_action_deploy](#input_github_action_deploy) | Indicates whether GitHub users can deploy from the Checks API. | `bool` | `true` | no | +| [github_enterprise](#input_github_enterprise) | The GitHub VCS settings |
object({
namespace = string
id = optional(string)
})
| `null` | no | +| [labels](#input_labels) | List of labels to apply to the stacks. | `list(string)` | `[]` | no | +| [manage_state](#input_manage_state) | Determines if Spacelift should manage state for this stack. | `bool` | `false` | no | +| [protect_from_deletion](#input_protect_from_deletion) | Protect this stack from accidental deletion. If set, attempts to delete this stack will fail. | `bool` | `false` | no | +| [repository](#input_repository) | The name of your infrastructure repo | `string` | n/a | yes | +| [root_module_structure](#input_root_module_structure) | The root module structure of the Stacks that you're reading in. See README for full details.

MultiInstance - You're using Workspaces or Dynamic Backend configuration to create multiple instances of the same root module code.
SingleInstance - You're using copies of a root module and your directory structure to create multiple instances of the same Terraform code. | `string` | `"MultiInstance"` | no | +| [root_modules_path](#input_root_modules_path) | The path, relative to the root of the repository, where the root module can be found. | `string` | `"root-modules"` | no | +| [runner_image](#input_runner_image) | URL of the Docker image used to process Runs. Defaults to `null` which is Spacelift's standard (Alpine) runner image. | `string` | `null` | no | +| [space_id](#input_space_id) | Place the created stacks in the specified space_id. | `string` | `"root"` | no | +| [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) | Terraform version to use. | `string` | `"1.7.2"` | 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 | ## Outputs -| Name | Description | -| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [spacelift_stacks](#output_spacelift_stacks) | A map of Spacelift stacks with selected attributes.
To reduce the risk of accidentally exporting sensitive data, only a subset of attributes is exported. | +| Name | Description | +| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [spacelift_stacks](#output_spacelift_stacks) | A map of Spacelift stacks with selected attributes.
To reduce the risk of accidentally exporting sensitive data, only a subset of attributes is exported. | diff --git a/main.tf b/main.tf index c16daf4..89c047e 100644 --- a/main.tf +++ b/main.tf @@ -298,7 +298,6 @@ resource "spacelift_stack" "default" { before_perform = compact(coalesce(try(local.stack_configs[each.key].before_perform, []), var.before_perform)) before_plan = compact(coalesce(try(local.stack_configs[each.key].before_plan, []), var.before_plan)) branch = try(local.stack_configs[each.key].branch, var.branch) - description = coalesce(try(local.stack_configs[each.key].description, null), var.description) enable_local_preview = try(local.stack_configs[each.key].enable_local_preview, var.enable_local_preview) enable_well_known_secret_masking = try(local.stack_configs[each.key].enable_well_known_secret_masking, var.enable_well_known_secret_masking) github_action_deploy = try(local.stack_configs[each.key].github_action_deploy, var.github_action_deploy) @@ -316,6 +315,13 @@ resource "spacelift_stack" "default" { terraform_workspace = local.configs[each.key].terraform_workspace worker_pool_id = try(local.stack_configs[each.key].worker_pool_id, var.worker_pool_id) + # Usage of `templatestring` requires OpenTofu 1.7 and Terraform 1.9 or later. + description = coalesce( + try(local.stack_configs[each.key].description, null), + try(templatestring(var.description, local.configs[each.key]), null), + "Managed by spacelift-automation Terraform root module." + ) + dynamic "github_enterprise" { for_each = var.github_enterprise != null ? [var.github_enterprise] : [] content { diff --git a/tests/fixtures/multi-instance/root-module-a/stacks/default-example.yaml b/tests/fixtures/multi-instance/root-module-a/stacks/default-example.yaml index 19f3db3..a65ce1e 100644 --- a/tests/fixtures/multi-instance/root-module-a/stacks/default-example.yaml +++ b/tests/fixtures/multi-instance/root-module-a/stacks/default-example.yaml @@ -1,6 +1,7 @@ kind: StackConfigV1 stack_settings: administrative: true + description: This is a test of the emergency broadcast system before_init: - echo 'World' labels: 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 ef983aa..03c0f36 100644 --- a/tests/fixtures/multi-instance/root-module-a/stacks/test.yaml +++ b/tests/fixtures/multi-instance/root-module-a/stacks/test.yaml @@ -1,4 +1,5 @@ kind: StackConfigV1 stack_settings: + space_id: 123 labels: - test_label diff --git a/tests/main.tftest.hcl b/tests/main.tftest.hcl index b7dba3d..0a5af45 100644 --- a/tests/main.tftest.hcl +++ b/tests/main.tftest.hcl @@ -55,6 +55,16 @@ run "test_stacks_include_expected" { } } +# Test that the stack resource is created with the correct name +run "test_stack_resource_is_created_with_correct_name" { + command = plan + + assert { + condition = spacelift_stack.default["root-module-a-test"].name == "root-module-a-test" + error_message = "Stack resource was not created correctly: ${jsonencode(spacelift_stack.default)}" + } +} + # Test that the folder labels get created with correct format run "test_folder_labels_are_correct_format" { command = plan @@ -144,3 +154,35 @@ run "test_before_init_includes_the_default_before_init_and_stack_before_init" { error_message = "Before_init was not created correctly: ${jsonencode(local.before_init)}" } } + +# Test that the description is created correctly +run "test_description_is_created_correctly" { + command = plan + + assert { + condition = spacelift_stack.default["root-module-a-test"].description == "Root Module: root-module-a\nProject Root: ./tests/fixtures/multi-instance/root-module-a\nWorkspace: test\nManaged by spacelift-automation Terraform root module." + error_message = "Description was not created correctly: ${jsonencode(local.configs)}" + } +} + +# Test that the description is created correctly when non-default template string is used +run "test_description_is_created_correctly_when_non_default_template_string_is_used" { + command = plan + variables { + description = "Space ID: $${stack_settings.space_id}" + } + + assert { + condition = spacelift_stack.default["root-module-a-test"].description == "Space ID: 123" + error_message = "Description was not created correctly: ${jsonencode(local.configs)}" + } +} + +run "test_description_is_created_correctly_when_passed_from_stack_config" { + command = plan + + assert { + condition = spacelift_stack.default["root-module-a-default-example"].description == "This is a test of the emergency broadcast system" + error_message = "Description was not created correctly: ${jsonencode(local.configs)}" + } +} diff --git a/variables.tf b/variables.tf index 20d2868..f6ed3e1 100644 --- a/variables.tf +++ b/variables.tf @@ -207,8 +207,12 @@ variable "default_tf_workspace_enabled" { variable "description" { type = string - description = "Description of the stack" - default = "Managed by spacelift-automation Terraform root module." + description = <