{"id":23744543,"url":"https://github.com/masterpointio/terraform-spacelift-automation","last_synced_at":"2025-10-18T19:15:43.093Z","repository":{"id":259603620,"uuid":"845043331","full_name":"masterpointio/terraform-spacelift-automation","owner":"masterpointio","description":"Terraform module to automate Spacelift Stack management ⚡","archived":false,"fork":false,"pushed_at":"2024-12-30T17:01:39.000Z","size":160,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-12-30T17:37:40.509Z","etag":null,"topics":["opentofu","opentofu-module","spacelift","terraform","terraform-module"],"latest_commit_sha":null,"homepage":"https://masterpoint.io","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/masterpointio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-20T13:22:54.000Z","updated_at":"2024-12-30T17:01:27.000Z","dependencies_parsed_at":"2024-11-08T14:19:36.711Z","dependency_job_id":"9e05a1ff-7166-4c99-bade-5555636677b8","html_url":"https://github.com/masterpointio/terraform-spacelift-automation","commit_stats":null,"previous_names":["masterpointio/terraform-spacelift-automation"],"tags_count":7,"template":false,"template_full_name":"masterpointio/terraform-module-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/masterpointio%2Fterraform-spacelift-automation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/masterpointio%2Fterraform-spacelift-automation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/masterpointio%2Fterraform-spacelift-automation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/masterpointio%2Fterraform-spacelift-automation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/masterpointio","download_url":"https://codeload.github.com/masterpointio/terraform-spacelift-automation/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231984257,"owners_count":18456019,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["opentofu","opentofu-module","spacelift","terraform","terraform-module"],"created_at":"2024-12-31T12:24:08.514Z","updated_at":"2025-10-18T19:15:43.085Z","avatar_url":"https://github.com/masterpointio.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Banner][banner-image]](https://masterpoint.io/)\n\n# spacelift-automation\n\n[![Release][release-badge]][latest-release]\n\n💡 Learn more about Masterpoint [below](#who-we-are-𐦂𖨆𐀪𖠋).\n\n## Purpose and Functionality\n\nThis Terraform child module provides infrastructure automation for projects in [Spacelift](https://docs.spacelift.io/).\n\n### Overview\n\nThis `spacelift-automation` child module is designed to streamline the deployment and management of all Spacelift infrastructure, including creating a Spacelift Stack to manage itself.\n\nCheck out our quick introduction to this child module here: [![[External] terraform-spacelift-automation quick intro - Watch Video](https://cdn.loom.com/sessions/thumbnails/8de21afb732048a58fdee90042b4840f-11908d1d42de3247-full-play.gif)](https://www.loom.com/share/8de21afb732048a58fdee90042b4840f)\n\nIt automates the creation of \"child\" stacks and all the required accompanying Spacelift resources. For each enabled root module it creates:\n\n1. [Spacelift Stack](https://docs.spacelift.io/concepts/stack/)\n   You can think about a stack as a combination of source code, state file and configuration in the form of environment variables and mounted files.\n2. [Spacelift Stack Destructor](https://docs.spacelift.io/concepts/stack/stack-dependencies.html#ordered-stack-creation-and-deletion)\n   Required to destroy the resources of a Stack before deleting it. Destroying this resource will delete the resources in the stack. If this resource needs to be deleted and the resources in the stacks are to be preserved, ensure that the deactivated attribute is set to true.\n3. [Spacelift AWS Integration Attachment](https://docs.spacelift.io/integrations/cloud-providers/aws#lets-explain)\n   Associates a specific AWS IAM role with a stack to allow it to assume that role. The IAM role typically has permissions to manage specific AWS resources, and Spacelift assumes this role to run the operations required by the stack.\n4. [Spacelift Initialization Hook](https://docs.spacelift.io/concepts/run#initializing)\n   Prepares your environment before executing infrastructure code. This custom script copies corresponding Terraform tfvars files into a working directory before any Spacelift run or task as a `spacelift.auto.tfvars` file. This ensures your tfvars are [automatically loaded](https://opentofu.org/docs/v1.7/language/values/variables/#variable-definitions-tfvars-files) into the OpenTofu/Terraform execution environment.\n\n## Usage\n\nSpacelift Automation logic is opinionated and heavily relies on certain repository structures.\nThis module is configured to track all the files in the given root module directory and create Spacelift Stacks based on the provided configuration.\n\nWe support the following root module directory structures, which are controlled by the `var.root_modules_structure` variable:\n\n### `MultiInstance` (the default)\n\nThis is the default structure that we expect and recommend. This is intended for root modules that manage multiple state files (instances) through [workspaces](https://opentofu.org/docs/cli/workspaces/) or [Dynamic Backend configurations](https://opentofu.org/docs/intro/whats-new/#early-variablelocals-evaluation).\n\nStructure requirements:\n\n- Stack configs are placed in `\u003croot_modules_path\u003e/\u003croot_module\u003e/stacks` directory for each workspace / instance of that stack. e.g. `root-modules/k8s-cluster/stacks/dev.yaml` and `root-modules/k8s-cluster/stacks/stage.yaml`\n- Terraform variables are placed in `\u003croot_modules_path\u003e/\u003croot_module\u003e/tfvars` directory for each workspace / instance of that stack. e.g. `root-modules/k8s-cluster/tfvars/dev.tfvars` and `root-modules/k8s-cluster/tfvars/stage.tfvars`\n- Stack config files and tfvars files must be equal to OpenTofu/Terraform workspace, e.g. `stacks/dev.yaml` and `tfvars/dev.tfvars` for a workspace named `dev`.\n- Common configs are placed in `\u003croot_modules_path\u003e/\u003croot_module\u003e/stacks/common.yaml` file (or `var.common_config_file` value). This is useful when you know that some values should be shared across all the stacks created for a root module. For example, all stacks that manage Spacelift Policies must use the `administrative: true` setting or all stacks must share the same labels.\n\nWe have an example of this structure in the [examples/complete](./examples/complete/root-modules/), which looks like the following:\n\n```sh\n├── root-modules\n│   ├── network\n│   │   ├── stacks\n│   │   │   └── dev.yaml\n│   │   │   └── prod.yaml\n│   │   ├── tfvars\n│   │   │   └── dev.tfvars\n│   │   │   └── prod.tfvars\n│   │   ├── variables.tf\n│   │   ├── main.tf\n│   │   └── versions.tf\n│   ├── random-pet\n│   │   ├── stacks\n│   │   │   └── dev.yaml\n│   │   │   └── prod.yaml\n│   │   │   └── common.yaml\n│   │   ├── tfvars\n│   │   │   └── dev.tfvars\n│   │   │   └── prod.tfvars\n│   │   ├── variables.tf\n│   │   ├── main.tf\n│   │   └── versions.tf\n│   ├── spacelift-automation\n│   │   ├── stacks\n│   │   │   └── common.yaml\n│   │   ├── main.tf\n│   │   └── versions.tf\n...\n```\n\nThe `spacelift-automation/main.tf` file looks something like this:\n\n```hcl\ngithub_enterprise = {\n  namespace = \"masterpointio\"\n}\nrepository = \"terraform-spacelift-automation\"\n\n# Stacks configurations\nroot_modules_path        = \"root-modules\"\nall_root_modules_enabled = true\n\naws_integration_id = \"ZDPP8SKNVG0G27T4\"\n```\n\nThe configuration above creates the following stacks:\n\n- `network-dev`\n- `network-prod`\n- `random-pet-dev`\n- `random-pet-prod`\n- `spacelift-automation`\n\nThese stacks have the following configuration:\n\n- Stacks track changes in GitHub repo `github.com/masterpointio/terraform-spacelift-automation`, branch `main` (the default), and directrory `root-modules`.\n- Common configuration is defined in `root-modules/random-pet/stacks/common.yaml` and applied to both `random-pet-dev` and `random-pet-prod` stacks. However, if there is an override in a Stack config (e.g. `root-modules/random-pet/stacks/dev.yaml`), it takes precedence over common configs.\n- Corresponding Terraform variables are generated by an [Initialization Hook](https://docs.spacelift.io/concepts/run#initializing) and placed in the root of each Stack's working directory during each run or task. For example, the content of the file `root-modules/network/tfvars/dev.tfvars` will be copied to working directory of the Stack `network-dev` as file `spacelift.auto.tfvars` allowing the OpenTofu/Terraform inputs to be automatically loaded.\n  - If you would like to disable this functionality, you can set `tfvars.enabled` in the Stack's YAML file to `false`.\n\n### `SingleInstance`\n\nThis is a special case where each root module directory only manages one state file (instance). Each time you want to create a new instance of a root module, you need to create a new directory with the same code and change your inputs. **We do not recommend this structure** as it is less flexible and easily leads to anti-patterns, but it is supported.\n\nStructure requirements:\n\n- Stack configs are placed in `\u003croot_modules_path\u003e/\u003croot_module\u003e/stack.yaml` directory. e.g. `root-modules/rds-cluster/stack.yaml`\n- Tfvars values are not supported in this structure. In this structure, we suggest you just add your tfvars as `***.auto.tfvars` or hardcode your values directly in root module code.\n\nHere is an example of this structure that we have in the [examples/single-instance](./examples/single-instance/) directory:\n\n```sh\n├── root-modules\n│   ├── spacelift-automation\n│   │   ├── stack.yaml\n│   │   ├── variables.tf\n│   │   ├── main.tf\n│   │   └── versions.tf\n│   ├── rds-cluster-dev\n│   │   ├── stack.yaml\n│   │   ├── main.tf\n│   │   └── versions.tf\n│   ├── rds-cluster-prod\n│   │   ├── stack.yaml\n│   │   ├── main.tf\n│   │   └── versions.tf\n│   ├── random-pet\n│   │   ├── stack.yaml\n│   │   ├── variables.tf\n│   │   ├── main.tf\n│   │   └── versions.tf\n...\n```\n\nThe configuration above creates the following Spacelift Stacks:\n\n- `spacelift-automation`\n- `rds-cluster-dev`\n- `rds-cluster-prod`\n- `random-pet`\n\nThese stacks will be configured using the settings in the `stack.yaml` file.\n\n## FAQs\n\n### Can I create a Spacelift Stack for Spacelift Automation? (Recommended)\n\nSpacelift Automation can manage itself as a Stack as well, and we recommend this so you can fully automate your Stack management upon merging to your given branch. Follow these steps to achieve that:\n\n1. Create a new vanilla OpenTofu/Terraform root module in `\u003croot_modules_path\u003e/spacelift-automation` that consumes this child module and supplies the necessary configuration for your unique setup. e.g.\n\n   ```hcl\n   # root-modules/spacelift-automation/main.tf\n\n   module \"spacelift-automation\" {\n     source  = \"masterpointio/automation/spacelift\"\n     version = \"x.x.x\" # Always pin a version, use the latest version from the release page.\n\n     # GitHub configuration\n     github_enterprise = {\n       namespace = \"masterpointio\"\n     }\n     repository = \"your-infrastructure-repo\"\n\n     # Stacks configurations\n     root_modules_path        = \"../../root-modules\"\n     all_root_modules_enabled = true\n\n     aws_integration_id = \"ZDPP8SKNVG0G27T4\"\n   }\n   ```\n\n2. Optionally, create a Terraform workspace that will be used for your Automation configuration, e.g.:\n\n   ```sh\n   tofu workspace new main\n   ```\n\n   Remember that Stack config and tfvars file name must be equal to the workspace e.g. `main.yaml` and `main.tfvars`. If you choose not to create a new workspace, this can be `default.yaml` and `default.tfvars`.\n\n3. Apply the `spacelift-automation` root module.\n4. Move the Automation configs to the `\u003croot-modules\u003e/spacelift-automation/stacks` directory and push the changes to the tracked repo and branch.\n5. After pushed to your repo's tracked branch, Spacelift Automation will track the addition of new root modules and create Stacks for them.\n\nCheck out an example configuration in the [examples/complete](./examples/complete/root-modules/spacelift-automation).\n\n\u003c!-- NOTE to Masterpoint team: We might want to create a small wrapper to automatize this using Taskit. On hold for now. --\u003e\n\n### What goes in a Stack config file? e.g. `stacks/dev.yaml`, `stacks/common.yaml`, `stack.yaml`, and similar\n\nMost settings that you would set on [the Spacelift Stack resource](https://search.opentofu.org/provider/spacelift-io/spacelift/latest/docs/resources/stack) are supported. Additionally, you can include certain automation settings that will override this module's defaults like `automation_settings.default_tf_workspace_enabled`, `automation_settings.tfvars_enabled`, `space_name`, and similar.\n\nBelow is a brief example. You can also see the full schema in our [JSON Schema file](./stack-config.schema.json).\n\n```yaml\nkind: StackConfigV1\nstack_settings:\n  administrative: true\n  autodeploy: true\n  autoretry: true\n  description: \"Production EKS cluster configuration\"\n  labels:\n    - \"prod\"\n\n  terraform_version: \"1.9.0\"\n  terraform_workflow_tool: \"OPEN_TOFU\"\n\n  # Security and protection\n  protect_from_deletion: true\n  enable_local_preview: false\n\n  # Hooks and scripts\n  before_init:\n    - \"echo hello-world\"\n  after_apply:\n    - \"./scripts/notify-slack.sh\"\n\nautomation_settings:\n  default_tf_workspace_enabled: true\n  tfvars_enabled: false\n```\n\n### Why are variable values provided separately in `tfvars/` and not in the `yaml` file?\n\nThis is to support easy local and outside-spacelift operations. Keeping variable values in a `tfvars` file per workspace allows you to simply pass that file to the relevant CLI command locally via the `-var-file` option so that you don't need to provide values individually. e.g. `tofu plan -var-file=tfvars/dev.tfvars`\n\n### What if my stacks are in another repo?\n\nBy default, this module assumes all stacks are in the same repo as the stack with the module instance. To manage \"remote stacks\" in a different repo:\n\n1. Create the other repo. Add configuration files for each stack at the desired file path, such as `stacks/random-pet`. There should not be a `stack.yaml` file in the other repo.\n\n   ```text\n   other-repo\n   └── stacks\n       └── random-pet\n           ├── main.tf\n           └── versions.tofu\n   ```\n\n2. Update any Spacelift GitHub apps to allow access to the other repo.\n3. Add a directory for remote stacks to _this repo_. It is not recommended to nest the `remote-stacks` directory within the Spacelift automation stack directory because of how the module detects nested stacks (see [masterpointio/terraform-spacelift-automation#80](https://github.com/masterpointio/terraform-spacelift-automation/pull/80), released in\n   [module v1.5.0](https://github.com/masterpointio/terraform-spacelift-automation/releases/tag/v1.5.0)). For example, here's how it might look for a repo named `other-repo` and a stack named `other-repo-random-pet`:\n\n   ```text\n   this-repo\n   ├── remote-stacks\n   │   └── other-repo\n   │       └── other-repo-random-pet\n   │           └── stack.yaml\n   └── stacks\n       └── spacelift-automation\n           ├── main.tf\n           ├── stack.yaml\n           └── versions.tofu\n   ```\n\n4. Ensure that each `stack.yaml` has the `project_root` set to the stack path in _the other repo_ and that the appropriate settings have been applied.\n\n   ```yaml\n   # this-repo/remote-stacks/other-repo/other-repo-random-pet/stack.yaml\n   stack_settings:\n     project_root: stacks/random-pet\n   ```\n\n5. Add a new module block for the repo to `this-repo/stacks/spacelift-automation/main.tf`. The `root_modules_path` should point to the new `remote-stacks` subdirectory for the repo.\n\n   ```hcl\n   # this-repo/stacks/spacelift-automation/main.tf\n   module \"spacelift_automation_this_repo\" {\n     source = \"git::https://github.com/masterpointio/terraform-spacelift-automation.git\"\n\n     repository            = \"this-repo\"\n     root_modules_path     = \"../../stacks\"\n   }\n\n   module \"spacelift_automation_other_repo\" {\n     source = \"git::https://github.com/masterpointio/terraform-spacelift-automation.git\"\n\n     repository            = \"other-repo\"\n     root_modules_path     = \"../../remote-stacks/other-repo\"\n   }\n   ```\n\nThis will properly configure your spacelift-automation root module to start managing the stacks for the remote repositories.\n\nIf you have many remote repositories that you need to manage via this pattern, you can supply different `repository` values in your Stack configs and omit that value from the \"remote-stacks\" child module arguments.\n\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003c!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --\u003e\n## Requirements\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"requirement_terraform\"\u003e\u003c/a\u003e [terraform](#requirement\\_terraform) | \u003e= 1.9 |\n| \u003ca name=\"requirement_jsonschema\"\u003e\u003c/a\u003e [jsonschema](#requirement\\_jsonschema) | \u003e= 0.2.1 |\n| \u003ca name=\"requirement_spacelift\"\u003e\u003c/a\u003e [spacelift](#requirement\\_spacelift) | \u003e= 1.14 |\n\n## Providers\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"provider_jsonschema\"\u003e\u003c/a\u003e [jsonschema](#provider\\_jsonschema) | \u003e= 0.2.1 |\n| \u003ca name=\"provider_spacelift\"\u003e\u003c/a\u003e [spacelift](#provider\\_spacelift) | \u003e= 1.14 |\n\n## Modules\n\n| Name | Source | Version |\n|------|--------|---------|\n| \u003ca name=\"module_deep\"\u003e\u003c/a\u003e [deep](#module\\_deep) | cloudposse/config/yaml//modules/deepmerge | 1.0.2 |\n\n## Resources\n\n| Name | Type |\n|------|------|\n| [spacelift_aws_integration_attachment.default](https://registry.terraform.io/providers/spacelift-io/spacelift/latest/docs/resources/aws_integration_attachment) | resource |\n| [spacelift_drift_detection.default](https://registry.terraform.io/providers/spacelift-io/spacelift/latest/docs/resources/drift_detection) | resource |\n| [spacelift_space.default](https://registry.terraform.io/providers/spacelift-io/spacelift/latest/docs/resources/space) | resource |\n| [spacelift_stack.default](https://registry.terraform.io/providers/spacelift-io/spacelift/latest/docs/resources/stack) | resource |\n| [spacelift_stack_destructor.default](https://registry.terraform.io/providers/spacelift-io/spacelift/latest/docs/resources/stack_destructor) | resource |\n| [jsonschema_validator.runtime_overrides](https://registry.terraform.io/providers/bpedman/jsonschema/latest/docs/data-sources/validator) | data source |\n| [spacelift_aws_integrations.all](https://registry.terraform.io/providers/spacelift-io/spacelift/latest/docs/data-sources/aws_integrations) | data source |\n| [spacelift_spaces.all](https://registry.terraform.io/providers/spacelift-io/spacelift/latest/docs/data-sources/spaces) | data source |\n| [spacelift_worker_pools.all](https://registry.terraform.io/providers/spacelift-io/spacelift/latest/docs/data-sources/worker_pools) | data source |\n\n## Inputs\n\n| Name | Description | Type | Default | Required |\n|------|-------------|------|---------|:--------:|\n| \u003ca name=\"input_additional_project_globs\"\u003e\u003c/a\u003e [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 |\n| \u003ca name=\"input_administrative\"\u003e\u003c/a\u003e [administrative](#input\\_administrative) | Flag to mark the stack as administrative | `bool` | `false` | no |\n| \u003ca name=\"input_after_apply\"\u003e\u003c/a\u003e [after\\_apply](#input\\_after\\_apply) | List of after-apply scripts | `list(string)` | `[]` | no |\n| \u003ca name=\"input_after_destroy\"\u003e\u003c/a\u003e [after\\_destroy](#input\\_after\\_destroy) | List of after-destroy scripts | `list(string)` | `[]` | no |\n| \u003ca name=\"input_after_init\"\u003e\u003c/a\u003e [after\\_init](#input\\_after\\_init) | List of after-init scripts | `list(string)` | `[]` | no |\n| \u003ca name=\"input_after_perform\"\u003e\u003c/a\u003e [after\\_perform](#input\\_after\\_perform) | List of after-perform scripts | `list(string)` | `[]` | no |\n| \u003ca name=\"input_after_plan\"\u003e\u003c/a\u003e [after\\_plan](#input\\_after\\_plan) | List of after-plan scripts | `list(string)` | `[]` | no |\n| \u003ca name=\"input_after_run\"\u003e\u003c/a\u003e [after\\_run](#input\\_after\\_run) | List of after-run (aka `finally` hook) scripts | `list(string)` | `[]` | no |\n| \u003ca name=\"input_all_root_modules_enabled\"\u003e\u003c/a\u003e [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 |\n| \u003ca name=\"input_autodeploy\"\u003e\u003c/a\u003e [autodeploy](#input\\_autodeploy) | Flag to enable/disable automatic deployment of the stack | `bool` | `true` | no |\n| \u003ca name=\"input_autoretry\"\u003e\u003c/a\u003e [autoretry](#input\\_autoretry) | Flag to enable/disable automatic retry of the stack | `bool` | `false` | no |\n| \u003ca name=\"input_aws_integration_attachment_read\"\u003e\u003c/a\u003e [aws\\_integration\\_attachment\\_read](#input\\_aws\\_integration\\_attachment\\_read) | Indicates whether this attachment is used for read operations. | `bool` | `true` | no |\n| \u003ca name=\"input_aws_integration_attachment_write\"\u003e\u003c/a\u003e [aws\\_integration\\_attachment\\_write](#input\\_aws\\_integration\\_attachment\\_write) | Indicates whether this attachment is used for write operations. | `bool` | `true` | no |\n| \u003ca name=\"input_aws_integration_enabled\"\u003e\u003c/a\u003e [aws\\_integration\\_enabled](#input\\_aws\\_integration\\_enabled) | Indicates whether the AWS integration is enabled. | `bool` | `false` | no |\n| \u003ca name=\"input_aws_integration_id\"\u003e\u003c/a\u003e [aws\\_integration\\_id](#input\\_aws\\_integration\\_id) | ID of the AWS integration to attach. | `string` | `null` | no |\n| \u003ca name=\"input_aws_integration_name\"\u003e\u003c/a\u003e [aws\\_integration\\_name](#input\\_aws\\_integration\\_name) | Name of the AWS integration to attach, which will be resolved to aws\\_integration\\_id. We recommend using names rather than IDs to improve clarity \u0026 readability. Since Spacelift enforces unique names, you can rely on names as identifiers without worrying about duplication issues. | `string` | `null` | no |\n| \u003ca name=\"input_azure_devops\"\u003e\u003c/a\u003e [azure\\_devops](#input\\_azure\\_devops) | The Azure DevOps integration settings | \u003cpre\u003eobject({\u003cbr/\u003e    project = string\u003cbr/\u003e    id      = optional(string)\u003cbr/\u003e  })\u003c/pre\u003e | `null` | no |\n| \u003ca name=\"input_before_apply\"\u003e\u003c/a\u003e [before\\_apply](#input\\_before\\_apply) | List of before-apply scripts | `list(string)` | `[]` | no |\n| \u003ca name=\"input_before_destroy\"\u003e\u003c/a\u003e [before\\_destroy](#input\\_before\\_destroy) | List of before-destroy scripts | `list(string)` | `[]` | no |\n| \u003ca name=\"input_before_init\"\u003e\u003c/a\u003e [before\\_init](#input\\_before\\_init) | List of before-init scripts | `list(string)` | `[]` | no |\n| \u003ca name=\"input_before_perform\"\u003e\u003c/a\u003e [before\\_perform](#input\\_before\\_perform) | List of before-perform scripts | `list(string)` | `[]` | no |\n| \u003ca name=\"input_before_plan\"\u003e\u003c/a\u003e [before\\_plan](#input\\_before\\_plan) | List of before-plan scripts | `list(string)` | `[]` | no |\n| \u003ca name=\"input_bitbucket_cloud\"\u003e\u003c/a\u003e [bitbucket\\_cloud](#input\\_bitbucket\\_cloud) | The Bitbucket Cloud integration settings | \u003cpre\u003eobject({\u003cbr/\u003e    namespace = string\u003cbr/\u003e    id        = optional(string)\u003cbr/\u003e  })\u003c/pre\u003e | `null` | no |\n| \u003ca name=\"input_bitbucket_datacenter\"\u003e\u003c/a\u003e [bitbucket\\_datacenter](#input\\_bitbucket\\_datacenter) | The Bitbucket Data Center integration settings | \u003cpre\u003eobject({\u003cbr/\u003e    namespace = string\u003cbr/\u003e    id        = optional(string)\u003cbr/\u003e  })\u003c/pre\u003e | `null` | no |\n| \u003ca name=\"input_branch\"\u003e\u003c/a\u003e [branch](#input\\_branch) | Specify which branch to use within the infrastructure repository. | `string` | `\"main\"` | no |\n| \u003ca name=\"input_common_config_file\"\u003e\u003c/a\u003e [common\\_config\\_file](#input\\_common\\_config\\_file) | Name of the common configuration file for the stack across a root module. | `string` | `\"common.yaml\"` | no |\n| \u003ca name=\"input_default_tf_workspace_enabled\"\u003e\u003c/a\u003e [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.\u003cbr/\u003e\u003cbr/\u003eNOTE: We encourage the use of Terraform workspaces to manage multiple environments.\u003cbr/\u003eHowever, you will want to disable this behavior if you're utilizing different backends for each instance\u003cbr/\u003eof your root modules (we call this \"Dynamic Backends\"). | `bool` | `false` | no |\n| \u003ca name=\"input_description\"\u003e\u003c/a\u003e [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.\u003cbr/\u003e    See the main.tf for full internals of that object and the documentation on templatestring for usage.\u003cbr/\u003e    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 |\n| \u003ca name=\"input_destructor_deactivated\"\u003e\u003c/a\u003e [destructor\\_deactivated](#input\\_destructor\\_deactivated) | Whether to deactivate the stack destructor by default | `bool` | `true` | no |\n| \u003ca name=\"input_destructor_enabled\"\u003e\u003c/a\u003e [destructor\\_enabled](#input\\_destructor\\_enabled) | Whether to enable the stack destructor by default | `bool` | `true` | no |\n| \u003ca name=\"input_drift_detection_enabled\"\u003e\u003c/a\u003e [drift\\_detection\\_enabled](#input\\_drift\\_detection\\_enabled) | Flag to enable/disable Drift Detection configuration for a Stack. | `bool` | `false` | no |\n| \u003ca name=\"input_drift_detection_ignore_state\"\u003e\u003c/a\u003e [drift\\_detection\\_ignore\\_state](#input\\_drift\\_detection\\_ignore\\_state) | Controls whether drift detection should be performed on a stack\u003cbr/\u003ein any final state instead of just 'Finished'. | `bool` | `false` | no |\n| \u003ca name=\"input_drift_detection_reconcile\"\u003e\u003c/a\u003e [drift\\_detection\\_reconcile](#input\\_drift\\_detection\\_reconcile) | Flag to enable/disable automatic reconciliation of drifts. | `bool` | `false` | no |\n| \u003ca name=\"input_drift_detection_schedule\"\u003e\u003c/a\u003e [drift\\_detection\\_schedule](#input\\_drift\\_detection\\_schedule) | The schedule for drift detection. | `list(string)` | \u003cpre\u003e[\u003cbr/\u003e  \"0 4 * * *\"\u003cbr/\u003e]\u003c/pre\u003e | no |\n| \u003ca name=\"input_drift_detection_timezone\"\u003e\u003c/a\u003e [drift\\_detection\\_timezone](#input\\_drift\\_detection\\_timezone) | The timezone for drift detection. | `string` | `\"UTC\"` | no |\n| \u003ca name=\"input_enable_local_preview\"\u003e\u003c/a\u003e [enable\\_local\\_preview](#input\\_enable\\_local\\_preview) | Indicates whether local preview runs can be triggered on this Stack. | `bool` | `false` | no |\n| \u003ca name=\"input_enable_well_known_secret_masking\"\u003e\u003c/a\u003e [enable\\_well\\_known\\_secret\\_masking](#input\\_enable\\_well\\_known\\_secret\\_masking) | Indicates whether well-known secret masking is enabled. | `bool` | `true` | no |\n| \u003ca name=\"input_enabled_root_modules\"\u003e\u003c/a\u003e [enabled\\_root\\_modules](#input\\_enabled\\_root\\_modules) | List of root modules where to look for stack config files.\u003cbr/\u003eIgnored when all\\_root\\_modules\\_enabled is true.\u003cbr/\u003eExample: [\"spacelift-automation\", \"k8s-cluster\"] | `list(string)` | `[]` | no |\n| \u003ca name=\"input_github_action_deploy\"\u003e\u003c/a\u003e [github\\_action\\_deploy](#input\\_github\\_action\\_deploy) | Indicates whether GitHub users can deploy from the Checks API. | `bool` | `true` | no |\n| \u003ca name=\"input_github_enterprise\"\u003e\u003c/a\u003e [github\\_enterprise](#input\\_github\\_enterprise) | The GitHub VCS settings | \u003cpre\u003eobject({\u003cbr/\u003e    namespace = string\u003cbr/\u003e    id        = optional(string)\u003cbr/\u003e  })\u003c/pre\u003e | `null` | no |\n| \u003ca name=\"input_gitlab\"\u003e\u003c/a\u003e [gitlab](#input\\_gitlab) | The GitLab integration settings | \u003cpre\u003eobject({\u003cbr/\u003e    namespace = string\u003cbr/\u003e    id        = optional(string)\u003cbr/\u003e  })\u003c/pre\u003e | `null` | no |\n| \u003ca name=\"input_labels\"\u003e\u003c/a\u003e [labels](#input\\_labels) | List of labels to apply to the stacks. | `list(string)` | `[]` | no |\n| \u003ca name=\"input_manage_state\"\u003e\u003c/a\u003e [manage\\_state](#input\\_manage\\_state) | Determines if Spacelift should manage state for this stack. | `bool` | `false` | no |\n| \u003ca name=\"input_protect_from_deletion\"\u003e\u003c/a\u003e [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 |\n| \u003ca name=\"input_raw_git\"\u003e\u003c/a\u003e [raw\\_git](#input\\_raw\\_git) | The raw Git integration settings | \u003cpre\u003eobject({\u003cbr/\u003e    namespace = string\u003cbr/\u003e    url       = string\u003cbr/\u003e  })\u003c/pre\u003e | `null` | no |\n| \u003ca name=\"input_repository\"\u003e\u003c/a\u003e [repository](#input\\_repository) | The name of your infrastructure repo | `string` | n/a | yes |\n| \u003ca name=\"input_root_module_structure\"\u003e\u003c/a\u003e [root\\_module\\_structure](#input\\_root\\_module\\_structure) | The root module structure of the Stacks that you're reading in. See README for full details.\u003cbr/\u003e\u003cbr/\u003eMultiInstance - You're using Workspaces or Dynamic Backend configuration to create multiple instances of the same root module code.\u003cbr/\u003eSingleInstance - You're using copies of a root module and your directory structure to create multiple instances of the same Terraform code. | `string` | `\"MultiInstance\"` | no |\n| \u003ca name=\"input_root_modules_path\"\u003e\u003c/a\u003e [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 |\n| \u003ca name=\"input_runner_image\"\u003e\u003c/a\u003e [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 |\n| \u003ca name=\"input_runtime_overrides\"\u003e\u003c/a\u003e [runtime\\_overrides](#input\\_runtime\\_overrides) | Runtime overrides that are merged into the stack config.\u003cbr/\u003e  This allows for per-root-module overrides of the stack resources at runtime\u003cbr/\u003e  so you have more flexibility beyond the variable defaults and the static stack config files.\u003cbr/\u003e  Keys are the root module names and values match the StackConfig schema.\u003cbr/\u003e  See `stack-config.schema.json` for full details on the schema and\u003cbr/\u003e  `tests/fixtures/multi-instance/root-module-a/stacks/default-example.yaml` for a complete example. | `any` | `{}` | no |\n| \u003ca name=\"input_space_id\"\u003e\u003c/a\u003e [space\\_id](#input\\_space\\_id) | Place the created stacks in the specified space\\_id. Mutually exclusive with space\\_name. | `string` | `null` | no |\n| \u003ca name=\"input_space_name\"\u003e\u003c/a\u003e [space\\_name](#input\\_space\\_name) | Place the created stacks in the specified space\\_name. Mutually exclusive with space\\_id. We recommend using names rather than IDs to improve clarity \u0026 readability. Since Spacelift enforces unique names, you can rely on names as identifiers without worrying about duplication issues. | `string` | `null` | no |\n| \u003ca name=\"input_spaces\"\u003e\u003c/a\u003e [spaces](#input\\_spaces) | A map of Spacelift Spaces to create | \u003cpre\u003emap(object({\u003cbr/\u003e    description      = optional(string, null)\u003cbr/\u003e    inherit_entities = optional(bool, false)\u003cbr/\u003e    labels           = optional(list(string), null)\u003cbr/\u003e    parent_space_id  = optional(string, \"root\")\u003cbr/\u003e  }))\u003c/pre\u003e | `{}` | no |\n| \u003ca name=\"input_terraform_smart_sanitization\"\u003e\u003c/a\u003e [terraform\\_smart\\_sanitization](#input\\_terraform\\_smart\\_sanitization) | Indicates whether runs on this will use terraform's sensitive value system to sanitize\u003cbr/\u003ethe outputs of Terraform state and plans in spacelift instead of sanitizing all fields. | `bool` | `false` | no |\n| \u003ca name=\"input_terraform_version\"\u003e\u003c/a\u003e [terraform\\_version](#input\\_terraform\\_version) | OpenTofu/Terraform version to use. Defaults to the latest available version of the `terraform_workflow_tool`. | `string` | `null` | no |\n| \u003ca name=\"input_terraform_workflow_tool\"\u003e\u003c/a\u003e [terraform\\_workflow\\_tool](#input\\_terraform\\_workflow\\_tool) | Defines the tool that will be used to execute the workflow.\u003cbr/\u003eThis can be one of OPEN\\_TOFU, TERRAFORM\\_FOSS or CUSTOM. | `string` | `\"OPEN_TOFU\"` | no |\n| \u003ca name=\"input_worker_pool_id\"\u003e\u003c/a\u003e [worker\\_pool\\_id](#input\\_worker\\_pool\\_id) | ID of the worker pool to use. Mutually exclusive with worker\\_pool\\_name.\u003cbr/\u003eNOTE: worker\\_pool\\_name or worker\\_pool\\_id is required when using a self-hosted instance of Spacelift.\u003cbr/\u003eWe recommend using names rather than IDs to improve clarity \u0026 readability. Since Spacelift enforces unique names, you can rely on names as identifiers without worrying about duplication issues. | `string` | `null` | no |\n| \u003ca name=\"input_worker_pool_name\"\u003e\u003c/a\u003e [worker\\_pool\\_name](#input\\_worker\\_pool\\_name) | Name of the worker pool to use. Mutually exclusive with worker\\_pool\\_id.\u003cbr/\u003eNOTE: worker\\_pool\\_name or worker\\_pool\\_id is required when using a self-hosted instance of Spacelift. | `string` | `null` | no |\n\n## Outputs\n\n| Name | Description |\n|------|-------------|\n| \u003ca name=\"output_spacelift_spaces\"\u003e\u003c/a\u003e [spacelift\\_spaces](#output\\_spacelift\\_spaces) | A map of Spacelift spaces with all their attributes. |\n| \u003ca name=\"output_spacelift_stacks\"\u003e\u003c/a\u003e [spacelift\\_stacks](#output\\_spacelift\\_stacks) | A map of Spacelift stacks with selected attributes.\u003cbr/\u003eTo reduce the risk of accidentally exporting sensitive data, only a subset of attributes is exported. |\n\u003c!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK --\u003e\n\u003c!-- markdownlint-enable --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n## Built By\n\nPowered by the [Masterpoint team](https://masterpoint.io/who-we-are/) and driven forward by contributions from the community ❤️\n\n[![Contributors][contributors-image]][contributors-url]\n\n## Contribution Guidelines\n\nContributions are welcome and appreciated!\n\nFound an issue or want to request a feature? [Open an issue][issues-url]\n\nWant to fix a bug you found or add some functionality? Fork, clone, commit, push, and PR — we'll check it out.\n\n## Who We Are 𐦂𖨆𐀪𖠋\n\nEstablished in 2016, Masterpoint is a team of experienced software and platform engineers specializing in Infrastructure as Code (IaC). We provide expert guidance to organizations of all sizes, helping them leverage the latest IaC practices to accelerate their engineering teams.\n\n### Our Mission\n\nOur mission is to simplify cloud infrastructure so developers can innovate faster, safer, and with greater confidence. By open-sourcing tools and modules that we use internally, we aim to contribute back to the community, promoting consistency, quality, and security.\n\n### Our Commitments\n\n- 🌟 **Open Source**: We live and breathe open source, contributing to and maintaining hundreds of projects across multiple organizations.\n- 🌎 **1% for the Planet**: Demonstrating our commitment to environmental sustainability, we are proud members of [1% for the Planet](https://www.onepercentfortheplanet.org), pledging to donate 1% of our annual sales to environmental nonprofits.\n- 🇺🇦 **1% Towards Ukraine**: With team members and friends affected by the ongoing [Russo-Ukrainian war](https://en.wikipedia.org/wiki/Russo-Ukrainian_War), we donate 1% of our annual revenue to invasion relief efforts, supporting organizations providing aid to those in need. [Here's how you can help Ukraine with just a few clicks](https://masterpoint.io/updates/supporting-ukraine/).\n\n## Connect With Us\n\nWe're active members of the community and are always publishing content, giving talks, and sharing our hard earned expertise. Here are a few ways you can see what we're up to:\n\n[![LinkedIn][linkedin-badge]][linkedin-url] [![Newsletter][newsletter-badge]][newsletter-url] [![Blog][blog-badge]][blog-url] [![YouTube][youtube-badge]][youtube-url]\n\n... and be sure to connect with our founder, [Matt Gowie](https://www.linkedin.com/in/gowiem/).\n\n## License\n\n[Apache License, Version 2.0][license-url].\n\n[![Open Source Initiative][osi-image]][license-url]\n\nCopyright © 2016-2025 [Masterpoint Consulting LLC](https://masterpoint.io/)\n\n\u003c!-- MARKDOWN LINKS \u0026 IMAGES --\u003e\n\n[banner-image]: https://masterpoint-public.s3.us-west-2.amazonaws.com/v2/standard-long-fullcolor.png\n[license-url]: https://opensource.org/license/apache-2-0\n[osi-image]: https://i0.wp.com/opensource.org/wp-content/uploads/2023/03/cropped-OSI-horizontal-large.png?fit=250%2C229\u0026ssl=1\n[linkedin-badge]: https://img.shields.io/badge/LinkedIn-Follow-0A66C2?style=for-the-badge\u0026logoColor=white\n[linkedin-url]: https://www.linkedin.com/company/masterpoint-consulting\n[blog-badge]: https://img.shields.io/badge/Blog-IaC_Insights-55C1B4?style=for-the-badge\u0026logoColor=white\n[blog-url]: https://masterpoint.io/updates/\n[newsletter-badge]: https://img.shields.io/badge/Newsletter-Subscribe-ECE295?style=for-the-badge\u0026logoColor=222222\n[newsletter-url]: https://newsletter.masterpoint.io/\n[youtube-badge]: https://img.shields.io/badge/YouTube-Subscribe-D191BF?style=for-the-badge\u0026logo=youtube\u0026logoColor=white\n[youtube-url]: https://www.youtube.com/channel/UCeeDaO2NREVlPy9Plqx-9JQ\n[release-badge]: https://img.shields.io/github/v/release/masterpointio/terraform-spacelift-automation?color=0E383A\u0026label=Release\u0026style=for-the-badge\u0026logo=github\u0026logoColor=white\n[latest-release]: https://github.com/masterpointio/terraform-spacelift-automation/releases/latest\n[contributors-image]: https://contrib.rocks/image?repo=masterpointio/terraform-spacelift-automation\n[contributors-url]: https://github.com/masterpointio/terraform-spacelift-automation/graphs/contributors\n[issues-url]: https://github.com/masterpointio/terraform-spacelift-automation/issues\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmasterpointio%2Fterraform-spacelift-automation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmasterpointio%2Fterraform-spacelift-automation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmasterpointio%2Fterraform-spacelift-automation/lists"}