diff --git a/docs/data-sources/module.md b/docs/data-sources/module.md index 725977fe..dd160449 100644 --- a/docs/data-sources/module.md +++ b/docs/data-sources/module.md @@ -47,6 +47,7 @@ data "spacelift_module" "k8s-module" { - `space_id` (String) ID (slug) of the space the module is in - `terraform_provider` (String) The module provider will by default be inferred from the repository name if it follows the terraform-provider-name naming convention. However, if the repository doesn't follow this convention, or you gave the module a custom name, you can provide the provider name here. - `worker_pool_id` (String) ID of the worker pool to use +- `workflow_tool` (String) Defines the tool that will be used to execute the workflow. This can be one of `OPEN_TOFU`, `TERRAFORM_FOSS` or `CUSTOM`. ### Nested Schema for `azure_devops` diff --git a/docs/data-sources/stack.md b/docs/data-sources/stack.md index 808d7031..82a96bb6 100644 --- a/docs/data-sources/stack.md +++ b/docs/data-sources/stack.md @@ -71,6 +71,7 @@ data "spacelift_stack" "k8s-core" { - `terraform_external_state_access` (Boolean) Indicates whether you can access the Stack state file from other stacks or outside of Spacelift. - `terraform_smart_sanitization` (Boolean) 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. - `terraform_version` (String) Terraform version to use +- `terraform_workflow_tool` (String) Defines the tool that will be used to execute the workflow. This can be one of `OPEN_TOFU`, `TERRAFORM_FOSS` or `CUSTOM`. - `terraform_workspace` (String) Terraform workspace to select - `worker_pool_id` (String) ID of the worker pool to use diff --git a/docs/data-sources/stacks.md b/docs/data-sources/stacks.md index 8b106622..79d11336 100644 --- a/docs/data-sources/stacks.md +++ b/docs/data-sources/stacks.md @@ -168,6 +168,7 @@ Read-Only: - `terraform_external_state_access` (Boolean) - `terraform_smart_sanitization` (Boolean) - `terraform_version` (String) +- `terraform_workflow_tool` (String) - `terraform_workspace` (String) - `worker_pool_id` (String) diff --git a/docs/resources/module.md b/docs/resources/module.md index 4190954c..16c7588b 100644 --- a/docs/resources/module.md +++ b/docs/resources/module.md @@ -59,6 +59,7 @@ resource "spacelift_module" "example-module" { - `space_id` (String) ID (slug) of the space the module is in - `terraform_provider` (String) The module provider will by default be inferred from the repository name if it follows the terraform-provider-name naming convention. However, if the repository doesn't follow this convention, or you gave the module a custom name, you can provide the provider name here. - `worker_pool_id` (String) ID of the worker pool to use. NOTE: worker_pool_id is required when using a self-hosted instance of Spacelift. +- `workflow_tool` (String) Defines the tool that will be used to execute the workflow. This can be one of `OPEN_TOFU`, `TERRAFORM_FOSS` or `CUSTOM`. Defaults to `TERRAFORM_FOSS`. ### Read-Only diff --git a/docs/resources/stack.md b/docs/resources/stack.md index 35d30f17..2399c50d 100644 --- a/docs/resources/stack.md +++ b/docs/resources/stack.md @@ -232,6 +232,7 @@ resource "spacelift_stack" "ansible-stack" { - `terraform_external_state_access` (Boolean) Indicates whether you can access the Stack state file from other stacks or outside of Spacelift. Defaults to `false`. - `terraform_smart_sanitization` (Boolean) 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. Note: Requires the terraform version to be v1.0.1 or above. Defaults to `false`. - `terraform_version` (String) Terraform version to use +- `terraform_workflow_tool` (String) Defines the tool that will be used to execute the workflow. This can be one of `OPEN_TOFU`, `TERRAFORM_FOSS` or `CUSTOM`. Defaults to `TERRAFORM_FOSS`. - `terraform_workspace` (String) Terraform workspace to select - `terragrunt` (Block List, Max: 1) Terragrunt-specific configuration. Presence means this Stack is an Terragrunt Stack. (see [below for nested schema](#nestedblock--terragrunt)) - `worker_pool_id` (String) ID of the worker pool to use. NOTE: worker_pool_id is required when using a self-hosted instance of Spacelift. diff --git a/spacelift/data_module.go b/spacelift/data_module.go index c05f643f..65d758cc 100644 --- a/spacelift/data_module.go +++ b/spacelift/data_module.go @@ -167,6 +167,11 @@ func dataModule() *schema.Resource { Description: "ID of the worker pool to use", Computed: true, }, + "workflow_tool": { + Type: schema.TypeString, + Description: "Defines the tool that will be used to execute the workflow. This can be one of `OPEN_TOFU`, `TERRAFORM_FOSS` or `CUSTOM`.", + Computed: true, + }, }, } } @@ -233,5 +238,9 @@ func dataModuleRead(ctx context.Context, d *schema.ResourceData, meta interface{ d.Set("worker_pool_id", nil) } + if workflowTool := module.WorkflowTool; workflowTool != nil { + d.Set("workflow_tool", *workflowTool) + } + return nil } diff --git a/spacelift/data_module_test.go b/spacelift/data_module_test.go index 6605d70b..58b8aa30 100644 --- a/spacelift/data_module_test.go +++ b/spacelift/data_module_test.go @@ -11,10 +11,11 @@ import ( ) func TestModuleData(t *testing.T) { - randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + t.Run("basic test", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) - testSteps(t, []resource.TestStep{{ - Config: fmt.Sprintf(` + testSteps(t, []resource.TestStep{{ + Config: fmt.Sprintf(` resource "spacelift_module" "test" { name = "test-module-%s" administrative = true @@ -28,20 +29,70 @@ func TestModuleData(t *testing.T) { module_id = spacelift_module.test.id } `, randomID), - Check: Resource( - "data.spacelift_module.test", - Attribute("id", Equals(fmt.Sprintf("test-module-%s", randomID))), - Attribute("administrative", Equals("true")), - Attribute("branch", Equals("master")), - Attribute("description", Equals("description")), - SetEquals("labels", "one", "two"), - Attribute("name", Equals(fmt.Sprintf("test-module-%s", randomID))), - Attribute("project_root", Equals("")), - Attribute("repository", Equals("terraform-bacon-tasty")), - SetEquals("shared_accounts", "bar-subdomain", "foo-subdomain"), - Attribute("terraform_provider", Equals("default")), - ), - }}) + Check: Resource( + "data.spacelift_module.test", + Attribute("id", Equals(fmt.Sprintf("test-module-%s", randomID))), + Attribute("administrative", Equals("true")), + Attribute("branch", Equals("master")), + Attribute("description", Equals("description")), + SetEquals("labels", "one", "two"), + Attribute("name", Equals(fmt.Sprintf("test-module-%s", randomID))), + Attribute("project_root", Equals("")), + Attribute("repository", Equals("terraform-bacon-tasty")), + SetEquals("shared_accounts", "bar-subdomain", "foo-subdomain"), + Attribute("terraform_provider", Equals("default")), + ), + }}) + }) + + t.Run("with terraform_workflow_tool defaulted", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + + testSteps(t, []resource.TestStep{ + { + Config: fmt.Sprintf(` + resource "spacelift_module" "test" { + name = "test-module-%s" + administrative = true + branch = "master" + repository = "terraform-bacon-tasty" + } + data "spacelift_module" "test" { + module_id = spacelift_module.test.id + } + `, randomID), + Check: Resource( + "data.spacelift_module.test", + Attribute("workflow_tool", Equals("TERRAFORM_FOSS")), + ), + }, + }) + }) + + t.Run("with terraform_workflow_tool set", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + + testSteps(t, []resource.TestStep{ + { + Config: fmt.Sprintf(` + resource "spacelift_module" "test" { + name = "test-module-%s" + administrative = true + branch = "master" + repository = "terraform-bacon-tasty" + workflow_tool = "CUSTOM" + } + data "spacelift_module" "test" { + module_id = spacelift_module.test.id + } + `, randomID), + Check: Resource( + "data.spacelift_module.test", + Attribute("workflow_tool", Equals("CUSTOM")), + ), + }, + }) + }) } func TestModuleDataSpace(t *testing.T) { diff --git a/spacelift/data_stack.go b/spacelift/data_stack.go index cc062136..301cbb78 100644 --- a/spacelift/data_stack.go +++ b/spacelift/data_stack.go @@ -378,6 +378,11 @@ func dataStack() *schema.Resource { Description: "Terraform version to use", Computed: true, }, + "terraform_workflow_tool": { + Type: schema.TypeString, + Description: "Defines the tool that will be used to execute the workflow. This can be one of `OPEN_TOFU`, `TERRAFORM_FOSS` or `CUSTOM`.", + Computed: true, + }, "terraform_workspace": { Type: schema.TypeString, Description: "Terraform workspace to select", @@ -455,6 +460,7 @@ func dataStackRead(ctx context.Context, d *schema.ResourceData, meta interface{} d.Set("terraform_workspace", stack.VendorConfig.Terraform.Workspace) d.Set("terraform_smart_sanitization", stack.VendorConfig.Terraform.UseSmartSanitization) d.Set("terraform_external_state_access", stack.VendorConfig.Terraform.ExternalStateAccessEnabled) + d.Set("terraform_workflow_tool", stack.VendorConfig.Terraform.WorkflowTool) } if workerPool := stack.WorkerPool; workerPool != nil { diff --git a/spacelift/data_stack_test.go b/spacelift/data_stack_test.go index 7cd50af2..b4f86d6b 100644 --- a/spacelift/data_stack_test.go +++ b/spacelift/data_stack_test.go @@ -263,6 +263,55 @@ func TestStackData(t *testing.T) { ), }}) }) + + t.Run("with terraform_workflow_tool defaulted", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + + testSteps(t, []resource.TestStep{ + { + Config: fmt.Sprintf(` + resource "spacelift_stack" "test" { + branch = "master" + name = "Provider test stack workflow_tool default %s" + project_root = "root" + repository = "demo" + } + data "spacelift_stack" "test" { + stack_id = spacelift_stack.test.id + } + `, randomID), + Check: Resource( + "data.spacelift_stack.test", + Attribute("terraform_workflow_tool", Equals("TERRAFORM_FOSS")), + ), + }, + }) + }) + + t.Run("with terraform_workflow_tool set", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + + testSteps(t, []resource.TestStep{ + { + Config: fmt.Sprintf(` + resource "spacelift_stack" "test" { + branch = "master" + name = "Provider test stack workflow_tool default %s" + project_root = "root" + repository = "demo" + terraform_workflow_tool = "CUSTOM" + } + data "spacelift_stack" "test" { + stack_id = spacelift_stack.test.id + } + `, randomID), + Check: Resource( + "data.spacelift_stack.test", + Attribute("terraform_workflow_tool", Equals("CUSTOM")), + ), + }, + }) + }) } func TestStackDataSpace(t *testing.T) { diff --git a/spacelift/internal/structs/module.go b/spacelift/internal/structs/module.go index 120bfff9..32d9c72f 100644 --- a/spacelift/internal/structs/module.go +++ b/spacelift/internal/structs/module.go @@ -26,6 +26,7 @@ type Module struct { WorkerPool *struct { ID string `graphql:"id"` } `graphql:"workerPool"` + WorkflowTool *string `graphql:"workflowTool"` } // ExportVCSSettings exports VCS settings into Terraform schema. diff --git a/spacelift/internal/structs/module_input.go b/spacelift/internal/structs/module_input.go index 3466b332..e51f6ea8 100644 --- a/spacelift/internal/structs/module_input.go +++ b/spacelift/internal/structs/module_input.go @@ -11,6 +11,7 @@ type ModuleCreateInput struct { Repository graphql.String `json:"repository"` TerraformProvider *graphql.String `json:"terraformProvider"` Space *graphql.String `json:"space"` + WorkflowTool *graphql.String `json:"workflowTool"` } // ModuleUpdateInput represents the input required to update a Module. @@ -43,4 +44,5 @@ type ModuleUpdateV2Input struct { SharedAccounts *[]graphql.String `json:"sharedAccounts"` Space *graphql.String `json:"space"` WorkerPool *graphql.ID `json:"workerPool"` + WorkflowTool *graphql.String `json:"workflowTool"` } diff --git a/spacelift/internal/structs/stack.go b/spacelift/internal/structs/stack.go index 8ff60d2c..a0f8ec57 100644 --- a/spacelift/internal/structs/stack.go +++ b/spacelift/internal/structs/stack.go @@ -78,6 +78,7 @@ type Stack struct { Terraform struct { UseSmartSanitization bool `graphql:"useSmartSanitization"` Version *string `graphql:"version"` + WorkflowTool *string `graphql:"workflowTool"` Workspace *string `graphql:"workspace"` ExternalStateAccessEnabled bool `graphql:"externalStateAccessEnabled"` } `graphql:"... on StackConfigVendorTerraform"` @@ -222,6 +223,7 @@ func PopulateStack(d *schema.ResourceData, stack *Stack) error { default: d.Set("terraform_smart_sanitization", stack.VendorConfig.Terraform.UseSmartSanitization) d.Set("terraform_version", stack.VendorConfig.Terraform.Version) + d.Set("terraform_workflow_tool", stack.VendorConfig.Terraform.WorkflowTool) d.Set("terraform_workspace", stack.VendorConfig.Terraform.Workspace) d.Set("terraform_external_state_access", stack.VendorConfig.Terraform.ExternalStateAccessEnabled) } diff --git a/spacelift/internal/structs/stack_input.go b/spacelift/internal/structs/stack_input.go index e56992cd..5b1305c7 100644 --- a/spacelift/internal/structs/stack_input.go +++ b/spacelift/internal/structs/stack_input.go @@ -82,6 +82,7 @@ type TerragruntInput struct { type TerraformInput struct { UseSmartSanitization *graphql.Boolean `json:"useSmartSanitization"` Version *graphql.String `json:"version"` + WorkflowTool *graphql.String `json:"workflowTool"` Workspace *graphql.String `json:"workspace"` ExternalStateAccessEnabled *graphql.Boolean `json:"externalStateAccessEnabled"` } diff --git a/spacelift/resource_module.go b/spacelift/resource_module.go index 5c2a8c79..93bcd2a8 100644 --- a/spacelift/resource_module.go +++ b/spacelift/resource_module.go @@ -202,6 +202,12 @@ func resourceModule() *schema.Resource { Description: "ID of the worker pool to use. NOTE: worker_pool_id is required when using a self-hosted instance of Spacelift.", Optional: true, }, + "workflow_tool": { + Type: schema.TypeString, + Description: "Defines the tool that will be used to execute the workflow. This can be one of `OPEN_TOFU`, `TERRAFORM_FOSS` or `CUSTOM`. Defaults to `TERRAFORM_FOSS`.", + Optional: true, + Computed: true, + }, }, } } @@ -281,6 +287,10 @@ func resourceModuleRead(ctx context.Context, d *schema.ResourceData, meta interf d.Set("worker_pool_id", nil) } + if workflowTool := module.WorkflowTool; workflowTool != nil { + d.Set("workflow_tool", *workflowTool) + } + return nil } @@ -385,6 +395,10 @@ func moduleCreateInput(d *schema.ResourceData) structs.ModuleCreateInput { ret.TerraformProvider = toOptionalString(terraformProvider) } + if workflowTool, ok := d.GetOk("workflow_tool"); ok { + ret.WorkflowTool = toOptionalString(workflowTool) + } + return ret } @@ -475,5 +489,9 @@ func moduleUpdateV2Input(d *schema.ResourceData) structs.ModuleUpdateV2Input { ret.WorkerPool = graphql.NewID(workerPoolID) } + if workflowTool, ok := d.GetOk("workflow_tool"); ok { + ret.WorkflowTool = toOptionalString(workflowTool) + } + return ret } diff --git a/spacelift/resource_module_test.go b/spacelift/resource_module_test.go index 95edeabe..dc2cefc8 100644 --- a/spacelift/resource_module_test.go +++ b/spacelift/resource_module_test.go @@ -171,6 +171,92 @@ func TestModuleResource(t *testing.T) { }, }) }) + + t.Run("with workflow_tool", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + + testSteps(t, []resource.TestStep{ + // Defaults to TERRAFORM_FOSS + { + Config: fmt.Sprintf(` + resource "spacelift_module" "workflow_tool" { + name = "workflow-tool-%s" + branch = "master" + repository = "terraform-bacon-tasty" + terraform_provider = "papaya" + } + `, randomID), + Check: Resource( + "spacelift_module.workflow_tool", + Attribute("workflow_tool", Equals("TERRAFORM_FOSS")), + ), + }, + // Can update the tool + { + Config: fmt.Sprintf(` + resource "spacelift_module" "workflow_tool" { + name = "workflow-tool-%s" + branch = "master" + repository = "terraform-bacon-tasty" + terraform_provider = "papaya" + workflow_tool = "CUSTOM" + } + `, randomID), + Check: Resource( + "spacelift_module.workflow_tool", + Attribute("workflow_tool", Equals("CUSTOM")), + ), + }, + // Can create a module with OPEN_TOFU + { + Config: fmt.Sprintf(` + resource "spacelift_module" "workflow_tool_open_tofu" { + name = "workflow-tool-open-tofu-%s" + branch = "master" + repository = "terraform-bacon-tasty" + terraform_provider = "papaya" + workflow_tool = "OPEN_TOFU" + } + `, randomID), + Check: Resource( + "spacelift_module.workflow_tool_open_tofu", + Attribute("workflow_tool", Equals("OPEN_TOFU")), + ), + }, + // Can create a module with TERRAFORM_FOSS + { + Config: fmt.Sprintf(` + resource "spacelift_module" "workflow_tool_terraform_foss" { + name = "workflow-tool-terraform-foss-%s" + branch = "master" + repository = "terraform-bacon-tasty" + terraform_provider = "papaya" + workflow_tool = "TERRAFORM_FOSS" + } + `, randomID), + Check: Resource( + "spacelift_module.workflow_tool_terraform_foss", + Attribute("workflow_tool", Equals("TERRAFORM_FOSS")), + ), + }, + // Can create a module with CUSTOM + { + Config: fmt.Sprintf(` + resource "spacelift_module" "workflow_tool_custom" { + name = "workflow-tool-custom-%s" + branch = "master" + repository = "terraform-bacon-tasty" + terraform_provider = "papaya" + workflow_tool = "CUSTOM" + } + `, randomID), + Check: Resource( + "spacelift_module.workflow_tool_custom", + Attribute("workflow_tool", Equals("CUSTOM")), + ), + }, + }) + }) } func TestModuleResourceSpace(t *testing.T) { diff --git a/spacelift/resource_stack.go b/spacelift/resource_stack.go index 09bd2dba..07127116 100644 --- a/spacelift/resource_stack.go +++ b/spacelift/resource_stack.go @@ -43,7 +43,7 @@ func resourceStack() *schema.Resource { }, "ansible": { Type: schema.TypeList, - ConflictsWith: []string{"cloudformation", "kubernetes", "pulumi", "terraform_version", "terraform_workspace", "terragrunt"}, + ConflictsWith: []string{"cloudformation", "kubernetes", "pulumi", "terraform_version", "terraform_workflow_tool", "terraform_workspace", "terragrunt"}, Description: "Ansible-specific configuration. Presence means this Stack is an Ansible Stack.", Optional: true, MaxItems: 1, @@ -233,7 +233,7 @@ func resourceStack() *schema.Resource { }, "cloudformation": { Type: schema.TypeList, - ConflictsWith: []string{"ansible", "kubernetes", "pulumi", "terraform_version", "terraform_workspace", "terragrunt"}, + ConflictsWith: []string{"ansible", "kubernetes", "pulumi", "terraform_version", "terraform_workflow_tool", "terraform_workspace", "terragrunt"}, Description: "CloudFormation-specific configuration. Presence means this Stack is a CloudFormation Stack.", Optional: true, MaxItems: 1, @@ -334,7 +334,7 @@ func resourceStack() *schema.Resource { }, "kubernetes": { Type: schema.TypeList, - ConflictsWith: []string{"ansible", "cloudformation", "pulumi", "terraform_version", "terraform_workspace", "terragrunt"}, + ConflictsWith: []string{"ansible", "cloudformation", "pulumi", "terraform_version", "terraform_workflow_tool", "terraform_workspace", "terragrunt"}, Description: "Kubernetes-specific configuration. Presence means this Stack is a Kubernetes Stack.", Optional: true, MaxItems: 1, @@ -387,7 +387,7 @@ func resourceStack() *schema.Resource { }, "pulumi": { Type: schema.TypeList, - ConflictsWith: []string{"ansible", "cloudformation", "kubernetes", "terraform_version", "terraform_workspace", "terragrunt"}, + ConflictsWith: []string{"ansible", "cloudformation", "kubernetes", "terraform_version", "terraform_workflow_tool", "terraform_workspace", "terragrunt"}, Description: "Pulumi-specific configuration. Presence means this Stack is a Pulumi Stack.", Optional: true, MaxItems: 1, @@ -487,6 +487,12 @@ func resourceStack() *schema.Resource { Optional: true, DiffSuppressFunc: onceTheVersionIsSetDoNotUnset, }, + "terraform_workflow_tool": { + Type: schema.TypeString, + Description: "Defines the tool that will be used to execute the workflow. This can be one of `OPEN_TOFU`, `TERRAFORM_FOSS` or `CUSTOM`. Defaults to `TERRAFORM_FOSS`.", + Optional: true, + Computed: true, + }, "terraform_workspace": { Type: schema.TypeString, Description: "Terraform workspace to select", @@ -494,7 +500,7 @@ func resourceStack() *schema.Resource { }, "terragrunt": { Type: schema.TypeList, - ConflictsWith: []string{"ansible", "cloudformation", "kubernetes", "pulumi", "terraform_version", "terraform_workspace"}, + ConflictsWith: []string{"ansible", "cloudformation", "kubernetes", "pulumi", "terraform_version", "terraform_workflow_tool", "terraform_workspace"}, Description: "Terragrunt-specific configuration. Presence means this Stack is an Terragrunt Stack.", Optional: true, MaxItems: 1, @@ -775,12 +781,6 @@ func stackInput(d *schema.ResourceData) structs.StackInput { ret.RunnerImage = toOptionalString(runnerImage) } - if terraformVersion, ok := d.GetOk("terraform_version"); ok { - ret.VendorConfig = &structs.VendorConfigInput{Terraform: &structs.TerraformInput{ - Version: toOptionalString(terraformVersion), - }} - } - ret.VendorConfig = getVendorConfig(d) if workerPoolID, ok := d.GetOk("worker_pool_id"); ok { @@ -850,6 +850,10 @@ func getVendorConfig(d *schema.ResourceData) *structs.VendorConfigInput { terraformConfig.Version = toOptionalString(terraformVersion) } + if terraformWorkflowTool, ok := d.GetOk("terraform_workflow_tool"); ok { + terraformConfig.WorkflowTool = toOptionalString(terraformWorkflowTool) + } + if terraformWorkspace, ok := d.GetOk("terraform_workspace"); ok { terraformConfig.Workspace = toOptionalString(terraformWorkspace) } diff --git a/spacelift/resource_stack_test.go b/spacelift/resource_stack_test.go index 94358ebf..dd795d6b 100644 --- a/spacelift/resource_stack_test.go +++ b/spacelift/resource_stack_test.go @@ -1203,6 +1203,92 @@ func TestStackResourceSpace(t *testing.T) { }, }) }) + + t.Run("with terraform_workflow_tool", func(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + + testSteps(t, []resource.TestStep{ + // Check that the tool defaults correctly + { + Config: fmt.Sprintf(` + resource "spacelift_stack" "terraform_workflow_tool" { + branch = "master" + name = "Provider test stack workflow_tool default %s" + project_root = "root" + repository = "demo" + } + `, randomID), + Check: Resource( + "spacelift_stack.terraform_workflow_tool", + Attribute("terraform_workflow_tool", Equals("TERRAFORM_FOSS")), + ), + }, + // Check we can update it to a different tool + { + Config: fmt.Sprintf(` + resource "spacelift_stack" "terraform_workflow_tool" { + branch = "master" + name = "Provider test stack workflow_tool default %s" + project_root = "root" + repository = "demo" + terraform_workflow_tool = "CUSTOM" + } + `, randomID), + Check: Resource( + "spacelift_stack.terraform_workflow_tool", + Attribute("terraform_workflow_tool", Equals("CUSTOM")), + ), + }, + // Check we can create an OPEN_TOFU stack + { + Config: fmt.Sprintf(` + resource "spacelift_stack" "terraform_workflow_tool_open_tofu" { + branch = "master" + name = "Provider test stack workflow_tool OPEN_TOFU %s" + project_root = "root" + repository = "demo" + terraform_workflow_tool = "OPEN_TOFU" + } + `, randomID), + Check: Resource( + "spacelift_stack.terraform_workflow_tool_open_tofu", + Attribute("terraform_workflow_tool", Equals("OPEN_TOFU")), + ), + }, + // Check we can create a TERRAFORM_FOSS stack + { + Config: fmt.Sprintf(` + resource "spacelift_stack" "terraform_workflow_tool_foss" { + branch = "master" + name = "Provider test stack workflow_tool TERRAFORM_FOSS %s" + project_root = "root" + repository = "demo" + terraform_workflow_tool = "TERRAFORM_FOSS" + } + `, randomID), + Check: Resource( + "spacelift_stack.terraform_workflow_tool_foss", + Attribute("terraform_workflow_tool", Equals("TERRAFORM_FOSS")), + ), + }, + // Check we can create a CUSTOM stack + { + Config: fmt.Sprintf(` + resource "spacelift_stack" "terraform_workflow_tool_custom" { + branch = "master" + name = "Provider test stack workflow_tool CUSTOM %s" + project_root = "root" + repository = "demo" + terraform_workflow_tool = "CUSTOM" + } + `, randomID), + Check: Resource( + "spacelift_stack.terraform_workflow_tool_custom", + Attribute("terraform_workflow_tool", Equals("CUSTOM")), + ), + }, + }) + }) } // getConfig returns a stack config with injected vendor config