diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a14b221..b2238018 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- `scalr_workspace`: deleted attribute `terragrunt_version` ([#390](https://github.com/Scalr/terraform-provider-scalr/pull/390)) +- `scalr_workspace`: deleted attribute `terragrunt_use_run_all` ([#390](https://github.com/Scalr/terraform-provider-scalr/pull/390)) +- `scalr_workspace`: added attribute `terragrunt` ([#390](https://github.com/Scalr/terraform-provider-scalr/pull/390)) + ### Added ## [2.4.0] - 2025-01-24 diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index 2d88202f..cc5522f9 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -61,8 +61,7 @@ data "scalr_workspace" "example2" { - `vcs_provider_id` (String) The identifier of a VCS provider in the format `vcs-`. - `vcs_repo` (List of Object) If a workspace is linked to a VCS repository this block shows the details, otherwise `{}` (see [below for nested schema](#nestedatt--vcs_repo)) - `working_directory` (String) A relative path that Terraform will execute within. -- `terragrunt_version` (String) The version of Terragrunt the workspace performs runs on. -- `terragrunt_use_run_all` (Boolean) Indicates whether the workspace uses `terragrunt run-all`. +- `terragrunt` (List of Object) If a workspace is linked to a Terragrunt configuration this block shows the details, otherwise `{}` (see [below for nested schema](#nestedatt--terragrunt)) ### Nested Schema for `created_by` @@ -95,3 +94,13 @@ Read-Only: - `identifier` (String) The reference to the VCS repository in the format `:org/:repo`, this refers to the organization and repository in your VCS provider. - `ingress_submodules` (Boolean) Designates whether to clone git submodules of the VCS repository. - `path` (String) Path within the repo, if any. + + + +### Nested Schema for `terragrunt` + +Read-Only: + +- `version` (String) The version of Terragrunt used for this workspace. +- `use_run_all` (Boolean) Boolean indicates if Terragrunt will use `run-all` command. +- `include_external_dependencies` (Boolean) Boolean indicates if Terragrunt will include external dependencies. diff --git a/docs/resources/workspace.md b/docs/resources/workspace.md index 23dd9de9..1fac9f08 100644 --- a/docs/resources/workspace.md +++ b/docs/resources/workspace.md @@ -168,8 +168,7 @@ resource "scalr_workspace" "example-b" { - `ssh_key_id` (String) The identifier of the SSH key to use for the workspace. - `tag_ids` (Set of String) List of tag IDs associated with the workspace. - `terraform_version` (String) The version of Terraform to use for this workspace. Defaults to the latest available version. -- `terragrunt_use_run_all` (Boolean) Indicates whether the workspace uses `terragrunt run-all`. -- `terragrunt_version` (String) The version of Terragrunt the workspace performs runs on. +- `terragrunt` (Block List) Settings for the workspace's Terragrunt configuration. (see [below for nested schema](#nestedblock--terragrunt)) - `type` (String) The type of the Scalr Workspace environment, available options: `production`, `staging`, `testing`, `development`, `unmapped`. - `var_files` (List of String) A list of paths to the `.tfvars` file(s) to be used as part of the workspace configuration. - `vcs_provider_id` (String) ID of VCS provider - required if vcs-repo present and vice versa, in the format `vcs-`. @@ -206,6 +205,19 @@ Optional: - `alias` (String) The alias of provider configuration. + +### Nested Schema for `terragrunt` + +Required: + +- `version` (String) The version of Terragrunt the workspace performs runs on. + +Optional: + +- `include_external_dependencies` (Boolean) Indicates whether the workspace includes external dependencies. +- `use_run_all` (Boolean) Indicates whether the workspace uses `terragrunt run-all`. + + ### Nested Schema for `vcs_repo` diff --git a/go.mod b/go.mod index e81b5134..73138c4b 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 github.com/hashicorp/terraform-plugin-testing v1.11.0 github.com/hashicorp/terraform-svchost v0.1.1 - github.com/scalr/go-scalr v0.0.0-20250115101005-ccf67688eb14 + github.com/scalr/go-scalr v0.0.0-20250130154226-fa553e85a1fc ) require ( diff --git a/go.sum b/go.sum index 5ebfd654..04b5a1f1 100644 --- a/go.sum +++ b/go.sum @@ -201,8 +201,8 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= -github.com/scalr/go-scalr v0.0.0-20250115101005-ccf67688eb14 h1:lzee+F20vQN/iQA0eQZGS1ZXtf7la1ak3cdZdo739BI= -github.com/scalr/go-scalr v0.0.0-20250115101005-ccf67688eb14/go.mod h1:p34SHb25YRvbgft7SUjSDYESeoQhWzAlxGXId/BbaSE= +github.com/scalr/go-scalr v0.0.0-20250130154226-fa553e85a1fc h1:UwvZEI2YI7EmpIeEZeYviG4WsFPpsY0KioLz9Y50WE8= +github.com/scalr/go-scalr v0.0.0-20250130154226-fa553e85a1fc/go.mod h1:PKuZ6tEH/QfPk10pLtFCN7yYqYQ3przx/Yut1qbK48Q= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= diff --git a/internal/provider/data_source_scalr_workspace.go b/internal/provider/data_source_scalr_workspace.go index 6018b6c2..0244b1d4 100644 --- a/internal/provider/data_source_scalr_workspace.go +++ b/internal/provider/data_source_scalr_workspace.go @@ -94,16 +94,31 @@ func dataSourceScalrWorkspace() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "terragrunt_version": { - Description: "The version of Terragrunt the workspace performs runs on.", - Type: schema.TypeString, - Computed: true, - }, - "terragrunt_use_run_all": { - Description: "Indicates whether the workspace uses `terragrunt run-all`.", - Type: schema.TypeBool, + "terragrunt": { + Description: "List of terragrunt configurations in a workspace if set.", + Type: schema.TypeList, Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "version": { + Description: "The version of terragrunt.", + Type: schema.TypeString, + Computed: true, + }, + "use_run_all": { + Description: "Boolean indicates if terragrunt should run all commands.", + Type: schema.TypeBool, + Computed: true, + }, + "include_external_dependencies": { + Description: "Boolean indicates if terragrunt should include external dependencies.", + Type: schema.TypeBool, + Computed: true, + }, + }, + }, }, + "iac_platform": { Description: "The IaC platform used for this workspace.", Type: schema.TypeString, @@ -175,7 +190,6 @@ func dataSourceScalrWorkspace() *schema.Resource { }, }, }, - "vcs_repo": { Description: "If a workspace is linked to a VCS repository this block shows the details, otherwise `{}`", Type: schema.TypeList, @@ -284,8 +298,6 @@ func dataSourceScalrWorkspaceRead(ctx context.Context, d *schema.ResourceData, m _ = d.Set("operations", workspace.Operations) _ = d.Set("execution_mode", workspace.ExecutionMode) _ = d.Set("terraform_version", workspace.TerraformVersion) - _ = d.Set("terragrunt_version", workspace.TerragruntVersion) - _ = d.Set("terragrunt_use_run_all", workspace.TerragruntUseRunAll) _ = d.Set("iac_platform", workspace.IaCPlatform) _ = d.Set("type", workspace.EnvironmentType) _ = d.Set("working_directory", workspace.WorkingDirectory) @@ -322,6 +334,17 @@ func dataSourceScalrWorkspaceRead(ctx context.Context, d *schema.ResourceData, m } _ = d.Set("vcs_repo", vcsRepo) + var terragrunt []interface{} + if workspace.Terragrunt != nil { + terragruntConfig := map[string]interface{}{ + "version": workspace.Terragrunt.Version, + "use_run_all": workspace.Terragrunt.UseRunAll, + "include_external_dependencies": workspace.Terragrunt.IncludeExternalDependencies, + } + terragrunt = append(terragrunt, terragruntConfig) + } + _ = d.Set("terragrunt", terragrunt) + var hooks []interface{} if workspace.Hooks != nil { hooks = append(hooks, map[string]interface{}{ diff --git a/internal/provider/workspace_models.go b/internal/provider/workspace_models.go index bde62e3a..b55a7919 100644 --- a/internal/provider/workspace_models.go +++ b/internal/provider/workspace_models.go @@ -21,6 +21,14 @@ var ( "trigger_prefixes": types.ListType{ElemType: types.StringType}, }, } + terragruntElementType = types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "version": types.StringType, + "use_run_all": types.BoolType, + "include_external_dependencies": types.BoolType, + }, + } + providerConfigurationElementType = types.ObjectType{ AttrTypes: map[string]attr.Type{ "id": types.StringType, @@ -60,8 +68,7 @@ type workspaceResourceModel struct { SSHKeyID types.String `tfsdk:"ssh_key_id"` TagIDs types.Set `tfsdk:"tag_ids"` TerraformVersion types.String `tfsdk:"terraform_version"` - TerragruntUseRunAll types.Bool `tfsdk:"terragrunt_use_run_all"` - TerragruntVersion types.String `tfsdk:"terragrunt_version"` + Terragrunt types.List `tfsdk:"terragrunt"` Type types.String `tfsdk:"type"` VCSProviderID types.String `tfsdk:"vcs_provider_id"` VCSRepo types.List `tfsdk:"vcs_repo"` @@ -69,6 +76,12 @@ type workspaceResourceModel struct { WorkingDirectory types.String `tfsdk:"working_directory"` } +type terragruntModel struct { + Version types.String `tfsdk:"version"` + UseRunAll types.Bool `tfsdk:"use_run_all"` + IncludeExternalDependencies types.Bool `tfsdk:"include_external_dependencies"` +} + type vcsRepoModel struct { Branch types.String `tfsdk:"branch"` DryRunsEnabled types.Bool `tfsdk:"dry_runs_enabled"` @@ -123,8 +136,7 @@ func workspaceResourceModelFromAPI( SSHKeyID: types.StringNull(), TagIDs: types.SetNull(types.StringType), TerraformVersion: types.StringValue(ws.TerraformVersion), - TerragruntUseRunAll: types.BoolValue(ws.TerragruntUseRunAll), - TerragruntVersion: types.StringValue(ws.TerragruntVersion), + Terragrunt: types.ListNull(terragruntElementType), Type: types.StringValue(string(ws.EnvironmentType)), VCSProviderID: types.StringNull(), VCSRepo: types.ListNull(vcsRepoElementType), @@ -180,6 +192,17 @@ func workspaceResourceModelFromAPI( model.VCSRepo = repoValue } + if ws.Terragrunt != nil { + terragrunt := terragruntModel{ + Version: types.StringValue(ws.Terragrunt.Version), + UseRunAll: types.BoolValue(ws.Terragrunt.UseRunAll), + IncludeExternalDependencies: types.BoolValue(ws.Terragrunt.IncludeExternalDependencies), + } + terragruntValue, d := types.ListValueFrom(ctx, terragruntElementType, []terragruntModel{terragrunt}) + diags.Append(d...) + model.Terragrunt = terragruntValue + } + if ws.CreatedBy != nil { createdBy := []userModel{*userModelFromAPI(ws.CreatedBy)} createdByValue, d := types.ListValueFrom(ctx, userElementType, createdBy) diff --git a/internal/provider/workspace_resource.go b/internal/provider/workspace_resource.go index 751571fb..ab7e51ad 100644 --- a/internal/provider/workspace_resource.go +++ b/internal/provider/workspace_resource.go @@ -79,7 +79,6 @@ func (r *workspaceResource) Create(ctx context.Context, req resource.CreateReque IacPlatform: ptr(scalr.WorkspaceIaCPlatform(plan.IaCPlatform.ValueString())), Name: plan.Name.ValueStringPointer(), Operations: plan.Operations.ValueBoolPointer(), - TerragruntUseRunAll: plan.TerragruntUseRunAll.ValueBoolPointer(), VarFiles: varFiles, WorkingDirectory: plan.WorkingDirectory.ValueStringPointer(), Environment: &scalr.Environment{ @@ -91,10 +90,6 @@ func (r *workspaceResource) Create(ctx context.Context, req resource.CreateReque opts.TerraformVersion = plan.TerraformVersion.ValueStringPointer() } - if !plan.TerragruntVersion.IsUnknown() && !plan.TerragruntVersion.IsNull() { - opts.TerragruntVersion = plan.TerragruntVersion.ValueStringPointer() - } - if !plan.RunOperationTimeout.IsUnknown() && !plan.RunOperationTimeout.IsNull() { opts.RunOperationTimeout = ptr(int(plan.RunOperationTimeout.ValueInt32())) } @@ -144,6 +139,20 @@ func (r *workspaceResource) Create(ctx context.Context, req resource.CreateReque } } + if !plan.Terragrunt.IsUnknown() && !plan.Terragrunt.IsNull() { + var terragrunt []terragruntModel + resp.Diagnostics.Append(plan.Terragrunt.ElementsAs(ctx, &terragrunt, false)...) + + if len(terragrunt) > 0 { + terr := terragrunt[0] + opts.Terragrunt = &scalr.WorkspaceTerragruntOptions{ + Version: terr.Version.ValueString(), + UseRunAll: terr.UseRunAll.ValueBoolPointer(), + IncludeExternalDependencies: terr.IncludeExternalDependencies.ValueBoolPointer(), + } + } + } + if !plan.Hooks.IsUnknown() && !plan.Hooks.IsNull() { var hooks []hooksModel resp.Diagnostics.Append(plan.Hooks.ElementsAs(ctx, &hooks, false)...) @@ -355,14 +364,6 @@ func (r *workspaceResource) Update(ctx context.Context, req resource.UpdateReque opts.TerraformVersion = plan.TerraformVersion.ValueStringPointer() } - if !plan.TerragruntUseRunAll.Equal(state.TerragruntUseRunAll) { - opts.TerragruntUseRunAll = plan.TerragruntUseRunAll.ValueBoolPointer() - } - - if !plan.TerragruntVersion.Equal(state.TerragruntVersion) && !plan.TerragruntVersion.IsNull() { - opts.TerragruntVersion = plan.TerragruntVersion.ValueStringPointer() - } - if !plan.Type.Equal(state.Type) { opts.EnvironmentType = ptr(scalr.WorkspaceEnvironmentType(plan.Type.ValueString())) } @@ -410,6 +411,20 @@ func (r *workspaceResource) Update(ctx context.Context, req resource.UpdateReque } } + if !plan.Terragrunt.IsNull() { + var terragrunt []terragruntModel + resp.Diagnostics.Append(plan.Terragrunt.ElementsAs(ctx, &terragrunt, false)...) + + if len(terragrunt) > 0 { + terr := terragrunt[0] + opts.Terragrunt = &scalr.WorkspaceTerragruntOptions{ + Version: terr.Version.ValueString(), + UseRunAll: terr.UseRunAll.ValueBoolPointer(), + IncludeExternalDependencies: terr.IncludeExternalDependencies.ValueBoolPointer(), + } + } + } + if !plan.Hooks.Equal(state.Hooks) { var hooks []hooksModel resp.Diagnostics.Append(plan.Hooks.ElementsAs(ctx, &hooks, false)...) diff --git a/internal/provider/workspace_schemas.go b/internal/provider/workspace_schemas.go index e40efe7d..4db24cb0 100644 --- a/internal/provider/workspace_schemas.go +++ b/internal/provider/workspace_schemas.go @@ -2,6 +2,7 @@ package provider import ( "context" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" @@ -26,7 +27,6 @@ import ( func workspaceResourceSchema(ctx context.Context) *schema.Schema { emptyStringList, _ := types.ListValueFrom(ctx, types.StringType, []string{}) emptyStringSet, _ := types.SetValueFrom(ctx, types.StringType, []string{}) - asteriskStringSet, _ := types.SetValueFrom(ctx, types.StringType, []string{"*"}) return &schema.Schema{ MarkdownDescription: "Manages the state of workspaces in Scalr.", @@ -117,20 +117,6 @@ func workspaceResourceSchema(ctx context.Context) *schema.Schema { stringplanmodifier.UseStateForUnknown(), }, }, - "terragrunt_version": schema.StringAttribute{ - MarkdownDescription: "The version of Terragrunt the workspace performs runs on.", - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, - }, - "terragrunt_use_run_all": schema.BoolAttribute{ - MarkdownDescription: "Indicates whether the workspace uses `terragrunt run-all`.", - Optional: true, - Computed: true, - Default: booldefault.StaticBool(false), - }, "iac_platform": schema.StringAttribute{ MarkdownDescription: "The IaC platform to use for this workspace. Valid values are `terraform` and `opentofu`. Defaults to `terraform`.", Optional: true, @@ -218,10 +204,12 @@ func workspaceResourceSchema(ctx context.Context) *schema.Schema { ElementType: types.StringType, Optional: true, Computed: true, - Default: setdefault.StaticValue(asteriskStringSet), Validators: []validator.Set{ setvalidator.ValueStringsAre(validation.StringIsNotWhiteSpace()), }, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, }, }, Blocks: map[string]schema.Block{ @@ -339,6 +327,32 @@ func workspaceResourceSchema(ctx context.Context) *schema.Schema { }, }, }, + "terragrunt": schema.ListNestedBlock{ + MarkdownDescription: "Settings for the workspace's Terragrunt configuration.", + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "version": schema.StringAttribute{ + MarkdownDescription: "The version of Terragrunt the workspace performs runs on.", + Required: true, + }, + "use_run_all": schema.BoolAttribute{ + MarkdownDescription: "Indicates whether the workspace uses `terragrunt run-all`.", + Default: booldefault.StaticBool(false), + Optional: true, + Computed: true, + }, + "include_external_dependencies": schema.BoolAttribute{ + MarkdownDescription: "Indicates whether the workspace includes external dependencies.", + Default: booldefault.StaticBool(false), + Optional: true, + Computed: true, + }, + }, + }, + Validators: []validator.List{ + listvalidator.SizeAtMost(1), + }, + }, }, } } diff --git a/templates/data-sources/workspace.md.tmpl b/templates/data-sources/workspace.md.tmpl index 7f24dd17..36a72b99 100644 --- a/templates/data-sources/workspace.md.tmpl +++ b/templates/data-sources/workspace.md.tmpl @@ -52,8 +52,7 @@ hidden: false - `vcs_provider_id` (String) The identifier of a VCS provider in the format `vcs-`. - `vcs_repo` (List of Object) If a workspace is linked to a VCS repository this block shows the details, otherwise `{}` (see [below for nested schema](#nestedatt--vcs_repo)) - `working_directory` (String) A relative path that Terraform will execute within. -- `terragrunt_version` (String) The version of Terragrunt the workspace performs runs on. -- `terragrunt_use_run_all` (Boolean) Indicates whether the workspace uses `terragrunt run-all`. +- `terragrunt` (List of Object) If a workspace is linked to a Terragrunt configuration this block shows the details, otherwise `{}` (see [below for nested schema](#nestedatt--terragrunt)) ### Nested Schema for `created_by` @@ -86,3 +85,13 @@ Read-Only: - `identifier` (String) The reference to the VCS repository in the format `:org/:repo`, this refers to the organization and repository in your VCS provider. - `ingress_submodules` (Boolean) Designates whether to clone git submodules of the VCS repository. - `path` (String) Path within the repo, if any. + + + +### Nested Schema for `terragrunt` + +Read-Only: + +- `version` (String) The version of Terragrunt used for this workspace. +- `use_run_all` (Boolean) Boolean indicates if Terragrunt will use `run-all` command. +- `include_external_dependencies` (Boolean) Boolean indicates if Terragrunt will include external dependencies.