From 8e4fd3ec8101eceda5909f24a693edf29771ef46 Mon Sep 17 00:00:00 2001 From: Jonathan Johnson Date: Thu, 2 Dec 2021 12:58:13 -0600 Subject: [PATCH 01/31] add first pass of variable set provider documentation --- website/docs/r/varset.html.markdown | 118 ++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 website/docs/r/varset.html.markdown diff --git a/website/docs/r/varset.html.markdown b/website/docs/r/varset.html.markdown new file mode 100644 index 000000000..de875dd42 --- /dev/null +++ b/website/docs/r/varset.html.markdown @@ -0,0 +1,118 @@ +--- +layout: "tfe" +page_title: "Terraform Enterprise: tfe_variable_set" +sidebar_current: "docs-resource-tfe-variable-set" +description: |- + Manages variable sets. +--- + +# tfe_variable_set + +Creates, updates and destroys variable sets. + +## Example Usage + +Basic usage: + +```hcl +resource "tfe_organization" "test" { + name = "my-org-name" + email = "admin@company.com" +} + +resource "tfe_workspace" "test" { + name = "my-workspace-name" + organization = tfe_organization.test.id +} + +resource "tfe_variable_set" "test" { + name = "Test Varset" + description = "Some description." + global = false + organization = tfe_organization.test.id + workspaces = [tfe_workspace.test.id] +} + +resource "tfe_variable" "test" { + key = "seperate_variable" + value = "my_value_name" + category = "terraform" + description = "a useful description" + variable_set = tfe_variable_set.test.id +} + +resource "tfe_variable" "test" { + key = "another_variable" + value = "my_value_name" + category = "env" + description = "an environment variable" + variable_set = tfe_variable_set.test.id +} +``` + +Creating a global variable set: + +```hcl +resource "tfe_organization" "test" { + name = "my-org-name" + email = "admin@company.com" +} + +resource "tfe_variable_set" "test" { + name = "Global Varset" + description = "Variable set applied to all workspaces." + global = true + organization = tfe_organization.test.id +} + +resource "tfe_variable" "test" { + key = "seperate_variable" + value = "my_value_name" + category = "terraform" + description = "a useful description" + variable_set = tfe_variable_set.test.id +} + +resource "tfe_variable" "test" { + key = "another_variable" + value = "my_value_name" + category = "env" + description = "an environment variable" + variable_set = tfe_variable_set.test.id +} +``` + +Creating a variable set that is applied based on workspace tags: + +```hcl +resource "tfe_organization" "test" { + name = "my-org-name" + email = "admin@company.com" +} + +data "tfe_workspace_ids" "prod-apps" { + tag_names = ["prod", "app", "aws"] + organization = tfe_organization.test.id +} + +resource "tfe_variable_set" "test" { + name = "Tag Based Varset" + description = "Variable set applied to workspaces based on tag." + organization = tfe_organization.test.id + workspaces = tfe_workspace_ids.prod-apps.ids +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Name of the variable set. +* `description` - (Optional) Description of the variable set. +* `global` - (Optional) Whether or not the variable set applies to all workspaces in the organization. Defaults to `false`. +* `organization` - (Required) Name of the organization. +* `workspaces` - (Optional) IDs of the workspaces that use the variable set. + +## Attributes Reference + +* `id` - The ID of the variable. From 065b3b3e8f0f107d438e98b50080dec3843f6ad1 Mon Sep 17 00:00:00 2001 From: Jonathan Johnson Date: Thu, 2 Dec 2021 13:03:17 -0600 Subject: [PATCH 02/31] rename varset file and update variable resource --- website/docs/r/variable.html.markdown | 40 +++++++++++++++++-- ...ml.markdown => variable_set.html.markdown} | 20 +++++----- 2 files changed, 47 insertions(+), 13 deletions(-) rename website/docs/r/{varset.html.markdown => variable_set.html.markdown} (86%) diff --git a/website/docs/r/variable.html.markdown b/website/docs/r/variable.html.markdown index b502a87e0..28634cfa1 100644 --- a/website/docs/r/variable.html.markdown +++ b/website/docs/r/variable.html.markdown @@ -12,7 +12,7 @@ Creates, updates and destroys variables. ## Example Usage -Basic usage: +Basic usage for workspaces: ```hcl resource "tfe_organization" "test" { @@ -34,6 +34,38 @@ resource "tfe_variable" "test" { } ``` +Basic usage for variable sets: + +```hcl +resource "tfe_organization" "test" { + name = "my-org-name" + email = "admin@company.com" +} + +resource "tfe_variable_set" "test" { + name = "Test Varset" + description = "Some description." + global = false + organization = tfe_organization.test.id +} + +resource "tfe_variable" "test" { + key = "seperate_variable" + value = "my_value_name" + category = "terraform" + description = "a useful description" + variable_set_id = tfe_variable_set.test.id +} + +resource "tfe_variable" "test" { + key = "another_variable" + value = "my_value_name" + category = "env" + description = "an environment variable" + variable_set_id = tfe_variable_set.test.id +} +``` + ## Argument Reference The following arguments are supported: @@ -46,8 +78,10 @@ The following arguments are supported: * `hcl` - (Optional) Whether to evaluate the value of the variable as a string of HCL code. Has no effect for environment variables. Defaults to `false`. * `sensitive` - (Optional) Whether the value is sensitive. If true then the - variable is written once and not visible thereafter. Defaults to `false`. -* `workspace_id` - (Required) ID of the workspace that owns the variable. +variable is written once and not visible thereafter. Defaults to `false`. + * One of the following (Required) + * `workspace_id` - ID of the workspace that owns the variable. + * `variable_set_id` - ID of the variable set that owns the variable. ## Attributes Reference diff --git a/website/docs/r/varset.html.markdown b/website/docs/r/variable_set.html.markdown similarity index 86% rename from website/docs/r/varset.html.markdown rename to website/docs/r/variable_set.html.markdown index de875dd42..105060886 100644 --- a/website/docs/r/varset.html.markdown +++ b/website/docs/r/variable_set.html.markdown @@ -66,19 +66,19 @@ resource "tfe_variable_set" "test" { } resource "tfe_variable" "test" { - key = "seperate_variable" - value = "my_value_name" - category = "terraform" - description = "a useful description" - variable_set = tfe_variable_set.test.id + key = "seperate_variable" + value = "my_value_name" + category = "terraform" + description = "a useful description" + variable_set_id = tfe_variable_set.test.id } resource "tfe_variable" "test" { - key = "another_variable" - value = "my_value_name" - category = "env" - description = "an environment variable" - variable_set = tfe_variable_set.test.id + key = "another_variable" + value = "my_value_name" + category = "env" + description = "an environment variable" + variable_set_id = tfe_variable_set.test.id } ``` From e69468beefaf9b750645b343454917b3140bdb6c Mon Sep 17 00:00:00 2001 From: Jonathan Johnson Date: Thu, 2 Dec 2021 13:07:39 -0600 Subject: [PATCH 03/31] update variables data source for variable sets --- website/docs/d/variables.html.markdown | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/website/docs/d/variables.html.markdown b/website/docs/d/variables.html.markdown index cf4940a40..880c46db9 100644 --- a/website/docs/d/variables.html.markdown +++ b/website/docs/d/variables.html.markdown @@ -12,6 +12,8 @@ This data source is used to retrieve all variables defined in a specified worksp ## Example Usage +For workspace variables: + ```hcl data "tfe_workspace" "test" { name = "my-workspace-name" @@ -23,11 +25,25 @@ data "tfe_variables" "test" { } ``` +For variable set variables: + +```hcl +data "tfe_variable_set" "test" { + name = "my-variable-set-name" + organization = "my-org-name" +} + +data "tfe_variables" "test" { + variable_set_id = data.tfe_variable_set.test.id +} +``` + ## Argument Reference -The following arguments are supported: +One of following arguments are required: -* `workspace_id` - (Required) ID of the workspace. +* `workspace_id` - ID of the workspace. +* `variable_set_id` - ID of the workspace. ## Attributes Reference From 925bdd6fa3f3a1389509a8e2421da2cae0327902 Mon Sep 17 00:00:00 2001 From: Jonathan Johnson Date: Thu, 2 Dec 2021 13:13:34 -0600 Subject: [PATCH 04/31] add variable set data source --- website/docs/d/variable_sets.html.markdown | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 website/docs/d/variable_sets.html.markdown diff --git a/website/docs/d/variable_sets.html.markdown b/website/docs/d/variable_sets.html.markdown new file mode 100644 index 000000000..8fb31ff12 --- /dev/null +++ b/website/docs/d/variable_sets.html.markdown @@ -0,0 +1,39 @@ +--- +layout: "tfe" +page_title: "Terraform Enterprise: tfe_variable_set" +sidebar_current: "docs-datasource-tfe-variable-set" +description: |- + Get information on organization variable sets. +--- + +# Data Source: tfe_variable_set + +This data source is used to retrieve all variables defined in a specified workspace + +## Example Usage + +For workspace variables: + +```hcl +data "tfe_variable_set" "test" { + name = "my-variable-set-name" + organization = "my-org-name" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Name of the workspace. +* `organization` - (Required) Name of the organization. + +## Attributes Reference + +* `id` - The ID of the variable. +* `organization` - Name of the organization. +* `name` - Name of the variable set. +* `description` - Description of the variable set. +* `global` - Whether or not the variable set applies to all workspaces in the organization. +* `workspaces` - IDs of the workspaces that use the variable set. +* `variables` - IDs of the variables attached to the variable set. From 376ab1834b34c29b594ee1e087028fb72148bfd8 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Tue, 1 Mar 2022 13:16:34 -0500 Subject: [PATCH 05/31] variables sets without variables or workspaces --- tfe/resource_tfe_variable_set.go | 145 ++++++++++++++++++ tfe/resource_tfe_variable_set_test.go | 209 ++++++++++++++++++++++++++ 2 files changed, 354 insertions(+) create mode 100644 tfe/resource_tfe_variable_set.go create mode 100644 tfe/resource_tfe_variable_set_test.go diff --git a/tfe/resource_tfe_variable_set.go b/tfe/resource_tfe_variable_set.go new file mode 100644 index 000000000..f05a24131 --- /dev/null +++ b/tfe/resource_tfe_variable_set.go @@ -0,0 +1,145 @@ +package tfe + +import ( + "fmt" + "log" + "regexp" + + tfe "github.com/hashicorp/go-tfe" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var variableSetIdRegexp = regexp.MustCompile("varset-[a-zA-Z0-9]{16}$") + +func resourceTFEVariableSet() *schema.Resource { + return &schema.Resource{ + Create: resourceTFEVariableSetCreate, + Read: resourceTFEVariableSetRead, + Update: resourceTFEVariableSetUpdate, + Delete: resourceTFEVariableSetDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "global": { + Type: schema.TypeBool, + Optional: true, + Default: false, + ConflictsWith: []string{"workspaces"}, + }, + + "organization": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + /* + "workspaces": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + */ + }, + } +} + +func resourceTFEVariableSetCreate(d *schema.ResourceData, meta interface{}) error { + tfeClient := meta.(*tfe.Client) + + // Get the name and organization. + name := d.Get("name").(string) + organization := d.Get("organization").(string) + + // Create a new options struct. + options := tfe.VariableSetCreateOptions{ + Name: tfe.String(name), + Description: tfe.String(d.Get("description").(string)), + Global: tfe.Bool(d.Get("global").(bool)), + } + + variableSet, err := tfeClient.VariableSets.Create(ctx, organization, &options) + if err != nil { + return fmt.Errorf( + "Error creating variable set %s, for organization: %s: %v", name, organization, err) + } + + d.SetId(variableSet.ID) + + return resourceTFEVariableSetRead(d, meta) +} + +func resourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) error { + tfeClient := meta.(*tfe.Client) + + id := d.Id() + log.Printf("[DEBUG] Read configuration of variable set: %s", id) + variableSet, err := tfeClient.VariableSets.Read(ctx, id, nil) //&VariableSetReadOptions{VariableSetWorkspaces}) + if err != nil { + if err == tfe.ErrResourceNotFound { + log.Printf("[DEBUG] Variable set %s no longer exists", id) + d.SetId("") + return nil + } + return fmt.Errorf("Error reading configuration of variable set %s: %v", id, err) + } + + // Update the config. + d.Set("name", variableSet.Name) + d.Set("description", variableSet.Description) + d.Set("global", variableSet.Global) + d.Set("organization", variableSet.Organization) + //d.Set("workspaces", variableSet.Workspaces) + + return nil +} + +func resourceTFEVariableSetUpdate(d *schema.ResourceData, meta interface{}) error { + tfeClient := meta.(*tfe.Client) + id := d.Id() + + if d.HasChange("name") || d.HasChange("description") || d.HasChange("global") { + options := tfe.VariableSetUpdateOptions{ + Name: tfe.String(d.Get("name").(string)), + Description: tfe.String(d.Get("description").(string)), + Global: tfe.Bool(d.Get("global").(bool)), + } + + log.Printf("[DEBUG] Update variable set: %s", id) + _, err := tfeClient.VariableSets.Update(ctx, id, &options) + if err != nil { + return fmt.Errorf("Error updateing variable %s: %v", id, err) + } + } + + return resourceTFEVariableSetRead(d, meta) +} + +func resourceTFEVariableSetDelete(d *schema.ResourceData, meta interface{}) error { + tfeClient := meta.(*tfe.Client) + id := d.Id() + + log.Printf("[DEBUG] Delete variable set: %s", id) + err := tfeClient.VariableSets.Delete(ctx, id) + if err != nil { + if err == tfe.ErrResourceNotFound { + return nil + } + return fmt.Errorf("Error deleting variable set %s: %v", id, err) + } + + return nil +} diff --git a/tfe/resource_tfe_variable_set_test.go b/tfe/resource_tfe_variable_set_test.go new file mode 100644 index 000000000..c2454614d --- /dev/null +++ b/tfe/resource_tfe_variable_set_test.go @@ -0,0 +1,209 @@ +package tfe + +import ( + "fmt" + "math/rand" + "testing" + "time" + + tfe "github.com/hashicorp/go-tfe" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccTFEVariableSet_basic(t *testing.T) { + variableSet := &tfe.VariableSet{} + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckTFEVariableSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTFEVariableSet_basic(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEVariableSetEExists( + "tfe_variable_set.foobar", variableSet), + testAccCheckTFEVariableSetAttributes(variableSet), + resource.TestCheckResourceAttr( + "tfe_variable_set.foobar", "name", "foobar"), + resource.TestCheckResourceAttr( + "tfe_variable_set.foobar", "description", "a test variable set"), + resource.TestCheckResourceAttr( + "tfe_variable_set.foobar", "global", "false"), + ), + }, + }, + }) +} + +func TestAccTFEVariableSet_update(t *testing.T) { + variable := &tfe.VariableSet{} + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckTFEVariableSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTFEVariableSet_basic(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEVariableSetEExists( + "tfe_variable_set.foobar", variableSet), + testAccCheckTFEVariableSetAttributes(variableSet), + resource.TestCheckResourceAttr( + "tfe_variable_set.foobar", "name", "foobar"), + resource.TestCheckResourceAttr( + "tfe_variable_set.foobar", "description", "a test variable set"), + resource.TestCheckResourceAttr( + "tfe_variable_set.foobar", "global", "false"), + ), + }, + + { + Config: testAccTFEVariableSet_update(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEVariableSetEExists( + "tfe_variable_set.foobar", variableSet), + testAccCheckTFEVariableSetAttributesUpdate(variableSet), + resource.TestCheckResourceAttr( + "tfe_variable_set.foobar", "name", "variable_set_test_updated"), + resource.TestCheckResourceAttr( + "tfe_variable_set.foobar", "description", "another description"), + resource.TestCheckResourceAttr( + "tfe_variable_set.foobar", "global", "true"), + ), + }, + }, + }) +} + +func TestAccTFEVariable_import(t *testing.T) { + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckTFEVariableSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTFEVariableSet_basic(rInt), + }, + + { + ResourceName: "tfe_variable_set.foobar", + ImportState: true, + ImportStateIdPrefix: fmt.Sprintf("tst-terraform-%d/workspace-test/", rInt), + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckTFEVariableSetExists( + n string, variableSet *tfe.VariableSet) resource.TestCheckFunc { + return func(s *terraform.State) error { + tfeClient := testAccProvider.Meta().(*tfe.Client) + + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No instance ID is set") + } + + vs, err := tfeClient.VariableSets.Read(ctx, rs.Primary.ID, nil) + if err != nil { + return err + } + + *variableSet = *vs + + return nil + } +} + +func testAccCheckTFEVariableSetAttributes( + variableSet *tfe.VariableSet) resource.TestCheckFunc { + return func(s *terraform.State) error { + if variableSet.name != "variable_set_test" { + return fmt.Errorf("Bad name: %s", variableSet.Name) + } + if variableSet.description != "a test variable set" { + return fmt.Errorf("Bad description: %s", variableSet.Description) + } + if variableSet.global != "false" { + return fmt.Errorf("Bad global: %s", variableSet.Global) + } + } +} + +func testAccCheckTFEVariableSetAttributesUpdate( + variableSet *tfe.VariableSet) resource.TestCheckFunc { + return func(s *terraform.State) error { + if variableSet.name != "variable_set_test_updated" { + return fmt.Errorf("Bad name: %s", variableSet.Name) + } + if variableSet.description != "another description" { + return fmt.Errorf("Bad description: %s", variableSet.Description) + } + if variableSet.global != "true" { + return fmt.Errorf("Bad global: %s", variableSet.Global) + } + } +} + +func testAccCheckTFEVariableSetDestroy(rInt int) string { + tfeClient := testAccProvider.Meta().(*tfe.Client) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "tfe_variable_set" { + continue + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No instance ID is set") + } + + _, err := tfeClient.VariableSets.Read(ctx, rs.Primary.ID, nil) + if err == nil { + return fmt.Errorf("Variable Set %s still exists", rs.Primary.ID) + } + } + + return nil +} + +func testAccTFEVariableSet_basic(rInt int) string { + return fmt.Sprintf(` +resource "tfe_organization" "foobar" { + name = "tft-terraform-%d" + email = "admin@company.com" +} + +resource "tfe_variable_set" "foobar" { + name = "variable_set_test" + description = "a test variable set" + global = false + organizaiton = tfe_organizatoin.foobar.id +}`, rInt) +} + +func testAccTFEVariable_update(rInt int) string { + return fmt.Sprintf(` +resource "tfe_organization" "foobar" { + name = "tst-terraform-%d" + email = "admin@company.com" +} + +resource "tfe_variable_set" "foobar" { + name = "variable_set_test_updated" + description = "another description" + global = true + organizaiton = tfe_organizatoin.foobar.id +}`, rInt) +} From 6c06a70da1c12fb303972a7ffba863e3b822cbe1 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Wed, 2 Mar 2022 13:51:51 -0500 Subject: [PATCH 06/31] resource provider support for variable set variables. needs tests --- go.mod | 2 + tfe/resource_tfe_variable.go | 200 ++++++++++++++++++++++++++++-- tfe/resource_tfe_variable_test.go | 54 ++++++++ tfe/variable_set_helpers.go | 35 ++++++ tfe/variable_set_helpers_test.go | 52 ++++++++ 5 files changed, 332 insertions(+), 11 deletions(-) create mode 100644 tfe/variable_set_helpers.go create mode 100644 tfe/variable_set_helpers_test.go diff --git a/go.mod b/go.mod index 0f4ad081b..07bc81eee 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/hashicorp/terraform-provider-tfe go 1.17 +replace github.com/hashicorp/go-tfe => /Users/alex/Work/go-tfe + require ( github.com/agext/levenshtein v1.2.3 // indirect github.com/aws/aws-sdk-go v1.37.0 // indirect diff --git a/tfe/resource_tfe_variable.go b/tfe/resource_tfe_variable.go index 4a94dda7e..956366b99 100644 --- a/tfe/resource_tfe_variable.go +++ b/tfe/resource_tfe_variable.go @@ -74,14 +74,26 @@ func resourceTFEVariable() *schema.Resource { }, "workspace_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ExactlyOneof: []string{"workspace_id", "variable_set_id"}, ValidateFunc: validation.StringMatch( workspaceIdRegexp, "must be a valid workspace ID (ws-)", ), }, + + "variable_set_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ExactlyOneOf: []string{"workspace_id", "variable_set_id"}, + ValidateFunc: validation.StringMatch( + variableSetIdRegexp, + "must be a valid variable set ID (varset-)", + ), + }, }, CustomizeDiff: forceRecreateResourceIf(), @@ -113,7 +125,13 @@ func resourceTFEVariableCreate(d *schema.ResourceData, meta interface{}) error { key := d.Get("key").(string) category := d.Get("category").(string) - // Get the workspace + //Switch to variable set variable logic + _, variableSetIdProvided := d.GetOk("variable_set_id") + if variableSetIdProvided { + return resourceTFEVariableSetVariableCreate(d, meta) + } + + // Get the workspace if workspace_id present workspaceID := d.Get("workspace_id").(string) ws, err := tfeClient.Workspaces.ReadByID(ctx, workspaceID) if err != nil { @@ -142,9 +160,51 @@ func resourceTFEVariableCreate(d *schema.ResourceData, meta interface{}) error { return resourceTFEVariableRead(d, meta) } +func resourceTFEVariableSetVariableCreate(d *schema.ResourceData, meta interface{}) error { + tfeClient := meta.(*tfe.Client) + + // Get key and category. + key := d.Get("key").(string) + category := d.Get("category").(string) + + // Get the variable set + variableSetID := d.Get("variable_set_id").(string) + vs, err := tfeClient.VariableSets.Read(ctx, variableSetID, nil) + if err != nil { + return fmt.Errorf( + "Error retrieving variable set %s: %v", variableSetID, err) + } + + // Create a new options struct. + options := tfe.VariableSetVariableCreateOptions{ + Key: tfe.String(key), + Value: tfe.String(d.Get("value").(string)), + Category: tfe.Category(tfe.CategoryType(category)), + HCL: tfe.Bool(d.Get("hcl").(bool)), + Sensitive: tfe.Bool(d.Get("sensitive").(bool)), + Description: tfe.String(d.Get("description").(string)), + } + + log.Printf("[DEBUG] Create %s variable: %s", category, key) + variable, err := tfeClient.VariableSetVariables.Create(ctx, vs.ID, options) + if err != nil { + return fmt.Errorf("Error creating %s variable %s: %v", category, key, err) + } + + d.SetId(variable.ID) + + return resourceTFEVariableRead(d, meta) +} + func resourceTFEVariableRead(d *schema.ResourceData, meta interface{}) error { tfeClient := meta.(*tfe.Client) + //Switch to variable set variable logic + _, variableSetIdProvided := d.GetOk("variable_set_id") + if variableSetIdProvided { + return resourceTFEVariableSetVariableRead(d, meta) + } + // Get the workspace. workspaceID := d.Get("workspace_id").(string) ws, err := tfeClient.Workspaces.ReadByID(ctx, workspaceID) @@ -184,9 +244,57 @@ func resourceTFEVariableRead(d *schema.ResourceData, meta interface{}) error { return nil } +func resourceTFEVariableSetVariableRead(d *schema.ResourceData, meta interface{}) error { + tfeClient := meta.(*tfe.Client) + + // Get the variable set + variableSetID := d.Get("variable_set_id").(string) + vs, err := tfeClient.VariableSet.Read(ctx, variableSetID, nil) + if err != nil { + if err == tfe.ErrResourceNotFound { + log.Printf("[DEBUG] Variable set %s no longer exists", variableSetID) + d.SetId("") + return nil + } + return fmt.Errorf( + "Error retrieving variable set %s: %v", variableSetID, err) + } + + log.Printf("[DEBUG] Read variable: %s", d.Id()) + variable, err := tfeClient.VariableSetVariables.Read(ctx, vs.ID, d.Id()) + if err != nil { + if err == tfe.ErrResourceNotFound { + log.Printf("[DEBUG] Variable %s does no longer exist", d.Id()) + d.SetId("") + return nil + } + return fmt.Errorf("Error reading variable %s: %v", d.Id(), err) + } + + // Update config. + d.Set("key", variable.Key) + d.Set("category", string(variable.Category)) + d.Set("description", string(variable.Description)) + d.Set("hcl", variable.HCL) + d.Set("sensitive", variable.Sensitive) + + // Only set the value if its not sensitive, as otherwise it will be empty. + if !variable.Sensitive { + d.Set("value", variable.Value) + } + + return nil +} + func resourceTFEVariableUpdate(d *schema.ResourceData, meta interface{}) error { tfeClient := meta.(*tfe.Client) + //Switch to variable set variable logic + _, variableSetIdProvided := d.GetOk("variable_set_id") + if variableSetIdProvided { + return resourceTFEVariableSetVariableUpdate(d, meta) + } + // Get the workspace. workspaceID := d.Get("workspace_id").(string) ws, err := tfeClient.Workspaces.ReadByID(ctx, workspaceID) @@ -213,9 +321,44 @@ func resourceTFEVariableUpdate(d *schema.ResourceData, meta interface{}) error { return resourceTFEVariableRead(d, meta) } +func resourceTFEVariableSetVariableUpdate(d *schema.ResourceData, meta interface{}) error { + tfeClient := meta.(*tfe.Client) + + // Get the variable set. + variableSetID := d.Get("variable_set_id").(string) + vs, err := tfeClient.VariableSets.Read(ctx, variableSetID, nil) + if err != nil { + return fmt.Errorf( + "Error retrieving variable set %s: %v", variableSetID, err) + } + + // Create a new options struct. + options := tfe.VariableSetVariableUpdateOptions{ + Key: tfe.String(d.Get("key").(string)), + Value: tfe.String(d.Get("value").(string)), + HCL: tfe.Bool(d.Get("hcl").(bool)), + Sensitive: tfe.Bool(d.Get("sensitive").(bool)), + Description: tfe.String(d.Get("description").(string)), + } + + log.Printf("[DEBUG] Update variable: %s", d.Id()) + _, err = tfeClient.VariableSetVariables.Update(ctx, vs.ID, d.Id(), options) + if err != nil { + return fmt.Errorf("Error updating variable %s: %v", d.Id(), err) + } + + return resourceTFEVariableRead(d, meta) +} + func resourceTFEVariableDelete(d *schema.ResourceData, meta interface{}) error { tfeClient := meta.(*tfe.Client) + //Switch to variable set variable logic + _, variableSetIdProvided := d.GetOk("variable_set_id") + if variableSetIdProvided { + return resourceTFEVariableSetVariableUpdate(d, meta) + } + // Get the workspace. workspaceID := d.Get("workspace_id").(string) ws, err := tfeClient.Workspaces.ReadByID(ctx, workspaceID) @@ -236,24 +379,59 @@ func resourceTFEVariableDelete(d *schema.ResourceData, meta interface{}) error { return nil } +func resourceTFEVariableSetVariableDelete(d *schema.ResourceData, meta interface{}) error { + tfeClient := meta.(*tfe.Client) + + // Get the variable set. + variableSetID := d.Get("variable_set__id").(string) + vs, err := tfeClient.VariableSets.Read(ctx, variableSetID, nil) + if err != nil { + return fmt.Errorf( + "Error retrieving variable set %s: %v", variableSetID, err) + } + + log.Printf("[DEBUG] Delete variable: %s", d.Id()) + err = tfeClient.VariableSetVariables.Delete(ctx, vs.ID, d.Id()) + if err != nil { + if err == tfe.ErrResourceNotFound { + return nil + } + return fmt.Errorf("Error deleting variable%s: %v", d.Id(), err) + } + + return nil +} + func resourceTFEVariableImporter(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { tfeClient := meta.(*tfe.Client) s := strings.SplitN(d.Id(), "/", 3) if len(s) != 3 { return nil, fmt.Errorf( - "invalid variable import format: %s (expected //)", + "invalid variable import format: %s (expected //)", d.Id(), ) } - // Set the fields that are part of the import ID. - workspace_id, err := fetchWorkspaceExternalID(s[0]+"/"+s[1], tfeClient) - if err != nil { - return nil, fmt.Errorf( - "error retrieving workspace %s from organization %s: %v", s[1], s[0], err) + varsetIdUsed, e := regexp.MatchString(variableSetIdRegexp, s[1]) + if varsetIdUsed { + // Set the fields that are part of the import ID. + variableSet_id, err := fetchVariableSetExternalID(s[0]+"/"+s[1], tfeClient) + if err != nil { + return nil, fmt.Errorf( + "error retrieving variable set %s from organization %s: %v", s[1], s[0], err) + } + d.Set("variable_set_id", variableSet_id) + } else { + // Set the fields that are part of the import ID. + workspace_id, err := fetchWorkspaceExternalID(s[0]+"/"+s[1], tfeClient) + if err != nil { + return nil, fmt.Errorf( + "error retrieving workspace %s from organization %s: %v", s[1], s[0], err) + } + d.Set("workspace_id", workspace_id) } - d.Set("workspace_id", workspace_id) + d.SetId(s[2]) return []*schema.ResourceData{d}, nil diff --git a/tfe/resource_tfe_variable_test.go b/tfe/resource_tfe_variable_test.go index c9621734b..5c25c6157 100644 --- a/tfe/resource_tfe_variable_test.go +++ b/tfe/resource_tfe_variable_test.go @@ -44,6 +44,39 @@ func TestAccTFEVariable_basic(t *testing.T) { }) } +func TestAccTFEVariable_basic_variable_set(t *testing.T) { + variable := &tfe.VariableSetVariable{} + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckTFEVariableDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTFEVariable_basic_variable_set(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEVariableExists( + "tfe_variable.foobar", variable), + testAccCheckTFEVariableAttributes(variable), + resource.TestCheckResourceAttr( + "tfe_variable.foobar", "key", "key_test"), + resource.TestCheckResourceAttr( + "tfe_variable.foobar", "value", "value_test"), + resource.TestCheckResourceAttr( + "tfe_variable.foobar", "description", "some description"), + resource.TestCheckResourceAttr( + "tfe_variable.foobar", "category", "env"), + resource.TestCheckResourceAttr( + "tfe_variable.foobar", "hcl", "false"), + resource.TestCheckResourceAttr( + "tfe_variable.foobar", "sensitive", "false"), + ), + }, + }, + }) +} + func TestAccTFEVariable_update(t *testing.T) { variable := &tfe.Variable{} rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() @@ -353,6 +386,27 @@ resource "tfe_variable" "foobar" { }`, rInt) } +func testAccTFEVariable_basic_variable_set(rInt int) string { + return fmt.Sprintf(` +resource "tfe_organization" "foobar" { + name = "tst-terraform-%d" + email = "admin@company.com" +} + +resource "tfe_variable_set" "foobar" { + name = "workspace-test" + organization = tfe_organization.foobar.id +} + +resource "tfe_variable" "foobar" { + key = "key_test" + value = "value_test" + description = "some description" + category = "env" + variable_set_id = tfe_varaible_set.foobar.id +}`, rInt) +} + func testAccTFEVariable_update(rInt int) string { return fmt.Sprintf(` resource "tfe_organization" "foobar" { diff --git a/tfe/variable_set_helpers.go b/tfe/variable_set_helpers.go new file mode 100644 index 000000000..ddcf94f41 --- /dev/null +++ b/tfe/variable_set_helpers.go @@ -0,0 +1,35 @@ +package tfe + +import ( + "context" + "fmt" + "strings" + + tfe "github.com/hashicorp/go-tfe" +) + +// fetchWorkspaceExternalID returns the external id for a workspace +// when given a workspace id of the form ORGANIZATION_AME/WORKSPACE_NAME +func fetchVariableSetExternalID(id string, client *tfe.Client) (string, error) { + orgName, vsId, err := unpackVariableSetID(id) + if err != nil { + return "", fmt.Errorf("Error unpacking variable set ID: %v", err) + } + + vs, err := client.VariableSets.Read(ctx, orgName, vsId) + if err != nil { + return "", fmt.Errorf("Error reading configuration of variable set %s: %v", id, err) + } + + return vs.ID, nil +} + +func unpackVariableSetID(id string) (organization, name string, err error) { + s := strings.SplitN(id, "/", 2) + if len(s) != 2 { + return "", "", fmt.Errorf( + "invalid workspace ID format: %s (expected /)", id) + } + + return s[0], s[1], nil +} diff --git a/tfe/variable_set_helpers_test.go b/tfe/variable_set_helpers_test.go new file mode 100644 index 000000000..cbe3d6cb0 --- /dev/null +++ b/tfe/variable_set_helpers_test.go @@ -0,0 +1,52 @@ +package tfe + +import ( + "context" + "testing" + + tfe "github.com/hashicorp/go-tfe" +) + +func TestFetchVariableSetExternalID(t *testing.T) { + tests := map[string]struct { + def string + want string + err bool + }{ + "non exisiting organization": { + "not-an-org/variable_set", + "", + true, + }, + "non exisiting variable_set": { + "hashicorp/not-a-variable_set", + "", + true, + }, + "found variable_set": { + "hashicorp/a-variable_set", + "vs-123", + false, + }, + } + + client := testTfeClient(t, testClientOptions{defaultVariableSetID: "vs-123"}) + name := "a-variable_set" + client.VariableSets.Create(nil, "hashicorp", tfe.VariableSetCreateOptions{ + Name: &name, + }) + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + got, err := fetchVariableSetExternalID(test.def, client) + + if (err != nil) != test.err { + t.Fatalf("expected error is %t, got %v", test.err, err) + } + + if got != test.want { + t.Fatalf("wrong result\ngot: %#v\nwant: %#v", got, test.want) + } + }) + } +} From 5b99284a4d76344feb5428b8dfd82c31f96eb10f Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Wed, 2 Mar 2022 16:17:32 -0500 Subject: [PATCH 07/31] Add datasources for variable sets --- tfe/data_source_variable_set.go | 115 +++++++++++++++++++++++++++ tfe/data_source_variable_set_test.go | 73 +++++++++++++++++ tfe/data_source_variables.go | 70 +++++++++++++++- tfe/data_source_variables_test.go | 65 ++++++++++++--- 4 files changed, 310 insertions(+), 13 deletions(-) create mode 100644 tfe/data_source_variable_set.go create mode 100644 tfe/data_source_variable_set_test.go diff --git a/tfe/data_source_variable_set.go b/tfe/data_source_variable_set.go new file mode 100644 index 000000000..809abc1bb --- /dev/null +++ b/tfe/data_source_variable_set.go @@ -0,0 +1,115 @@ +package tfe + +import ( + "fmt" + "log" + + tfe "github.com/hashicorp/go-tfe" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceTFEVariableSet() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTFEVariableSetRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + + "organization": { + Type: schema.TypeString, + Required: true, + }, + + "description": { + Type: schema.TypeString, + Computed: true, + }, + + "global": { + Type: schema.TypeBool, + Computed: true, + }, + + "workspaces": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "vars": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func dataSourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) error { + tfeClient := meta.(*tfe.Client) + + // Get the name and organization. + name := d.Get("name").(string) + organization := d.Get("organization").(string) + + // Create an options struct. + options := tfe.VariableSetListOptions{} + + for { + // Variable Set relations, vars and workspaces, are omitted from the querying until + // we find the desired variable set. + l, err := tfeClient.VariableSets.List(ctx, organization, options) + if err != nil { + if err == tfe.ErrResourceNotFound { + return fmt.Errorf("could not find variable set%s/%s", organization, name) + } + return fmt.Errorf("Error retrieving variable set: %v", err) + } + + for _, vs := range l.Items { + if vs.Name == name { + d.Set("name", vs.Name) + d.Set("description", vs.Description) + d.Set("global", vs.Global) + + //Only now include vars and workspaces to cut down on request load. + vs, err = tfeClient.VariableSets.Read(ctx, vs.ID, &VariableSetReadOptions{ + Include: &[]VariableSetIncludeOps{VariableSetWorkspaces, VariableSetVars}, + }) + if err != nil { + return fmt.Errorf("Error retrieving variable set relations: %v", err) + } + + var workspaces []interface{} + for _, workspace := range vs.Workspaces { + workspaces = append(workspaces, workspace.ID) + } + d.Set("workspaces", workspace_ids) + + var vars []interface{} + for _, v := range vs.Workspaces { + vars = append(vars, v.ID) + } + d.Set("vars", vars) + + d.SetId(vs.ID) + return nil + } + } + + // Exit the loop when we've seen all pages. + if l.CurrentPage >= l.TotalPages { + break + } + + // Update the page number to get the next page. + options.PageNumber = l.NextPage + } + + return fmt.Errorf("Could not find variable set %s/%s", organization, name) +} diff --git a/tfe/data_source_variable_set_test.go b/tfe/data_source_variable_set_test.go new file mode 100644 index 000000000..add02b138 --- /dev/null +++ b/tfe/data_source_variable_set_test.go @@ -0,0 +1,73 @@ +package tfe + +import ( + "fmt" + "math/rand" + "testing" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccTFEVariableSetsDataSource_basic(t *testing.T) { + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + orgName := fmt.Sprintf("tst-terraform-%d", rInt) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccTFEVariableSetsDataSourceConfig_basic(rInt), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("data.tfe_variable_set.foobar", "id"), + resource.TestCheckResourceAttr( + "data.tfe_variable_set.foobar", "name", fmt.Sprintf("varset-foo-%d", rInt)), + resource.TestCheckResourceAttr( + "data.tfe_variable_set.foobar", "description", "a description"), + resource.TestCheckResourceAttr( + "data.tfe_variable_set.foobar", "global", "false"), + resource.TestCheckResourceAttr( + "data.tfe_variable_set.foobar", "organizaiton", orgName), + resource.TestCheckResourceAttr( + "data.tfe_variable_set.foobar", "workspaces.0", fmt.Sprintf("workspace-foo-%d", rInt)), + resource.TestCheckResourceAttr( + "data.tfe_variable_set.foobar", "variables.#", "1"), + ), + }, + }, + }, + ) +} + +func testAccTFEVariableSetsDataSourceConfig_basic(rInt int) string { + return fmt.Sprintf(` +resource "tfe_organization" "foobar" { + name = "org-%d" + email = "admin@company.com" +} + +resource "tfe_workspace" "foobar" { + name = "workspace-foo-%d" + organization = tfe_organization.foobar.id +} + +resource "tfe_variable_set" "foobar" { + name = "varset-foo-%d" + description = "a description" + organization = tfe_organization.foobar.id + workspace = [tfe_workspace.foobar.id] +} + +resource "tfe_variable" "envfoo" { + key = "vfoo" + value = "bar" + category = "env" + variable_set_id = tfe_variable_set.foobar.id +} + +data "tfe_variable" "foobar" { + name = tfe_variable_set.foobar.name + organization = tfe_variable_set.foobar.organization +}`, rInt, rInt) +} diff --git a/tfe/data_source_variables.go b/tfe/data_source_variables.go index b75aabd79..6c1777c10 100644 --- a/tfe/data_source_variables.go +++ b/tfe/data_source_variables.go @@ -62,14 +62,26 @@ func dataSourceTFEWorkspaceVariables() *schema.Resource { }, }, "workspace_id": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: false, + ExactlyOneOf: []string{"workspace_id", "variable_set_id"}, + }, + "variable_set_id": { + Type: schema.TypeString, + Required: false, + ExactlyOneOf: []string{"workspace_id", "variable_set_id"}, }, }, } } func dataSourceVariableRead(d *schema.ResourceData, meta interface{}) error { + //Switch to variable set variable logic + _, variableSetIdProvided := d.GetOk("variable_set_id") + if variableSetIdProvided { + return dataSourceVariableSetVariableRead(d, meta) + } + tfeClient := meta.(*tfe.Client) // Get the name and organization. @@ -122,3 +134,57 @@ func dataSourceVariableRead(d *schema.ResourceData, meta interface{}) error { d.Set("env", totalEnvVariables) return nil } + +func dataSourceVariableSetVariableRead(d *schema.ResourceData, meta interface{}) error { + tfeClient := meta.(*tfe.Client) + + // Get the name and organization. + variableSetId := d.Get("variable_set_id").(string) + + log.Printf("[DEBUG] Read configuration of variable set: %s", variableSetId) + + totalEnvVariables := make([]interface{}, 0) + totalTerraformVariables := make([]interface{}, 0) + + options := tfe.VariableSetVariableListOptions{} + + for { + variableList, err := tfeClient.VariableSetVariables.List(ctx, variableSetId, options) + if err != nil { + return fmt.Errorf("Error retrieving variable list: %w", err) + } + terraformVars := make([]interface{}, 0) + envVars := make([]interface{}, 0) + for _, variable := range variableList.Items { + result := make(map[string]interface{}) + result["id"] = variable.ID + result["category"] = variable.Category + result["hcl"] = variable.HCL + result["name"] = variable.Key + result["sensitive"] = variable.Sensitive + result["value"] = variable.Value + if variable.Category == "terraform" { + terraformVars = append(terraformVars, result) + } else if variable.Category == "env" { + envVars = append(envVars, result) + } + } + + totalEnvVariables = append(totalEnvVariables, envVars...) + totalTerraformVariables = append(totalTerraformVariables, terraformVars...) + + // Exit the loop when we've seen all pages. + if variableList.CurrentPage >= variableList.TotalPages { + break + } + + // Update the page number to get the next page. + options.PageNumber = variableList.NextPage + } + + d.SetId(fmt.Sprintf("variables/%v", variableSetId)) + d.Set("variables", append(totalTerraformVariables, totalEnvVariables...)) + d.Set("terraform", totalTerraformVariables) + d.Set("env", totalEnvVariables) + return nil +} diff --git a/tfe/data_source_variables_test.go b/tfe/data_source_variables_test.go index 2508df4a4..c0348508c 100644 --- a/tfe/data_source_variables_test.go +++ b/tfe/data_source_variables_test.go @@ -20,10 +20,14 @@ func TestAccTFEVariablesDataSource_basic(t *testing.T) { Config: testAccTFEVariablesDataSourceConfig_basic(rInt), Check: resource.ComposeAggregateTestCheckFunc( // variables attribute - resource.TestCheckResourceAttrSet("data.tfe_variables.foobar", "id"), - resource.TestCheckOutput("variables", "foo"), - resource.TestCheckOutput("env", "foo"), - resource.TestCheckOutput("terraform", "foo"), + resource.TestCheckResourceAttrSet("data.tfe_variables.workspace_foobar", "id"), + resource.TestCheckResourceAttrSet("data.tfe_variables.variable_set_foobar", "id"), + resource.TestCheckOutput("workspace_variables", "foo"), + resource.TestCheckOutput("workspace_env", "foo"), + resource.TestCheckOutput("workspace_terraform", "foo"), + resource.TestCheckOutput("variable_set_variables", "vfoo"), + resource.TestCheckOutput("variable_set_env", "vfoo"), + resource.TestCheckOutput("variable_set_terraform", "vfoo"), ), }, }, @@ -43,6 +47,11 @@ resource "tfe_workspace" "foobar" { organization = tfe_organization.foobar.id } +resource "tfe_variable_set" "foobar" { + name = "varset-foo-%d" + organization = tfe_organization.foobar.id +} + resource "tfe_variable" "terrbar" { key = "foo" value = "bar" @@ -57,7 +66,21 @@ resource "tfe_variable" "envbar" { workspace_id = tfe_workspace.foobar.id } -data "tfe_variables" "foobar" { +resource "tfe_variable" "terrfoo" { + key = "vfoo" + value = "bar" + category = "terraform" + variable_set_id = tfe_variable_set.foobar.id +} + +resource "tfe_variable" "envfoo" { + key = "vfoo" + value = "bar" + category = "env" + variable_set_id = tfe_variable_set.foobar.id +} + +data "tfe_variables" "workspace_foobar" { workspace_id = tfe_workspace.foobar.id depends_on = [ tfe_variable.terrbar, @@ -65,15 +88,35 @@ data "tfe_variables" "foobar" { ] } -output "variables" { - value = data.tfe_variables.foobar.variables[0]["name"] +data "tfe_variables" "variable_set_foobar" { + variable_set_id = tfe_variable_set.foobar.id + depends_on = [ + tfe_variable.terrfoo, + tfe_variable.envfoo + ] +} + +output "workspace_variables" { + value = data.tfe_variables.workspace_foobar.variables[0]["name"] +} + +output "workspace_env" { + value = data.tfe_variables.workspace_foobar.env[0]["name"] +} + +output "workspace_terraform" { + value = data.tfe_variables.workspace_foobar.terraform[0]["name"] +} + +output "variable_set_variables" { + value = data.tfe_variables.variable_set_foobar.variables[0]["name"] } -output "env" { - value = data.tfe_variables.foobar.env[0]["name"] +output "variable_set_env" { + value = data.tfe_variables.variable_set_foobar.terraform[0]["name"] } -output "terraform" { - value = data.tfe_variables.foobar.terraform[0]["name"] +output "variable_set_terraform" { + value = data.tfe_variables.variable_set_foobar.env[0]["name"] }`, rInt, rInt) } From 06f5e5d1e0f04b392337a10f6da4eff4ef60276d Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Wed, 2 Mar 2022 16:17:55 -0500 Subject: [PATCH 08/31] fork earlier for varset var logic --- tfe/resource_tfe_variable.go | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tfe/resource_tfe_variable.go b/tfe/resource_tfe_variable.go index 956366b99..d470a8487 100644 --- a/tfe/resource_tfe_variable.go +++ b/tfe/resource_tfe_variable.go @@ -77,7 +77,7 @@ func resourceTFEVariable() *schema.Resource { Type: schema.TypeString, Optional: true, ForceNew: true, - ExactlyOneof: []string{"workspace_id", "variable_set_id"}, + ExactlyOneOf: []string{"workspace_id", "variable_set_id"}, ValidateFunc: validation.StringMatch( workspaceIdRegexp, "must be a valid workspace ID (ws-)", @@ -119,18 +119,18 @@ func forceRecreateResourceIf() schema.CustomizeDiffFunc { } func resourceTFEVariableCreate(d *schema.ResourceData, meta interface{}) error { + //Switch to variable set variable logic if we need to + _, variableSetIdProvided := d.GetOk("variable_set_id") + if variableSetIdProvided { + return resourceTFEVariableSetVariableCreate(d, meta) + } + tfeClient := meta.(*tfe.Client) // Get key and category. key := d.Get("key").(string) category := d.Get("category").(string) - //Switch to variable set variable logic - _, variableSetIdProvided := d.GetOk("variable_set_id") - if variableSetIdProvided { - return resourceTFEVariableSetVariableCreate(d, meta) - } - // Get the workspace if workspace_id present workspaceID := d.Get("workspace_id").(string) ws, err := tfeClient.Workspaces.ReadByID(ctx, workspaceID) @@ -197,14 +197,14 @@ func resourceTFEVariableSetVariableCreate(d *schema.ResourceData, meta interface } func resourceTFEVariableRead(d *schema.ResourceData, meta interface{}) error { - tfeClient := meta.(*tfe.Client) - - //Switch to variable set variable logic + //Switch to variable set variable logic if we need to _, variableSetIdProvided := d.GetOk("variable_set_id") if variableSetIdProvided { return resourceTFEVariableSetVariableRead(d, meta) } + tfeClient := meta.(*tfe.Client) + // Get the workspace. workspaceID := d.Get("workspace_id").(string) ws, err := tfeClient.Workspaces.ReadByID(ctx, workspaceID) @@ -287,14 +287,14 @@ func resourceTFEVariableSetVariableRead(d *schema.ResourceData, meta interface{} } func resourceTFEVariableUpdate(d *schema.ResourceData, meta interface{}) error { - tfeClient := meta.(*tfe.Client) - - //Switch to variable set variable logic + //Switch to variable set variable logic if we need to _, variableSetIdProvided := d.GetOk("variable_set_id") if variableSetIdProvided { return resourceTFEVariableSetVariableUpdate(d, meta) } + tfeClient := meta.(*tfe.Client) + // Get the workspace. workspaceID := d.Get("workspace_id").(string) ws, err := tfeClient.Workspaces.ReadByID(ctx, workspaceID) @@ -351,14 +351,14 @@ func resourceTFEVariableSetVariableUpdate(d *schema.ResourceData, meta interface } func resourceTFEVariableDelete(d *schema.ResourceData, meta interface{}) error { - tfeClient := meta.(*tfe.Client) - - //Switch to variable set variable logic + //Switch to variable set variable logic if we need to _, variableSetIdProvided := d.GetOk("variable_set_id") if variableSetIdProvided { - return resourceTFEVariableSetVariableUpdate(d, meta) + return resourceTFEVariableSetVariableDelete(d, meta) } + tfeClient := meta.(*tfe.Client) + // Get the workspace. workspaceID := d.Get("workspace_id").(string) ws, err := tfeClient.Workspaces.ReadByID(ctx, workspaceID) From 2b22db22ac885c9464beace7f229a9804fea7984 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Wed, 2 Mar 2022 16:18:56 -0500 Subject: [PATCH 09/31] fix accidental go.mod change --- go.mod | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.mod b/go.mod index 07bc81eee..0f4ad081b 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,6 @@ module github.com/hashicorp/terraform-provider-tfe go 1.17 -replace github.com/hashicorp/go-tfe => /Users/alex/Work/go-tfe - require ( github.com/agext/levenshtein v1.2.3 // indirect github.com/aws/aws-sdk-go v1.37.0 // indirect From f1da8bcb3d06d072c7d08edc245b164f1cf5aa39 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Fri, 4 Mar 2022 11:50:37 -0500 Subject: [PATCH 10/31] Add workspaces assignment to variable sets --- tfe/resource_tfe_variable_set.go | 49 ++++++++++++++++----- tfe/resource_tfe_variable_set_test.go | 63 ++++++++++++++++++++++----- 2 files changed, 92 insertions(+), 20 deletions(-) diff --git a/tfe/resource_tfe_variable_set.go b/tfe/resource_tfe_variable_set.go index f05a24131..bcad5b989 100644 --- a/tfe/resource_tfe_variable_set.go +++ b/tfe/resource_tfe_variable_set.go @@ -45,14 +45,12 @@ func resourceTFEVariableSet() *schema.Resource { ForceNew: true, }, - /* - "workspaces": { - Type: schema.TypeSet, - Optional: true, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - */ + "workspaces": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, }, } } @@ -77,6 +75,21 @@ func resourceTFEVariableSetCreate(d *schema.ResourceData, meta interface{}) erro "Error creating variable set %s, for organization: %s: %v", name, organization, err) } + if workspaceIDs, workspacesSet := d.GetOK("workspaces"); !options.Global && workspacesSet { + log.Printf("[DEBUG] Assign variable set %s to workspaces %v", name, workspaceIDs) + + options = tfe.VariableSetAssignOptions{} + for _, workspaceID := range workspaceIDs.(*schema.Set).List() { + options.Workspace = append(options.Workspaces, Workspace{ID: workspaceID}) + } + + variableSet, err = tfeClient.VariableSets.Assign(ctx, variableSet.ID, &options) + if err != nil { + return fmt.Errorf( + "Error assigning variable set %s (%s) to given workspaces: %v", name, variableSet.ID, err) + } + } + d.SetId(variableSet.ID) return resourceTFEVariableSetRead(d, meta) @@ -87,7 +100,7 @@ func resourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) error id := d.Id() log.Printf("[DEBUG] Read configuration of variable set: %s", id) - variableSet, err := tfeClient.VariableSets.Read(ctx, id, nil) //&VariableSetReadOptions{VariableSetWorkspaces}) + variableSet, err := tfeClient.VariableSets.Read(ctx, id, &VariableSetReadOptions{VariableSetWorkspaces}) if err != nil { if err == tfe.ErrResourceNotFound { log.Printf("[DEBUG] Variable set %s no longer exists", id) @@ -102,7 +115,7 @@ func resourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) error d.Set("description", variableSet.Description) d.Set("global", variableSet.Global) d.Set("organization", variableSet.Organization) - //d.Set("workspaces", variableSet.Workspaces) + d.Set("workspaces", variableSet.Workspaces) return nil } @@ -125,6 +138,22 @@ func resourceTFEVariableSetUpdate(d *schema.ResourceData, meta interface{}) erro } } + if d.HasChanges("workspaces") { + workspaceIDs, workspacesSet := d.GetOK("workspaces") + log.Printf("[DEBUG] Assign variable set %s to workspaces %v", name, workspaceIDs) + + options = tfe.VariableSetAssignOptions{} + for _, workspaceID := range workspaceIDs.(*schema.Set).List() { + options.Workspace = append(options.Workspaces, Workspace{ID: workspaceID}) + } + + variableSet, err = tfeClient.VariableSets.Assign(ctx, variableSet.ID, &options) + if err != nil { + return fmt.Errorf( + "Error assigning variable set %s (%s) to given workspaces: %v", name, variableSet.ID, err) + } + } + return resourceTFEVariableSetRead(d, meta) } diff --git a/tfe/resource_tfe_variable_set_test.go b/tfe/resource_tfe_variable_set_test.go index c2454614d..c437ce992 100644 --- a/tfe/resource_tfe_variable_set_test.go +++ b/tfe/resource_tfe_variable_set_test.go @@ -23,7 +23,7 @@ func TestAccTFEVariableSet_basic(t *testing.T) { { Config: testAccTFEVariableSet_basic(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckTFEVariableSetEExists( + testAccCheckTFEVariableSetExists( "tfe_variable_set.foobar", variableSet), testAccCheckTFEVariableSetAttributes(variableSet), resource.TestCheckResourceAttr( @@ -32,6 +32,9 @@ func TestAccTFEVariableSet_basic(t *testing.T) { "tfe_variable_set.foobar", "description", "a test variable set"), resource.TestCheckResourceAttr( "tfe_variable_set.foobar", "global", "false"), + testAccCheckTFEVariableSetExists( + "tfe_variable_set.assigned", variableSet), + testAccCheckTFEVariableSetAssignment(variableSet), ), }, }, @@ -50,7 +53,7 @@ func TestAccTFEVariableSet_update(t *testing.T) { { Config: testAccTFEVariableSet_basic(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckTFEVariableSetEExists( + testAccCheckTFEVariableSetExists( "tfe_variable_set.foobar", variableSet), testAccCheckTFEVariableSetAttributes(variableSet), resource.TestCheckResourceAttr( @@ -65,7 +68,7 @@ func TestAccTFEVariableSet_update(t *testing.T) { { Config: testAccTFEVariableSet_update(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckTFEVariableSetEExists( + testAccCheckTFEVariableSetExists( "tfe_variable_set.foobar", variableSet), testAccCheckTFEVariableSetAttributesUpdate(variableSet), resource.TestCheckResourceAttr( @@ -116,7 +119,7 @@ func testAccCheckTFEVariableSetExists( return fmt.Errorf("No instance ID is set") } - vs, err := tfeClient.VariableSets.Read(ctx, rs.Primary.ID, nil) + vs, err := tfeClient.VariableSets.Read(ctx, rs.Primary.ID, &VariableSetReadOptions{VariableSetWorkspaces}) if err != nil { return err } @@ -130,13 +133,13 @@ func testAccCheckTFEVariableSetExists( func testAccCheckTFEVariableSetAttributes( variableSet *tfe.VariableSet) resource.TestCheckFunc { return func(s *terraform.State) error { - if variableSet.name != "variable_set_test" { + if variableSet.Name != "variable_set_test" { return fmt.Errorf("Bad name: %s", variableSet.Name) } - if variableSet.description != "a test variable set" { + if variableSet.Description != "a test variable set" { return fmt.Errorf("Bad description: %s", variableSet.Description) } - if variableSet.global != "false" { + if variableSet.Global != false { return fmt.Errorf("Bad global: %s", variableSet.Global) } } @@ -145,18 +148,34 @@ func testAccCheckTFEVariableSetAttributes( func testAccCheckTFEVariableSetAttributesUpdate( variableSet *tfe.VariableSet) resource.TestCheckFunc { return func(s *terraform.State) error { - if variableSet.name != "variable_set_test_updated" { + if variableSet.Name != "variable_set_test_updated" { return fmt.Errorf("Bad name: %s", variableSet.Name) } - if variableSet.description != "another description" { + if variableSet.Description != "another description" { return fmt.Errorf("Bad description: %s", variableSet.Description) } - if variableSet.global != "true" { + if variableSet.Global != true { return fmt.Errorf("Bad global: %s", variableSet.Global) } } } +func testAccCheckTFEVariableSetAssignment(variableSet *tfe.VariableSet) resource.TestCheckFunc { + return func(s *terraform.State) error { + if len(variableSet.Workspace) != 1 { + return fmt.Errorf("Bad workspace assignment: %s", variableSet.Workspaces) + } + } +} + +func testAccCheckTFEVariableSetAssignmentUpdate(variableSet *tfe.VariableSet) resource.TestCheckFunc { + return func(s *terraform.State) error { + if len(variableSet.Workspace) != 0 { + return fmt.Errorf("Bad workspace assignment: %s", variableSet.Workspaces) + } + } +} + func testAccCheckTFEVariableSetDestroy(rInt int) string { tfeClient := testAccProvider.Meta().(*tfe.Client) @@ -185,11 +204,23 @@ resource "tfe_organization" "foobar" { email = "admin@company.com" } +resource "tfe_workspace" "foobar" { + name = "foobar" + organization = tfe_organization.foobar.id +} + resource "tfe_variable_set" "foobar" { name = "variable_set_test" description = "a test variable set" global = false organizaiton = tfe_organizatoin.foobar.id +} + +resource "tfe_variable_set" "assigned" { + name = "variable_set_assigned" + description = "a test variable set" + workspaces = [tfe_workspace.foobar.id] + organizaiton = tfe_organizatoin.foobar.id }`, rInt) } @@ -200,10 +231,22 @@ resource "tfe_organization" "foobar" { email = "admin@company.com" } +resource "tfe_workspace" "foobar" { + name = "foobar" + organization = tfe_organization.foobar.id +} + resource "tfe_variable_set" "foobar" { name = "variable_set_test_updated" description = "another description" global = true organizaiton = tfe_organizatoin.foobar.id +} + +resource "tfe_variable_set" "assigned" { + name = "variable_set_assigned" + description = "a test variable set" + workspaces = [] + organizaiton = tfe_organizatoin.foobar.id }`, rInt) } From 730bce2c83ed9da6d234f91b3cdecf7e793ef0ce Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Tue, 8 Mar 2022 09:08:34 -0500 Subject: [PATCH 11/31] Various bug and error fixes --- tfe/data_source_variable_set.go | 13 ++++---- tfe/data_source_variables.go | 2 +- tfe/resource_tfe_variable.go | 32 ++++++++------------ tfe/resource_tfe_variable_set.go | 27 +++++++++-------- tfe/variable_set_helpers.go | 35 --------------------- tfe/variable_set_helpers_test.go | 52 -------------------------------- 6 files changed, 35 insertions(+), 126 deletions(-) delete mode 100644 tfe/variable_set_helpers.go delete mode 100644 tfe/variable_set_helpers_test.go diff --git a/tfe/data_source_variable_set.go b/tfe/data_source_variable_set.go index 809abc1bb..7cc456927 100644 --- a/tfe/data_source_variable_set.go +++ b/tfe/data_source_variable_set.go @@ -2,7 +2,6 @@ package tfe import ( "fmt" - "log" tfe "github.com/hashicorp/go-tfe" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -63,7 +62,7 @@ func dataSourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) erro for { // Variable Set relations, vars and workspaces, are omitted from the querying until // we find the desired variable set. - l, err := tfeClient.VariableSets.List(ctx, organization, options) + l, err := tfeClient.VariableSets.List(ctx, organization, &options) if err != nil { if err == tfe.ErrResourceNotFound { return fmt.Errorf("could not find variable set%s/%s", organization, name) @@ -78,9 +77,11 @@ func dataSourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) erro d.Set("global", vs.Global) //Only now include vars and workspaces to cut down on request load. - vs, err = tfeClient.VariableSets.Read(ctx, vs.ID, &VariableSetReadOptions{ - Include: &[]VariableSetIncludeOps{VariableSetWorkspaces, VariableSetVars}, - }) + readOptions := tfe.VariableSetReadOptions{ + Include: &[]tfe.VariableSetIncludeOps{tfe.VariableSetWorkspaces, tfe.VariableSetVars}, + } + + vs, err = tfeClient.VariableSets.Read(ctx, vs.ID, &readOptions) if err != nil { return fmt.Errorf("Error retrieving variable set relations: %v", err) } @@ -89,7 +90,7 @@ func dataSourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) erro for _, workspace := range vs.Workspaces { workspaces = append(workspaces, workspace.ID) } - d.Set("workspaces", workspace_ids) + d.Set("workspaces", workspaces) var vars []interface{} for _, v := range vs.Workspaces { diff --git a/tfe/data_source_variables.go b/tfe/data_source_variables.go index 6c1777c10..16fdc78ad 100644 --- a/tfe/data_source_variables.go +++ b/tfe/data_source_variables.go @@ -149,7 +149,7 @@ func dataSourceVariableSetVariableRead(d *schema.ResourceData, meta interface{}) options := tfe.VariableSetVariableListOptions{} for { - variableList, err := tfeClient.VariableSetVariables.List(ctx, variableSetId, options) + variableList, err := tfeClient.VariableSetVariables.List(ctx, variableSetId, &options) if err != nil { return fmt.Errorf("Error retrieving variable list: %w", err) } diff --git a/tfe/resource_tfe_variable.go b/tfe/resource_tfe_variable.go index d470a8487..7b591cda6 100644 --- a/tfe/resource_tfe_variable.go +++ b/tfe/resource_tfe_variable.go @@ -186,7 +186,7 @@ func resourceTFEVariableSetVariableCreate(d *schema.ResourceData, meta interface } log.Printf("[DEBUG] Create %s variable: %s", category, key) - variable, err := tfeClient.VariableSetVariables.Create(ctx, vs.ID, options) + variable, err := tfeClient.VariableSetVariables.Create(ctx, vs.ID, &options) if err != nil { return fmt.Errorf("Error creating %s variable %s: %v", category, key, err) } @@ -249,7 +249,7 @@ func resourceTFEVariableSetVariableRead(d *schema.ResourceData, meta interface{} // Get the variable set variableSetID := d.Get("variable_set_id").(string) - vs, err := tfeClient.VariableSet.Read(ctx, variableSetID, nil) + vs, err := tfeClient.VariableSets.Read(ctx, variableSetID, nil) if err != nil { if err == tfe.ErrResourceNotFound { log.Printf("[DEBUG] Variable set %s no longer exists", variableSetID) @@ -261,14 +261,14 @@ func resourceTFEVariableSetVariableRead(d *schema.ResourceData, meta interface{} } log.Printf("[DEBUG] Read variable: %s", d.Id()) - variable, err := tfeClient.VariableSetVariables.Read(ctx, vs.ID, d.Id()) + variable, errr := tfeClient.VariableSetVariables.Read(ctx, vs.ID, d.Id()) if err != nil { - if err == tfe.ErrResourceNotFound { + if errr == tfe.ErrResourceNotFound { log.Printf("[DEBUG] Variable %s does no longer exist", d.Id()) d.SetId("") return nil } - return fmt.Errorf("Error reading variable %s: %v", d.Id(), err) + return fmt.Errorf("Error reading variable %s: %v", d.Id(), errr) } // Update config. @@ -313,9 +313,9 @@ func resourceTFEVariableUpdate(d *schema.ResourceData, meta interface{}) error { } log.Printf("[DEBUG] Update variable: %s", d.Id()) - _, err = tfeClient.Variables.Update(ctx, ws.ID, d.Id(), options) - if err != nil { - return fmt.Errorf("Error updating variable %s: %v", d.Id(), err) + _, errr := tfeClient.Variables.Update(ctx, ws.ID, d.Id(), options) + if errr != nil { + return fmt.Errorf("Error updating variable %s: %v", d.Id(), errr) } return resourceTFEVariableRead(d, meta) @@ -342,9 +342,9 @@ func resourceTFEVariableSetVariableUpdate(d *schema.ResourceData, meta interface } log.Printf("[DEBUG] Update variable: %s", d.Id()) - _, err = tfeClient.VariableSetVariables.Update(ctx, vs.ID, d.Id(), options) - if err != nil { - return fmt.Errorf("Error updating variable %s: %v", d.Id(), err) + _, errr := tfeClient.VariableSetVariables.Update(ctx, vs.ID, d.Id(), &options) + if errr != nil { + return fmt.Errorf("Error updating variable %s: %v", d.Id(), errr) } return resourceTFEVariableRead(d, meta) @@ -413,15 +413,9 @@ func resourceTFEVariableImporter(d *schema.ResourceData, meta interface{}) ([]*s ) } - varsetIdUsed, e := regexp.MatchString(variableSetIdRegexp, s[1]) + varsetIdUsed := variableSetIdRegexp.MatchString(s[1]) if varsetIdUsed { - // Set the fields that are part of the import ID. - variableSet_id, err := fetchVariableSetExternalID(s[0]+"/"+s[1], tfeClient) - if err != nil { - return nil, fmt.Errorf( - "error retrieving variable set %s from organization %s: %v", s[1], s[0], err) - } - d.Set("variable_set_id", variableSet_id) + d.Set("variable_set_id", s[1]) } else { // Set the fields that are part of the import ID. workspace_id, err := fetchWorkspaceExternalID(s[0]+"/"+s[1], tfeClient) diff --git a/tfe/resource_tfe_variable_set.go b/tfe/resource_tfe_variable_set.go index bcad5b989..4e1aff7e3 100644 --- a/tfe/resource_tfe_variable_set.go +++ b/tfe/resource_tfe_variable_set.go @@ -75,15 +75,15 @@ func resourceTFEVariableSetCreate(d *schema.ResourceData, meta interface{}) erro "Error creating variable set %s, for organization: %s: %v", name, organization, err) } - if workspaceIDs, workspacesSet := d.GetOK("workspaces"); !options.Global && workspacesSet { + if workspaceIDs, workspacesSet := d.GetOk("workspaces"); !*options.Global && workspacesSet { log.Printf("[DEBUG] Assign variable set %s to workspaces %v", name, workspaceIDs) - options = tfe.VariableSetAssignOptions{} + assignOptions := tfe.VariableSetAssignOptions{} for _, workspaceID := range workspaceIDs.(*schema.Set).List() { - options.Workspace = append(options.Workspaces, Workspace{ID: workspaceID}) + assignOptions.Workspaces = append(assignOptions.Workspaces, &tfe.Workspace{ID: workspaceID.(string)}) } - variableSet, err = tfeClient.VariableSets.Assign(ctx, variableSet.ID, &options) + variableSet, err = tfeClient.VariableSets.Assign(ctx, variableSet.ID, &assignOptions) if err != nil { return fmt.Errorf( "Error assigning variable set %s (%s) to given workspaces: %v", name, variableSet.ID, err) @@ -100,7 +100,9 @@ func resourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) error id := d.Id() log.Printf("[DEBUG] Read configuration of variable set: %s", id) - variableSet, err := tfeClient.VariableSets.Read(ctx, id, &VariableSetReadOptions{VariableSetWorkspaces}) + variableSet, err := tfeClient.VariableSets.Read(ctx, id, &tfe.VariableSetReadOptions{ + Include: &[]tfe.VariableSetIncludeOps{tfe.VariableSetWorkspaces}, + }) if err != nil { if err == tfe.ErrResourceNotFound { log.Printf("[DEBUG] Variable set %s no longer exists", id) @@ -139,18 +141,17 @@ func resourceTFEVariableSetUpdate(d *schema.ResourceData, meta interface{}) erro } if d.HasChanges("workspaces") { - workspaceIDs, workspacesSet := d.GetOK("workspaces") - log.Printf("[DEBUG] Assign variable set %s to workspaces %v", name, workspaceIDs) - - options = tfe.VariableSetAssignOptions{} + workspaceIDs := d.Get("workspaces") + assignOptions := tfe.VariableSetAssignOptions{} for _, workspaceID := range workspaceIDs.(*schema.Set).List() { - options.Workspace = append(options.Workspaces, Workspace{ID: workspaceID}) + assignOptions.Workspaces = append(assignOptions.Workspaces, &tfe.Workspace{ID: workspaceID.(string)}) } - variableSet, err = tfeClient.VariableSets.Assign(ctx, variableSet.ID, &options) - if err != nil { + log.Printf("[DEBUG] Assign variable set %s to workspaces %v", id, workspaceIDs) + vs, errr := tfeClient.VariableSets.Assign(ctx, id, &assignOptions) + if errr != nil { return fmt.Errorf( - "Error assigning variable set %s (%s) to given workspaces: %v", name, variableSet.ID, err) + "Error assigning variable set %s (%s) to given workspaces: %v", vs.Name, id, errr) } } diff --git a/tfe/variable_set_helpers.go b/tfe/variable_set_helpers.go deleted file mode 100644 index ddcf94f41..000000000 --- a/tfe/variable_set_helpers.go +++ /dev/null @@ -1,35 +0,0 @@ -package tfe - -import ( - "context" - "fmt" - "strings" - - tfe "github.com/hashicorp/go-tfe" -) - -// fetchWorkspaceExternalID returns the external id for a workspace -// when given a workspace id of the form ORGANIZATION_AME/WORKSPACE_NAME -func fetchVariableSetExternalID(id string, client *tfe.Client) (string, error) { - orgName, vsId, err := unpackVariableSetID(id) - if err != nil { - return "", fmt.Errorf("Error unpacking variable set ID: %v", err) - } - - vs, err := client.VariableSets.Read(ctx, orgName, vsId) - if err != nil { - return "", fmt.Errorf("Error reading configuration of variable set %s: %v", id, err) - } - - return vs.ID, nil -} - -func unpackVariableSetID(id string) (organization, name string, err error) { - s := strings.SplitN(id, "/", 2) - if len(s) != 2 { - return "", "", fmt.Errorf( - "invalid workspace ID format: %s (expected /)", id) - } - - return s[0], s[1], nil -} diff --git a/tfe/variable_set_helpers_test.go b/tfe/variable_set_helpers_test.go deleted file mode 100644 index cbe3d6cb0..000000000 --- a/tfe/variable_set_helpers_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package tfe - -import ( - "context" - "testing" - - tfe "github.com/hashicorp/go-tfe" -) - -func TestFetchVariableSetExternalID(t *testing.T) { - tests := map[string]struct { - def string - want string - err bool - }{ - "non exisiting organization": { - "not-an-org/variable_set", - "", - true, - }, - "non exisiting variable_set": { - "hashicorp/not-a-variable_set", - "", - true, - }, - "found variable_set": { - "hashicorp/a-variable_set", - "vs-123", - false, - }, - } - - client := testTfeClient(t, testClientOptions{defaultVariableSetID: "vs-123"}) - name := "a-variable_set" - client.VariableSets.Create(nil, "hashicorp", tfe.VariableSetCreateOptions{ - Name: &name, - }) - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - got, err := fetchVariableSetExternalID(test.def, client) - - if (err != nil) != test.err { - t.Fatalf("expected error is %t, got %v", test.err, err) - } - - if got != test.want { - t.Fatalf("wrong result\ngot: %#v\nwant: %#v", got, test.want) - } - }) - } -} From bfd3f614b029c9e044ac5136655156196407d886 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Tue, 8 Mar 2022 11:41:24 -0500 Subject: [PATCH 12/31] More fixes --- tfe/data_source_variable_set_test.go | 2 +- tfe/data_source_variables_test.go | 2 +- tfe/resource_tfe_variable_set_test.go | 34 +++++++++----- tfe/resource_tfe_variable_test.go | 67 ++++++++++++++++++++++++++- 4 files changed, 90 insertions(+), 15 deletions(-) diff --git a/tfe/data_source_variable_set_test.go b/tfe/data_source_variable_set_test.go index add02b138..6b37fb6e5 100644 --- a/tfe/data_source_variable_set_test.go +++ b/tfe/data_source_variable_set_test.go @@ -69,5 +69,5 @@ resource "tfe_variable" "envfoo" { data "tfe_variable" "foobar" { name = tfe_variable_set.foobar.name organization = tfe_variable_set.foobar.organization -}`, rInt, rInt) +}`, rInt, rInt, rInt) } diff --git a/tfe/data_source_variables_test.go b/tfe/data_source_variables_test.go index c0348508c..834b193aa 100644 --- a/tfe/data_source_variables_test.go +++ b/tfe/data_source_variables_test.go @@ -118,5 +118,5 @@ output "variable_set_env" { output "variable_set_terraform" { value = data.tfe_variables.variable_set_foobar.env[0]["name"] -}`, rInt, rInt) +}`, rInt, rInt, rInt) } diff --git a/tfe/resource_tfe_variable_set_test.go b/tfe/resource_tfe_variable_set_test.go index c437ce992..a2525659d 100644 --- a/tfe/resource_tfe_variable_set_test.go +++ b/tfe/resource_tfe_variable_set_test.go @@ -42,7 +42,7 @@ func TestAccTFEVariableSet_basic(t *testing.T) { } func TestAccTFEVariableSet_update(t *testing.T) { - variable := &tfe.VariableSet{} + variableSet := &tfe.VariableSet{} rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() resource.Test(t, resource.TestCase{ @@ -83,7 +83,7 @@ func TestAccTFEVariableSet_update(t *testing.T) { }) } -func TestAccTFEVariable_import(t *testing.T) { +func TestAccTFEVariableSet_import(t *testing.T) { rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() resource.Test(t, resource.TestCase{ @@ -119,7 +119,11 @@ func testAccCheckTFEVariableSetExists( return fmt.Errorf("No instance ID is set") } - vs, err := tfeClient.VariableSets.Read(ctx, rs.Primary.ID, &VariableSetReadOptions{VariableSetWorkspaces}) + vs, err := tfeClient.VariableSets.Read( + ctx, + rs.Primary.ID, + &tfe.VariableSetReadOptions{&[]tfe.VariableSetIncludeOps{tfe.VariableSetWorkspaces}}, + ) if err != nil { return err } @@ -140,8 +144,10 @@ func testAccCheckTFEVariableSetAttributes( return fmt.Errorf("Bad description: %s", variableSet.Description) } if variableSet.Global != false { - return fmt.Errorf("Bad global: %s", variableSet.Global) + return fmt.Errorf("Bad global: %t", variableSet.Global) } + + return nil } } @@ -155,28 +161,34 @@ func testAccCheckTFEVariableSetAttributesUpdate( return fmt.Errorf("Bad description: %s", variableSet.Description) } if variableSet.Global != true { - return fmt.Errorf("Bad global: %s", variableSet.Global) + return fmt.Errorf("Bad global: %t", variableSet.Global) } + + return nil } } func testAccCheckTFEVariableSetAssignment(variableSet *tfe.VariableSet) resource.TestCheckFunc { return func(s *terraform.State) error { - if len(variableSet.Workspace) != 1 { - return fmt.Errorf("Bad workspace assignment: %s", variableSet.Workspaces) + if len(variableSet.Workspaces) != 1 { + return fmt.Errorf("Bad workspace assignment: %v", variableSet.Workspaces) } + + return nil } } func testAccCheckTFEVariableSetAssignmentUpdate(variableSet *tfe.VariableSet) resource.TestCheckFunc { return func(s *terraform.State) error { - if len(variableSet.Workspace) != 0 { - return fmt.Errorf("Bad workspace assignment: %s", variableSet.Workspaces) + if len(variableSet.Workspaces) != 0 { + return fmt.Errorf("Bad workspace assignment: %v", variableSet.Workspaces) } + + return nil } } -func testAccCheckTFEVariableSetDestroy(rInt int) string { +func testAccCheckTFEVariableSetDestroy(s *terraform.State) error { tfeClient := testAccProvider.Meta().(*tfe.Client) for _, rs := range s.RootModule().Resources { @@ -224,7 +236,7 @@ resource "tfe_variable_set" "assigned" { }`, rInt) } -func testAccTFEVariable_update(rInt int) string { +func testAccTFEVariableSet_update(rInt int) string { return fmt.Sprintf(` resource "tfe_organization" "foobar" { name = "tst-terraform-%d" diff --git a/tfe/resource_tfe_variable_test.go b/tfe/resource_tfe_variable_test.go index 5c25c6157..502fc65c5 100644 --- a/tfe/resource_tfe_variable_test.go +++ b/tfe/resource_tfe_variable_test.go @@ -56,9 +56,9 @@ func TestAccTFEVariable_basic_variable_set(t *testing.T) { { Config: testAccTFEVariable_basic_variable_set(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckTFEVariableExists( + testAccCheckTFEVariableSetVariableExists( "tfe_variable.foobar", variable), - testAccCheckTFEVariableAttributes(variable), + testAccCheckTFEVariableiSetVariableAttributes(variable), resource.TestCheckResourceAttr( "tfe_variable.foobar", "key", "key_test"), resource.TestCheckResourceAttr( @@ -240,6 +240,38 @@ func testAccCheckTFEVariableExists( } } +func testAccCheckTFEVariableSetVariableExists( + n string, variable *tfe.VariableSetVariable) resource.TestCheckFunc { + return func(s *terraform.State) error { + tfeClient := testAccProvider.Meta().(*tfe.Client) + + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No instance ID is set") + } + + vsID := rs.Primary.Attributes["variable_set_id"] + vs, err := tfeClient.VariableSets.Read(ctx, vsID, nil) + if err != nil { + return fmt.Errorf( + "Error retrieving variable set %s: %v", vsID, err) + } + + v, err := tfeClient.VariableSetVariables.Read(ctx, vs.ID, rs.Primary.ID) + if err != nil { + return err + } + + *variable = *v + + return nil + } +} + func testAccCheckTFEVariableAttributes( variable *tfe.Variable) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -271,6 +303,37 @@ func testAccCheckTFEVariableAttributes( } } +func testAccCheckTFEVariableiSetVariableAttributes( + variable *tfe.VariableSetVariable) resource.TestCheckFunc { + return func(s *terraform.State) error { + if variable.Key != "key_test" { + return fmt.Errorf("Bad key: %s", variable.Key) + } + + if variable.Value != "value_test" { + return fmt.Errorf("Bad value: %s", variable.Value) + } + + if variable.Description != "some description" { + return fmt.Errorf("Bad description: %s", variable.Description) + } + + if variable.Category != tfe.CategoryEnv { + return fmt.Errorf("Bad category: %s", variable.Category) + } + + if variable.HCL != false { + return fmt.Errorf("Bad HCL: %t", variable.HCL) + } + + if variable.Sensitive != false { + return fmt.Errorf("Bad sensitive: %t", variable.Sensitive) + } + + return nil + } +} + func testAccCheckTFEVariableAttributesUpdate( variable *tfe.Variable) resource.TestCheckFunc { return func(s *terraform.State) error { From 917a235a7ca5ca53ea850518be61acba8e623253 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Wed, 9 Mar 2022 10:18:28 -0500 Subject: [PATCH 13/31] further refinement, still buggy --- tfe/data_source_variable_set_test.go | 10 +++++----- tfe/data_source_variables.go | 4 ++-- tfe/provider.go | 2 ++ tfe/resource_tfe_variable.go | 23 +++++++++++++---------- tfe/resource_tfe_variable_set.go | 15 ++++++++++----- tfe/resource_tfe_variable_set_test.go | 14 +++++++------- 6 files changed, 39 insertions(+), 29 deletions(-) diff --git a/tfe/data_source_variable_set_test.go b/tfe/data_source_variable_set_test.go index 6b37fb6e5..c30accfd9 100644 --- a/tfe/data_source_variable_set_test.go +++ b/tfe/data_source_variable_set_test.go @@ -28,11 +28,11 @@ func TestAccTFEVariableSetsDataSource_basic(t *testing.T) { resource.TestCheckResourceAttr( "data.tfe_variable_set.foobar", "global", "false"), resource.TestCheckResourceAttr( - "data.tfe_variable_set.foobar", "organizaiton", orgName), + "data.tfe_variable_set.foobar", "organization", orgName), resource.TestCheckResourceAttr( - "data.tfe_variable_set.foobar", "workspaces.0", fmt.Sprintf("workspace-foo-%d", rInt)), + "data.tfe_variable_set.foobar", "workspaces.#", "1"), resource.TestCheckResourceAttr( - "data.tfe_variable_set.foobar", "variables.#", "1"), + "data.tfe_variable_set.foobar", "vars.#", "1"), ), }, }, @@ -56,7 +56,7 @@ resource "tfe_variable_set" "foobar" { name = "varset-foo-%d" description = "a description" organization = tfe_organization.foobar.id - workspace = [tfe_workspace.foobar.id] + workspaces = [tfe_workspace.foobar.id] } resource "tfe_variable" "envfoo" { @@ -66,7 +66,7 @@ resource "tfe_variable" "envfoo" { variable_set_id = tfe_variable_set.foobar.id } -data "tfe_variable" "foobar" { +data "tfe_variable_set" "foobar" { name = tfe_variable_set.foobar.name organization = tfe_variable_set.foobar.organization }`, rInt, rInt, rInt) diff --git a/tfe/data_source_variables.go b/tfe/data_source_variables.go index 16fdc78ad..480d525ee 100644 --- a/tfe/data_source_variables.go +++ b/tfe/data_source_variables.go @@ -63,12 +63,12 @@ func dataSourceTFEWorkspaceVariables() *schema.Resource { }, "workspace_id": { Type: schema.TypeString, - Required: false, + Optional: true, ExactlyOneOf: []string{"workspace_id", "variable_set_id"}, }, "variable_set_id": { Type: schema.TypeString, - Required: false, + Optional: true, ExactlyOneOf: []string{"workspace_id", "variable_set_id"}, }, }, diff --git a/tfe/provider.go b/tfe/provider.go index 32343106a..5290960b8 100644 --- a/tfe/provider.go +++ b/tfe/provider.go @@ -90,6 +90,7 @@ func Provider() *schema.Provider { "tfe_workspace": dataSourceTFEWorkspace(), "tfe_workspace_ids": dataSourceTFEWorkspaceIDs(), "tfe_variables": dataSourceTFEWorkspaceVariables(), + "tfe_variable_set": dataSourceTFEVariableSet(), }, ResourcesMap: map[string]*schema.Resource{ @@ -116,6 +117,7 @@ func Provider() *schema.Provider { "tfe_terraform_version": resourceTFETerraformVersion(), "tfe_workspace": resourceTFEWorkspace(), "tfe_variable": resourceTFEVariable(), + "tfe_variable_set": resourceTFEVariableSet(), }, ConfigureFunc: providerConfigure, diff --git a/tfe/resource_tfe_variable.go b/tfe/resource_tfe_variable.go index 7b591cda6..8026425f0 100644 --- a/tfe/resource_tfe_variable.go +++ b/tfe/resource_tfe_variable.go @@ -76,6 +76,7 @@ func resourceTFEVariable() *schema.Resource { "workspace_id": { Type: schema.TypeString, Optional: true, + Required: false, ForceNew: true, ExactlyOneOf: []string{"workspace_id", "variable_set_id"}, ValidateFunc: validation.StringMatch( @@ -87,6 +88,7 @@ func resourceTFEVariable() *schema.Resource { "variable_set_id": { Type: schema.TypeString, Optional: true, + Required: false, ForceNew: true, ExactlyOneOf: []string{"workspace_id", "variable_set_id"}, ValidateFunc: validation.StringMatch( @@ -261,14 +263,15 @@ func resourceTFEVariableSetVariableRead(d *schema.ResourceData, meta interface{} } log.Printf("[DEBUG] Read variable: %s", d.Id()) - variable, errr := tfeClient.VariableSetVariables.Read(ctx, vs.ID, d.Id()) + var variable *tfe.VariableSetVariable + variable, err = tfeClient.VariableSetVariables.Read(ctx, vs.ID, d.Id()) if err != nil { - if errr == tfe.ErrResourceNotFound { + if err == tfe.ErrResourceNotFound { log.Printf("[DEBUG] Variable %s does no longer exist", d.Id()) d.SetId("") return nil } - return fmt.Errorf("Error reading variable %s: %v", d.Id(), errr) + return fmt.Errorf("Error reading variable %s: %v", d.Id(), err) } // Update config. @@ -313,9 +316,9 @@ func resourceTFEVariableUpdate(d *schema.ResourceData, meta interface{}) error { } log.Printf("[DEBUG] Update variable: %s", d.Id()) - _, errr := tfeClient.Variables.Update(ctx, ws.ID, d.Id(), options) - if errr != nil { - return fmt.Errorf("Error updating variable %s: %v", d.Id(), errr) + _, err = tfeClient.Variables.Update(ctx, ws.ID, d.Id(), options) + if err != nil { + return fmt.Errorf("Error updating variable %s: %v", d.Id(), err) } return resourceTFEVariableRead(d, meta) @@ -342,9 +345,9 @@ func resourceTFEVariableSetVariableUpdate(d *schema.ResourceData, meta interface } log.Printf("[DEBUG] Update variable: %s", d.Id()) - _, errr := tfeClient.VariableSetVariables.Update(ctx, vs.ID, d.Id(), &options) - if errr != nil { - return fmt.Errorf("Error updating variable %s: %v", d.Id(), errr) + _, err = tfeClient.VariableSetVariables.Update(ctx, vs.ID, d.Id(), &options) + if err != nil { + return fmt.Errorf("Error updating variable %s: %v", d.Id(), err) } return resourceTFEVariableRead(d, meta) @@ -383,7 +386,7 @@ func resourceTFEVariableSetVariableDelete(d *schema.ResourceData, meta interface tfeClient := meta.(*tfe.Client) // Get the variable set. - variableSetID := d.Get("variable_set__id").(string) + variableSetID := d.Get("variable_set_id").(string) vs, err := tfeClient.VariableSets.Read(ctx, variableSetID, nil) if err != nil { return fmt.Errorf( diff --git a/tfe/resource_tfe_variable_set.go b/tfe/resource_tfe_variable_set.go index 4e1aff7e3..0fc058754 100644 --- a/tfe/resource_tfe_variable_set.go +++ b/tfe/resource_tfe_variable_set.go @@ -116,8 +116,13 @@ func resourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) error d.Set("name", variableSet.Name) d.Set("description", variableSet.Description) d.Set("global", variableSet.Global) - d.Set("organization", variableSet.Organization) - d.Set("workspaces", variableSet.Workspaces) + d.Set("organization", variableSet.Organization.Name) + + var wids []interface{} + for _, workspace := range variableSet.Workspaces { + wids = append(wids, workspace.ID) + } + d.Set("workspaces", wids) return nil } @@ -148,10 +153,10 @@ func resourceTFEVariableSetUpdate(d *schema.ResourceData, meta interface{}) erro } log.Printf("[DEBUG] Assign variable set %s to workspaces %v", id, workspaceIDs) - vs, errr := tfeClient.VariableSets.Assign(ctx, id, &assignOptions) - if errr != nil { + vs, err := tfeClient.VariableSets.Assign(ctx, id, &assignOptions) + if err != nil { return fmt.Errorf( - "Error assigning variable set %s (%s) to given workspaces: %v", vs.Name, id, errr) + "Error assigning variable set %s (%s) to given workspaces: %v", vs.Name, id, err) } } diff --git a/tfe/resource_tfe_variable_set_test.go b/tfe/resource_tfe_variable_set_test.go index a2525659d..ced984f31 100644 --- a/tfe/resource_tfe_variable_set_test.go +++ b/tfe/resource_tfe_variable_set_test.go @@ -27,7 +27,7 @@ func TestAccTFEVariableSet_basic(t *testing.T) { "tfe_variable_set.foobar", variableSet), testAccCheckTFEVariableSetAttributes(variableSet), resource.TestCheckResourceAttr( - "tfe_variable_set.foobar", "name", "foobar"), + "tfe_variable_set.foobar", "name", "variable_set_test"), resource.TestCheckResourceAttr( "tfe_variable_set.foobar", "description", "a test variable set"), resource.TestCheckResourceAttr( @@ -57,7 +57,7 @@ func TestAccTFEVariableSet_update(t *testing.T) { "tfe_variable_set.foobar", variableSet), testAccCheckTFEVariableSetAttributes(variableSet), resource.TestCheckResourceAttr( - "tfe_variable_set.foobar", "name", "foobar"), + "tfe_variable_set.foobar", "name", "variable_set_test"), resource.TestCheckResourceAttr( "tfe_variable_set.foobar", "description", "a test variable set"), resource.TestCheckResourceAttr( @@ -98,7 +98,7 @@ func TestAccTFEVariableSet_import(t *testing.T) { { ResourceName: "tfe_variable_set.foobar", ImportState: true, - ImportStateIdPrefix: fmt.Sprintf("tst-terraform-%d/workspace-test/", rInt), + ImportStateIdPrefix: "", ImportStateVerify: true, }, }, @@ -225,14 +225,14 @@ resource "tfe_variable_set" "foobar" { name = "variable_set_test" description = "a test variable set" global = false - organizaiton = tfe_organizatoin.foobar.id + organization = tfe_organization.foobar.id } resource "tfe_variable_set" "assigned" { name = "variable_set_assigned" description = "a test variable set" workspaces = [tfe_workspace.foobar.id] - organizaiton = tfe_organizatoin.foobar.id + organization = tfe_organization.foobar.id }`, rInt) } @@ -252,13 +252,13 @@ resource "tfe_variable_set" "foobar" { name = "variable_set_test_updated" description = "another description" global = true - organizaiton = tfe_organizatoin.foobar.id + organization = tfe_organization.foobar.id } resource "tfe_variable_set" "assigned" { name = "variable_set_assigned" description = "a test variable set" workspaces = [] - organizaiton = tfe_organizatoin.foobar.id + organization = tfe_organization.foobar.id }`, rInt) } From 59818cc7e0840e31a9d0deb654a690ee86e1710b Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Mon, 14 Mar 2022 15:23:49 -0400 Subject: [PATCH 14/31] More test fixes --- tfe/data_source_variable_set_test.go | 2 +- tfe/resource_tfe_variable_set.go | 5 +++-- tfe/resource_tfe_variable_set_test.go | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tfe/data_source_variable_set_test.go b/tfe/data_source_variable_set_test.go index c30accfd9..c5475d5f6 100644 --- a/tfe/data_source_variable_set_test.go +++ b/tfe/data_source_variable_set_test.go @@ -11,7 +11,7 @@ import ( func TestAccTFEVariableSetsDataSource_basic(t *testing.T) { rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() - orgName := fmt.Sprintf("tst-terraform-%d", rInt) + orgName := fmt.Sprintf("org-%d", rInt) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, diff --git a/tfe/resource_tfe_variable_set.go b/tfe/resource_tfe_variable_set.go index 0fc058754..7ac8faf2a 100644 --- a/tfe/resource_tfe_variable_set.go +++ b/tfe/resource_tfe_variable_set.go @@ -148,15 +148,16 @@ func resourceTFEVariableSetUpdate(d *schema.ResourceData, meta interface{}) erro if d.HasChanges("workspaces") { workspaceIDs := d.Get("workspaces") assignOptions := tfe.VariableSetAssignOptions{} + assignOptions.Workspaces = []*tfe.Workspace{} for _, workspaceID := range workspaceIDs.(*schema.Set).List() { assignOptions.Workspaces = append(assignOptions.Workspaces, &tfe.Workspace{ID: workspaceID.(string)}) } log.Printf("[DEBUG] Assign variable set %s to workspaces %v", id, workspaceIDs) - vs, err := tfeClient.VariableSets.Assign(ctx, id, &assignOptions) + _, err := tfeClient.VariableSets.Assign(ctx, id, &assignOptions) if err != nil { return fmt.Errorf( - "Error assigning variable set %s (%s) to given workspaces: %v", vs.Name, id, err) + "Error assigning variable set %s to given workspaces: %v", id, err) } } diff --git a/tfe/resource_tfe_variable_set_test.go b/tfe/resource_tfe_variable_set_test.go index ced984f31..c2812dbaa 100644 --- a/tfe/resource_tfe_variable_set_test.go +++ b/tfe/resource_tfe_variable_set_test.go @@ -212,7 +212,7 @@ func testAccCheckTFEVariableSetDestroy(s *terraform.State) error { func testAccTFEVariableSet_basic(rInt int) string { return fmt.Sprintf(` resource "tfe_organization" "foobar" { - name = "tft-terraform-%d" + name = "tst-terraform-%d" email = "admin@company.com" } From 02bd402307f77d703e4e41b86226ef9294653883 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Tue, 15 Mar 2022 12:57:20 -0400 Subject: [PATCH 15/31] Remove unused vars logic --- tfe/data_source_variable_set.go | 13 ------------- tfe/resource_tfe_variable_test.go | 2 +- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/tfe/data_source_variable_set.go b/tfe/data_source_variable_set.go index 7cc456927..5b17c66b3 100644 --- a/tfe/data_source_variable_set.go +++ b/tfe/data_source_variable_set.go @@ -38,13 +38,6 @@ func dataSourceTFEVariableSet() *schema.Resource { Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, - - "vars": { - Type: schema.TypeSet, - Optional: true, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, }, } } @@ -92,12 +85,6 @@ func dataSourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) erro } d.Set("workspaces", workspaces) - var vars []interface{} - for _, v := range vs.Workspaces { - vars = append(vars, v.ID) - } - d.Set("vars", vars) - d.SetId(vs.ID) return nil } diff --git a/tfe/resource_tfe_variable_test.go b/tfe/resource_tfe_variable_test.go index 502fc65c5..437313854 100644 --- a/tfe/resource_tfe_variable_test.go +++ b/tfe/resource_tfe_variable_test.go @@ -466,7 +466,7 @@ resource "tfe_variable" "foobar" { value = "value_test" description = "some description" category = "env" - variable_set_id = tfe_varaible_set.foobar.id + variable_set_id = tfe_variable_set.foobar.id }`, rInt) } From 690c2cf36ce8407abb59ff6408148a4e64adc449 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Wed, 23 Mar 2022 18:33:35 -0400 Subject: [PATCH 16/31] use pointers in varet related data sources --- tfe/data_source_variable_set.go | 2 +- tfe/data_source_variables.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tfe/data_source_variable_set.go b/tfe/data_source_variable_set.go index 5b17c66b3..d15679f18 100644 --- a/tfe/data_source_variable_set.go +++ b/tfe/data_source_variable_set.go @@ -71,7 +71,7 @@ func dataSourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) erro //Only now include vars and workspaces to cut down on request load. readOptions := tfe.VariableSetReadOptions{ - Include: &[]tfe.VariableSetIncludeOps{tfe.VariableSetWorkspaces, tfe.VariableSetVars}, + Include: &[]tfe.VariableSetIncludeOpt{tfe.VariableSetWorkspaces, tfe.VariableSetVars}, } vs, err = tfeClient.VariableSets.Read(ctx, vs.ID, &readOptions) diff --git a/tfe/data_source_variables.go b/tfe/data_source_variables.go index 480d525ee..45ec0f181 100644 --- a/tfe/data_source_variables.go +++ b/tfe/data_source_variables.go @@ -95,7 +95,7 @@ func dataSourceVariableRead(d *schema.ResourceData, meta interface{}) error { options := tfe.VariableListOptions{} for { - variableList, err := tfeClient.Variables.List(ctx, workspaceID, options) + variableList, err := tfeClient.Variables.List(ctx, workspaceID, &options) if err != nil { return fmt.Errorf("Error retrieving variable list: %w", err) } From 100c706f7caae380d3eb71efcc4d7b9bebd6e334 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Wed, 23 Mar 2022 18:37:51 -0400 Subject: [PATCH 17/31] Use pointers and correct func refs for applying varsets to workspaces --- tfe/resource_tfe_variable_set.go | 24 ++++++++++++------------ tfe/resource_tfe_variable_set_test.go | 22 +++++++++++----------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/tfe/resource_tfe_variable_set.go b/tfe/resource_tfe_variable_set.go index 7ac8faf2a..6fbc5bf3c 100644 --- a/tfe/resource_tfe_variable_set.go +++ b/tfe/resource_tfe_variable_set.go @@ -76,17 +76,17 @@ func resourceTFEVariableSetCreate(d *schema.ResourceData, meta interface{}) erro } if workspaceIDs, workspacesSet := d.GetOk("workspaces"); !*options.Global && workspacesSet { - log.Printf("[DEBUG] Assign variable set %s to workspaces %v", name, workspaceIDs) + log.Printf("[DEBUG] Apply variable set %s to workspaces %v", name, workspaceIDs) - assignOptions := tfe.VariableSetAssignOptions{} + applyOptions := tfe.VariableSetUpdateWorkspacesOptions{} for _, workspaceID := range workspaceIDs.(*schema.Set).List() { - assignOptions.Workspaces = append(assignOptions.Workspaces, &tfe.Workspace{ID: workspaceID.(string)}) + applyOptions.Workspaces = append(applyOptions.Workspaces, &tfe.Workspace{ID: workspaceID.(string)}) } - variableSet, err = tfeClient.VariableSets.Assign(ctx, variableSet.ID, &assignOptions) + variableSet, err = tfeClient.VariableSets.UpdateWorkspaces(ctx, variableSet.ID, &applyOptions) if err != nil { return fmt.Errorf( - "Error assigning variable set %s (%s) to given workspaces: %v", name, variableSet.ID, err) + "Error applying variable set %s (%s) to given workspaces: %v", name, variableSet.ID, err) } } @@ -101,7 +101,7 @@ func resourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) error id := d.Id() log.Printf("[DEBUG] Read configuration of variable set: %s", id) variableSet, err := tfeClient.VariableSets.Read(ctx, id, &tfe.VariableSetReadOptions{ - Include: &[]tfe.VariableSetIncludeOps{tfe.VariableSetWorkspaces}, + Include: &[]tfe.VariableSetIncludeOpt{tfe.VariableSetWorkspaces}, }) if err != nil { if err == tfe.ErrResourceNotFound { @@ -147,17 +147,17 @@ func resourceTFEVariableSetUpdate(d *schema.ResourceData, meta interface{}) erro if d.HasChanges("workspaces") { workspaceIDs := d.Get("workspaces") - assignOptions := tfe.VariableSetAssignOptions{} - assignOptions.Workspaces = []*tfe.Workspace{} + applyOptions := tfe.VariableSetUpdateWorkspacesOptions{} + applyOptions.Workspaces = []*tfe.Workspace{} for _, workspaceID := range workspaceIDs.(*schema.Set).List() { - assignOptions.Workspaces = append(assignOptions.Workspaces, &tfe.Workspace{ID: workspaceID.(string)}) + applyOptions.Workspaces = append(applyOptions.Workspaces, &tfe.Workspace{ID: workspaceID.(string)}) } - log.Printf("[DEBUG] Assign variable set %s to workspaces %v", id, workspaceIDs) - _, err := tfeClient.VariableSets.Assign(ctx, id, &assignOptions) + log.Printf("[DEBUG] Apply variable set %s to workspaces %v", id, workspaceIDs) + _, err := tfeClient.VariableSets.UpdateWorkspaces(ctx, id, &applyOptions) if err != nil { return fmt.Errorf( - "Error assigning variable set %s to given workspaces: %v", id, err) + "Error applying variable set %s to given workspaces: %v", id, err) } } diff --git a/tfe/resource_tfe_variable_set_test.go b/tfe/resource_tfe_variable_set_test.go index c2812dbaa..8b276563f 100644 --- a/tfe/resource_tfe_variable_set_test.go +++ b/tfe/resource_tfe_variable_set_test.go @@ -33,8 +33,8 @@ func TestAccTFEVariableSet_basic(t *testing.T) { resource.TestCheckResourceAttr( "tfe_variable_set.foobar", "global", "false"), testAccCheckTFEVariableSetExists( - "tfe_variable_set.assigned", variableSet), - testAccCheckTFEVariableSetAssignment(variableSet), + "tfe_variable_set.applied", variableSet), + testAccCheckTFEVariableSetApplication(variableSet), ), }, }, @@ -122,7 +122,7 @@ func testAccCheckTFEVariableSetExists( vs, err := tfeClient.VariableSets.Read( ctx, rs.Primary.ID, - &tfe.VariableSetReadOptions{&[]tfe.VariableSetIncludeOps{tfe.VariableSetWorkspaces}}, + &tfe.VariableSetReadOptions{Include: &[]tfe.VariableSetIncludeOpt{tfe.VariableSetWorkspaces}}, ) if err != nil { return err @@ -168,20 +168,20 @@ func testAccCheckTFEVariableSetAttributesUpdate( } } -func testAccCheckTFEVariableSetAssignment(variableSet *tfe.VariableSet) resource.TestCheckFunc { +func testAccCheckTFEVariableSetAplication(variableSet *tfe.VariableSet) resource.TestCheckFunc { return func(s *terraform.State) error { if len(variableSet.Workspaces) != 1 { - return fmt.Errorf("Bad workspace assignment: %v", variableSet.Workspaces) + return fmt.Errorf("Bad workspace apply: %v", variableSet.Workspaces) } return nil } } -func testAccCheckTFEVariableSetAssignmentUpdate(variableSet *tfe.VariableSet) resource.TestCheckFunc { +func testAccCheckTFEVariableSetApplicationUpdate(variableSet *tfe.VariableSet) resource.TestCheckFunc { return func(s *terraform.State) error { if len(variableSet.Workspaces) != 0 { - return fmt.Errorf("Bad workspace assignment: %v", variableSet.Workspaces) + return fmt.Errorf("Bad workspace apply: %v", variableSet.Workspaces) } return nil @@ -228,8 +228,8 @@ resource "tfe_variable_set" "foobar" { organization = tfe_organization.foobar.id } -resource "tfe_variable_set" "assigned" { - name = "variable_set_assigned" +resource "tfe_variable_set" "applied" { + name = "variable_set_applied" description = "a test variable set" workspaces = [tfe_workspace.foobar.id] organization = tfe_organization.foobar.id @@ -255,8 +255,8 @@ resource "tfe_variable_set" "foobar" { organization = tfe_organization.foobar.id } -resource "tfe_variable_set" "assigned" { - name = "variable_set_assigned" +resource "tfe_variable_set" "applied" { + name = "variable_set_applied" description = "a test variable set" workspaces = [] organization = tfe_organization.foobar.id From 5d2f59999474b389b461bbe5643dda287626bf8f Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Wed, 23 Mar 2022 18:56:29 -0400 Subject: [PATCH 18/31] pointer and ref fixes --- tfe/data_source_variables.go | 2 +- tfe/resource_tfe_variable_set_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tfe/data_source_variables.go b/tfe/data_source_variables.go index 45ec0f181..480d525ee 100644 --- a/tfe/data_source_variables.go +++ b/tfe/data_source_variables.go @@ -95,7 +95,7 @@ func dataSourceVariableRead(d *schema.ResourceData, meta interface{}) error { options := tfe.VariableListOptions{} for { - variableList, err := tfeClient.Variables.List(ctx, workspaceID, &options) + variableList, err := tfeClient.Variables.List(ctx, workspaceID, options) if err != nil { return fmt.Errorf("Error retrieving variable list: %w", err) } diff --git a/tfe/resource_tfe_variable_set_test.go b/tfe/resource_tfe_variable_set_test.go index 8b276563f..2b334985b 100644 --- a/tfe/resource_tfe_variable_set_test.go +++ b/tfe/resource_tfe_variable_set_test.go @@ -168,7 +168,7 @@ func testAccCheckTFEVariableSetAttributesUpdate( } } -func testAccCheckTFEVariableSetAplication(variableSet *tfe.VariableSet) resource.TestCheckFunc { +func testAccCheckTFEVariableSetApplication(variableSet *tfe.VariableSet) resource.TestCheckFunc { return func(s *terraform.State) error { if len(variableSet.Workspaces) != 1 { return fmt.Errorf("Bad workspace apply: %v", variableSet.Workspaces) From 362e6bb7b15459270777e368ec5ce2c336766073 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Wed, 23 Mar 2022 18:57:14 -0400 Subject: [PATCH 19/31] Ref go-tfe 1.1.0 - varsets --- go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 0f4ad081b..aafdb355e 100644 --- a/go.mod +++ b/go.mod @@ -12,8 +12,8 @@ require ( github.com/hashicorp/go-hclog v0.16.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.0 // indirect - github.com/hashicorp/go-slug v0.7.0 - github.com/hashicorp/go-tfe v0.25.0 + github.com/hashicorp/go-slug v0.8.0 + github.com/hashicorp/go-tfe v1.1.0 github.com/hashicorp/go-version v1.4.0 github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce github.com/hashicorp/hcl/v2 v2.10.0 // indirect From b5ee65276abb1ab4324bb70559463e76e631c09a Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Thu, 24 Mar 2022 12:05:39 -0400 Subject: [PATCH 20/31] Support variables in varset datasources --- tfe/data_source_variable_set.go | 13 +++++++++++++ tfe/data_source_variable_set_test.go | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/tfe/data_source_variable_set.go b/tfe/data_source_variable_set.go index d15679f18..179f31ee1 100644 --- a/tfe/data_source_variable_set.go +++ b/tfe/data_source_variable_set.go @@ -38,6 +38,13 @@ func dataSourceTFEVariableSet() *schema.Resource { Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, + + "variables": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, }, } } @@ -85,6 +92,12 @@ func dataSourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) erro } d.Set("workspaces", workspaces) + var variables []interface{} + for _, variable := range vs.Variables { + variables = append(variables, variable.ID) + } + d.Set("variables", variables) + d.SetId(vs.ID) return nil } diff --git a/tfe/data_source_variable_set_test.go b/tfe/data_source_variable_set_test.go index c5475d5f6..85a6dd979 100644 --- a/tfe/data_source_variable_set_test.go +++ b/tfe/data_source_variable_set_test.go @@ -32,7 +32,7 @@ func TestAccTFEVariableSetsDataSource_basic(t *testing.T) { resource.TestCheckResourceAttr( "data.tfe_variable_set.foobar", "workspaces.#", "1"), resource.TestCheckResourceAttr( - "data.tfe_variable_set.foobar", "vars.#", "1"), + "data.tfe_variable_set.foobar", "variables.#", "1"), ), }, }, From 3b32606e0d67a6b7fc294beb5a71d82d320bf50c Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Thu, 24 Mar 2022 14:23:30 -0400 Subject: [PATCH 21/31] style tweaks --- tfe/data_source_variables.go | 2 +- tfe/resource_tfe_variable.go | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tfe/data_source_variables.go b/tfe/data_source_variables.go index fe688a91b..d0ba0d138 100644 --- a/tfe/data_source_variables.go +++ b/tfe/data_source_variables.go @@ -138,7 +138,7 @@ func dataSourceVariableRead(d *schema.ResourceData, meta interface{}) error { func dataSourceVariableSetVariableRead(d *schema.ResourceData, meta interface{}) error { tfeClient := meta.(*tfe.Client) - // Get the name and organization. + // Get the id. variableSetId := d.Get("variable_set_id").(string) log.Printf("[DEBUG] Read configuration of variable set: %s", variableSetId) diff --git a/tfe/resource_tfe_variable.go b/tfe/resource_tfe_variable.go index 8026425f0..1ece2a246 100644 --- a/tfe/resource_tfe_variable.go +++ b/tfe/resource_tfe_variable.go @@ -263,8 +263,7 @@ func resourceTFEVariableSetVariableRead(d *schema.ResourceData, meta interface{} } log.Printf("[DEBUG] Read variable: %s", d.Id()) - var variable *tfe.VariableSetVariable - variable, err = tfeClient.VariableSetVariables.Read(ctx, vs.ID, d.Id()) + variable, err := tfeClient.VariableSetVariables.Read(ctx, vs.ID, d.Id()) if err != nil { if err == tfe.ErrResourceNotFound { log.Printf("[DEBUG] Variable %s does no longer exist", d.Id()) From b67577bbba0a2b4deb2db70986c72913a98a8759 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Thu, 24 Mar 2022 16:54:46 -0400 Subject: [PATCH 22/31] Reference go-tfe version that has varsets --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index a3bfda1d5..08418e056 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.0 // indirect github.com/hashicorp/go-slug v0.8.0 - github.com/hashicorp/go-tfe v1.0.0 + github.com/hashicorp/go-tfe v1.0.1-0.20220324182532-e004de0557a8 github.com/hashicorp/go-version v1.4.0 github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce github.com/hashicorp/hcl/v2 v2.10.0 // indirect diff --git a/go.sum b/go.sum index c9ac94ce8..68dde0a21 100644 --- a/go.sum +++ b/go.sum @@ -228,6 +228,8 @@ github.com/hashicorp/go-tfe v1.0.0-rc1 h1:ZUAfDF5en/oayJJByxm3lQCsIRbCPNpf9RqBFh github.com/hashicorp/go-tfe v1.0.0-rc1/go.mod h1:gyXLXbpBVxA2F/6opah8XBsOkZJxHYQmghl0OWi8keI= github.com/hashicorp/go-tfe v1.0.0 h1:CmwoHrOs7WJfD/yEmVjJ65+dyKeVRrgvRHBLVSQQ6Ks= github.com/hashicorp/go-tfe v1.0.0/go.mod h1:tJF/OlAXzVbmjiimAPLplSLgwg6kZDUOy0MzHuMwvF4= +github.com/hashicorp/go-tfe v1.0.1-0.20220324182532-e004de0557a8 h1:ekTBuuEK8nIeiYanudVRYzFd2hpIDVkMbgIaes3KeTg= +github.com/hashicorp/go-tfe v1.0.1-0.20220324182532-e004de0557a8/go.mod h1:tJF/OlAXzVbmjiimAPLplSLgwg6kZDUOy0MzHuMwvF4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= From 8533d09fd3fe1622a635abff2725a9ebb8a79afb Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Fri, 25 Mar 2022 16:49:38 -0400 Subject: [PATCH 23/31] More specific ID naming in varset datasource --- tfe/data_source_variable_set.go | 8 ++-- tfe/data_source_variable_set_test.go | 43 +++++++++++++++++++++- website/docs/d/variable_sets.html.markdown | 4 +- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/tfe/data_source_variable_set.go b/tfe/data_source_variable_set.go index 179f31ee1..d6d2f2d05 100644 --- a/tfe/data_source_variable_set.go +++ b/tfe/data_source_variable_set.go @@ -32,14 +32,14 @@ func dataSourceTFEVariableSet() *schema.Resource { Computed: true, }, - "workspaces": { + "workspace_ids": { Type: schema.TypeSet, Optional: true, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, - "variables": { + "variable_ids": { Type: schema.TypeSet, Optional: true, Computed: true, @@ -90,13 +90,13 @@ func dataSourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) erro for _, workspace := range vs.Workspaces { workspaces = append(workspaces, workspace.ID) } - d.Set("workspaces", workspaces) + d.Set("workspace_ids", workspaces) var variables []interface{} for _, variable := range vs.Variables { variables = append(variables, variable.ID) } - d.Set("variables", variables) + d.Set("variable_ids", variables) d.SetId(vs.ID) return nil diff --git a/tfe/data_source_variable_set_test.go b/tfe/data_source_variable_set_test.go index 85a6dd979..2c34d3676 100644 --- a/tfe/data_source_variable_set_test.go +++ b/tfe/data_source_variable_set_test.go @@ -29,10 +29,30 @@ func TestAccTFEVariableSetsDataSource_basic(t *testing.T) { "data.tfe_variable_set.foobar", "global", "false"), resource.TestCheckResourceAttr( "data.tfe_variable_set.foobar", "organization", orgName), + ), + }, + }, + }, + ) +} + +func TestAccTFEVariableSetsDataSource_full(t *testing.T) { + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccTFEVariableSetsDataSourceConfig_full(rInt), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("data.tfe_variable_set.foobar", "id"), + resource.TestCheckResourceAttr( + "data.tfe_variable_set.foobar", "name", fmt.Sprintf("varset-foo-%d", rInt)), resource.TestCheckResourceAttr( - "data.tfe_variable_set.foobar", "workspaces.#", "1"), + "data.tfe_variable_set.foobar", "workspace_ids.#", "1"), resource.TestCheckResourceAttr( - "data.tfe_variable_set.foobar", "variables.#", "1"), + "data.tfe_variable_set.foobar", "variable_ids.#", "1"), ), }, }, @@ -47,6 +67,25 @@ resource "tfe_organization" "foobar" { email = "admin@company.com" } +resource "tfe_variable_set" "foobar" { + name = "varset-foo-%d" + description = "a description" + organization = tfe_organization.foobar.id +} + +data "tfe_variable_set" "foobar" { + name = tfe_variable_set.foobar.name + organization = tfe_variable_set.foobar.organization +}`, rInt, rInt) +} + +func testAccTFEVariableSetsDataSourceConfig_full(rInt int) string { + return fmt.Sprintf(` +resource "tfe_organization" "foobar" { + name = "org-%d" + email = "admin@company.com" +} + resource "tfe_workspace" "foobar" { name = "workspace-foo-%d" organization = tfe_organization.foobar.id diff --git a/website/docs/d/variable_sets.html.markdown b/website/docs/d/variable_sets.html.markdown index 8fb31ff12..85c2d32f2 100644 --- a/website/docs/d/variable_sets.html.markdown +++ b/website/docs/d/variable_sets.html.markdown @@ -35,5 +35,5 @@ The following arguments are supported: * `name` - Name of the variable set. * `description` - Description of the variable set. * `global` - Whether or not the variable set applies to all workspaces in the organization. -* `workspaces` - IDs of the workspaces that use the variable set. -* `variables` - IDs of the variables attached to the variable set. +* `workspace_ids` - IDs of the workspaces that use the variable set. +* `variable_ids` - IDs of the variables attached to the variable set. From b5d4a74c74b0fa21a477986e81415ba39fb0e61d Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Fri, 25 Mar 2022 17:37:41 -0400 Subject: [PATCH 24/31] Split basic test into basic and full --- tfe/resource_tfe_variable_set_test.go | 46 +++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/tfe/resource_tfe_variable_set_test.go b/tfe/resource_tfe_variable_set_test.go index 2b334985b..7c7f01e2b 100644 --- a/tfe/resource_tfe_variable_set_test.go +++ b/tfe/resource_tfe_variable_set_test.go @@ -22,6 +22,33 @@ func TestAccTFEVariableSet_basic(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccTFEVariableSet_basic(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckTFEVariableSetExists( + "tfe_variable_set.foobar", variableSet), + testAccCheckTFEVariableSetAttributes(variableSet), + resource.TestCheckResourceAttr( + "tfe_variable_set.foobar", "name", "variable_set_test"), + resource.TestCheckResourceAttr( + "tfe_variable_set.foobar", "description", "a test variable set"), + resource.TestCheckResourceAttr( + "tfe_variable_set.foobar", "global", "true"), + ), + }, + }, + }) +} + +func TestAccTFEVariableSet_full(t *testing.T) { + variableSet := &tfe.VariableSet{} + rInt := rand.New(rand.NewSource(time.Now().UnixNano())).Int() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckTFEVariableSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTFEVariableSet_full(rInt), Check: resource.ComposeTestCheckFunc( testAccCheckTFEVariableSetExists( "tfe_variable_set.foobar", variableSet), @@ -61,7 +88,7 @@ func TestAccTFEVariableSet_update(t *testing.T) { resource.TestCheckResourceAttr( "tfe_variable_set.foobar", "description", "a test variable set"), resource.TestCheckResourceAttr( - "tfe_variable_set.foobar", "global", "false"), + "tfe_variable_set.foobar", "global", "true"), ), }, @@ -76,7 +103,7 @@ func TestAccTFEVariableSet_update(t *testing.T) { resource.TestCheckResourceAttr( "tfe_variable_set.foobar", "description", "another description"), resource.TestCheckResourceAttr( - "tfe_variable_set.foobar", "global", "true"), + "tfe_variable_set.foobar", "global", "false"), ), }, }, @@ -216,6 +243,21 @@ resource "tfe_organization" "foobar" { email = "admin@company.com" } +resource "tfe_variable_set" "foobar" { + name = "variable_set_test" + description = "a test variable set" + global = false + organization = tfe_organization.foobar.id +}`, rInt) +} + +func testAccTFEVariableSet_full(rInt int) string { + return fmt.Sprintf(` +resource "tfe_organization" "foobar" { + name = "tst-terraform-%d" + email = "admin@company.com" +} + resource "tfe_workspace" "foobar" { name = "foobar" organization = tfe_organization.foobar.id From 5b900b85a73c9f22282eee27413872b65afdefe5 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Fri, 25 Mar 2022 17:37:52 -0400 Subject: [PATCH 25/31] punctuation --- website/docs/d/variable_sets.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/d/variable_sets.html.markdown b/website/docs/d/variable_sets.html.markdown index 85c2d32f2..b0ecfca9f 100644 --- a/website/docs/d/variable_sets.html.markdown +++ b/website/docs/d/variable_sets.html.markdown @@ -8,7 +8,7 @@ description: |- # Data Source: tfe_variable_set -This data source is used to retrieve all variables defined in a specified workspace +This data source is used to retrieve all variables defined in a specified workspace. ## Example Usage From 4e3bd4d9e1ff725df8f91bf9384e48f05095725b Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Fri, 25 Mar 2022 17:52:13 -0400 Subject: [PATCH 26/31] Woops wrong test values --- tfe/resource_tfe_variable_set_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tfe/resource_tfe_variable_set_test.go b/tfe/resource_tfe_variable_set_test.go index 7c7f01e2b..405fa7604 100644 --- a/tfe/resource_tfe_variable_set_test.go +++ b/tfe/resource_tfe_variable_set_test.go @@ -88,7 +88,7 @@ func TestAccTFEVariableSet_update(t *testing.T) { resource.TestCheckResourceAttr( "tfe_variable_set.foobar", "description", "a test variable set"), resource.TestCheckResourceAttr( - "tfe_variable_set.foobar", "global", "true"), + "tfe_variable_set.foobar", "global", "false"), ), }, @@ -103,7 +103,7 @@ func TestAccTFEVariableSet_update(t *testing.T) { resource.TestCheckResourceAttr( "tfe_variable_set.foobar", "description", "another description"), resource.TestCheckResourceAttr( - "tfe_variable_set.foobar", "global", "false"), + "tfe_variable_set.foobar", "global", "true"), ), }, }, From 4c76a56ecdd9385434676fe16a4712dc6f4a7b60 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Fri, 25 Mar 2022 19:13:57 -0400 Subject: [PATCH 27/31] test fixes and workspaces to workspace_ids --- tfe/resource_tfe_variable_set.go | 12 ++++++------ tfe/resource_tfe_variable_set_test.go | 7 ++++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tfe/resource_tfe_variable_set.go b/tfe/resource_tfe_variable_set.go index 6fbc5bf3c..953a2ae9d 100644 --- a/tfe/resource_tfe_variable_set.go +++ b/tfe/resource_tfe_variable_set.go @@ -36,7 +36,7 @@ func resourceTFEVariableSet() *schema.Resource { Type: schema.TypeBool, Optional: true, Default: false, - ConflictsWith: []string{"workspaces"}, + ConflictsWith: []string{"workspace_ids"}, }, "organization": { @@ -45,7 +45,7 @@ func resourceTFEVariableSet() *schema.Resource { ForceNew: true, }, - "workspaces": { + "workspace_ids": { Type: schema.TypeSet, Optional: true, Computed: true, @@ -75,7 +75,7 @@ func resourceTFEVariableSetCreate(d *schema.ResourceData, meta interface{}) erro "Error creating variable set %s, for organization: %s: %v", name, organization, err) } - if workspaceIDs, workspacesSet := d.GetOk("workspaces"); !*options.Global && workspacesSet { + if workspaceIDs, workspacesSet := d.GetOk("workspace_ids"); !*options.Global && workspacesSet { log.Printf("[DEBUG] Apply variable set %s to workspaces %v", name, workspaceIDs) applyOptions := tfe.VariableSetUpdateWorkspacesOptions{} @@ -122,7 +122,7 @@ func resourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) error for _, workspace := range variableSet.Workspaces { wids = append(wids, workspace.ID) } - d.Set("workspaces", wids) + d.Set("workspace_ids", wids) return nil } @@ -145,8 +145,8 @@ func resourceTFEVariableSetUpdate(d *schema.ResourceData, meta interface{}) erro } } - if d.HasChanges("workspaces") { - workspaceIDs := d.Get("workspaces") + if d.HasChanges("workspace_ids") { + workspaceIDs := d.Get("workspace_ids") applyOptions := tfe.VariableSetUpdateWorkspacesOptions{} applyOptions.Workspaces = []*tfe.Workspace{} for _, workspaceID := range workspaceIDs.(*schema.Set).List() { diff --git a/tfe/resource_tfe_variable_set_test.go b/tfe/resource_tfe_variable_set_test.go index 405fa7604..afdf8d027 100644 --- a/tfe/resource_tfe_variable_set_test.go +++ b/tfe/resource_tfe_variable_set_test.go @@ -31,7 +31,7 @@ func TestAccTFEVariableSet_basic(t *testing.T) { resource.TestCheckResourceAttr( "tfe_variable_set.foobar", "description", "a test variable set"), resource.TestCheckResourceAttr( - "tfe_variable_set.foobar", "global", "true"), + "tfe_variable_set.foobar", "global", "false"), ), }, }, @@ -89,6 +89,7 @@ func TestAccTFEVariableSet_update(t *testing.T) { "tfe_variable_set.foobar", "description", "a test variable set"), resource.TestCheckResourceAttr( "tfe_variable_set.foobar", "global", "false"), + testAccCheckTFEVariableSetApplicationUpdate(variableSet), ), }, @@ -273,7 +274,7 @@ resource "tfe_variable_set" "foobar" { resource "tfe_variable_set" "applied" { name = "variable_set_applied" description = "a test variable set" - workspaces = [tfe_workspace.foobar.id] + workspace_ids = [tfe_workspace.foobar.id] organization = tfe_organization.foobar.id }`, rInt) } @@ -300,7 +301,7 @@ resource "tfe_variable_set" "foobar" { resource "tfe_variable_set" "applied" { name = "variable_set_applied" description = "a test variable set" - workspaces = [] + workspace_ids = [] organization = tfe_organization.foobar.id }`, rInt) } From 1064a22c40bd69b792a27ffd71cb92d5a83d967e Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Fri, 25 Mar 2022 19:17:06 -0400 Subject: [PATCH 28/31] tabs v spaces --- tfe/data_source_variables_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tfe/data_source_variables_test.go b/tfe/data_source_variables_test.go index 834b193aa..5302b8333 100644 --- a/tfe/data_source_variables_test.go +++ b/tfe/data_source_variables_test.go @@ -83,7 +83,7 @@ resource "tfe_variable" "envfoo" { data "tfe_variables" "workspace_foobar" { workspace_id = tfe_workspace.foobar.id depends_on = [ - tfe_variable.terrbar, + tfe_variable.terrbar, tfe_variable.envbar ] } @@ -91,7 +91,7 @@ data "tfe_variables" "workspace_foobar" { data "tfe_variables" "variable_set_foobar" { variable_set_id = tfe_variable_set.foobar.id depends_on = [ - tfe_variable.terrfoo, + tfe_variable.terrfoo, tfe_variable.envfoo ] } From 873a7ac83979722c38e9db679aa4e87e3ac1e92a Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Fri, 25 Mar 2022 19:37:01 -0400 Subject: [PATCH 29/31] light refactoring and addition of Description nil check --- tfe/resource_tfe_variable.go | 2 +- tfe/resource_tfe_variable_set.go | 38 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tfe/resource_tfe_variable.go b/tfe/resource_tfe_variable.go index 1ece2a246..46f279741 100644 --- a/tfe/resource_tfe_variable.go +++ b/tfe/resource_tfe_variable.go @@ -133,7 +133,7 @@ func resourceTFEVariableCreate(d *schema.ResourceData, meta interface{}) error { key := d.Get("key").(string) category := d.Get("category").(string) - // Get the workspace if workspace_id present + // Get the workspace workspaceID := d.Get("workspace_id").(string) ws, err := tfeClient.Workspaces.ReadByID(ctx, workspaceID) if err != nil { diff --git a/tfe/resource_tfe_variable_set.go b/tfe/resource_tfe_variable_set.go index 953a2ae9d..e500a91c0 100644 --- a/tfe/resource_tfe_variable_set.go +++ b/tfe/resource_tfe_variable_set.go @@ -64,9 +64,12 @@ func resourceTFEVariableSetCreate(d *schema.ResourceData, meta interface{}) erro // Create a new options struct. options := tfe.VariableSetCreateOptions{ - Name: tfe.String(name), - Description: tfe.String(d.Get("description").(string)), - Global: tfe.Bool(d.Get("global").(bool)), + Name: tfe.String(name), + Global: tfe.Bool(d.Get("global").(bool)), + } + + if description, descriptionSet := d.GetOk("description"); descriptionSet { + options.Description = tfe.String(description.(string)) } variableSet, err := tfeClient.VariableSets.Create(ctx, organization, &options) @@ -98,18 +101,17 @@ func resourceTFEVariableSetCreate(d *schema.ResourceData, meta interface{}) erro func resourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) error { tfeClient := meta.(*tfe.Client) - id := d.Id() - log.Printf("[DEBUG] Read configuration of variable set: %s", id) - variableSet, err := tfeClient.VariableSets.Read(ctx, id, &tfe.VariableSetReadOptions{ + log.Printf("[DEBUG] Read configuration of variable set: %s", d.Id()) + variableSet, err := tfeClient.VariableSets.Read(ctx, d.Id(), &tfe.VariableSetReadOptions{ Include: &[]tfe.VariableSetIncludeOpt{tfe.VariableSetWorkspaces}, }) if err != nil { if err == tfe.ErrResourceNotFound { - log.Printf("[DEBUG] Variable set %s no longer exists", id) + log.Printf("[DEBUG] Variable set %s no longer exists", d.Id()) d.SetId("") return nil } - return fmt.Errorf("Error reading configuration of variable set %s: %v", id, err) + return fmt.Errorf("Error reading configuration of variable set %s: %v", d.Id(), err) } // Update the config. @@ -129,7 +131,6 @@ func resourceTFEVariableSetRead(d *schema.ResourceData, meta interface{}) error func resourceTFEVariableSetUpdate(d *schema.ResourceData, meta interface{}) error { tfeClient := meta.(*tfe.Client) - id := d.Id() if d.HasChange("name") || d.HasChange("description") || d.HasChange("global") { options := tfe.VariableSetUpdateOptions{ @@ -138,10 +139,10 @@ func resourceTFEVariableSetUpdate(d *schema.ResourceData, meta interface{}) erro Global: tfe.Bool(d.Get("global").(bool)), } - log.Printf("[DEBUG] Update variable set: %s", id) - _, err := tfeClient.VariableSets.Update(ctx, id, &options) + log.Printf("[DEBUG] Update variable set: %s", d.Id()) + _, err := tfeClient.VariableSets.Update(ctx, d.Id(), &options) if err != nil { - return fmt.Errorf("Error updateing variable %s: %v", id, err) + return fmt.Errorf("Error updateing variable %s: %v", d.Id(), err) } } @@ -153,11 +154,11 @@ func resourceTFEVariableSetUpdate(d *schema.ResourceData, meta interface{}) erro applyOptions.Workspaces = append(applyOptions.Workspaces, &tfe.Workspace{ID: workspaceID.(string)}) } - log.Printf("[DEBUG] Apply variable set %s to workspaces %v", id, workspaceIDs) - _, err := tfeClient.VariableSets.UpdateWorkspaces(ctx, id, &applyOptions) + log.Printf("[DEBUG] Apply variable set %s to workspaces %v", d.Id(), workspaceIDs) + _, err := tfeClient.VariableSets.UpdateWorkspaces(ctx, d.Id(), &applyOptions) if err != nil { return fmt.Errorf( - "Error applying variable set %s to given workspaces: %v", id, err) + "Error applying variable set %s to given workspaces: %v", d.Id(), err) } } @@ -166,15 +167,14 @@ func resourceTFEVariableSetUpdate(d *schema.ResourceData, meta interface{}) erro func resourceTFEVariableSetDelete(d *schema.ResourceData, meta interface{}) error { tfeClient := meta.(*tfe.Client) - id := d.Id() - log.Printf("[DEBUG] Delete variable set: %s", id) - err := tfeClient.VariableSets.Delete(ctx, id) + log.Printf("[DEBUG] Delete variable set: %s", d.Id()) + err := tfeClient.VariableSets.Delete(ctx, d.Id()) if err != nil { if err == tfe.ErrResourceNotFound { return nil } - return fmt.Errorf("Error deleting variable set %s: %v", id, err) + return fmt.Errorf("Error deleting variable set %s: %v", d.Id(), err) } return nil From 9e0aa8448fbfd53a452e77b100f583ef55517382 Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Fri, 25 Mar 2022 19:42:27 -0400 Subject: [PATCH 30/31] reference go-tfe 1.1.0 --- go.mod | 2 +- go.sum | 22 ++-------------------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 08418e056..055788f44 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.0 // indirect github.com/hashicorp/go-slug v0.8.0 - github.com/hashicorp/go-tfe v1.0.1-0.20220324182532-e004de0557a8 + github.com/hashicorp/go-tfe v1.1.0 github.com/hashicorp/go-version v1.4.0 github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce github.com/hashicorp/hcl/v2 v2.10.0 // indirect diff --git a/go.sum b/go.sum index 68dde0a21..35b7a5f69 100644 --- a/go.sum +++ b/go.sum @@ -212,24 +212,10 @@ github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiw github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= -github.com/hashicorp/go-slug v0.7.0 h1:8HIi6oreWPtnhpYd8lIGQBgp4rXzDWQTOhfILZm+nok= -github.com/hashicorp/go-slug v0.7.0/go.mod h1:Ib+IWBYfEfJGI1ZyXMGNbu2BU+aa3Dzu41RKLH301v4= github.com/hashicorp/go-slug v0.8.0 h1:h7AGtXVAI/cJ/Wwa/JQQaftQnWQmZbAzkzgZeZVVmLw= github.com/hashicorp/go-slug v0.8.0/go.mod h1:Ib+IWBYfEfJGI1ZyXMGNbu2BU+aa3Dzu41RKLH301v4= -github.com/hashicorp/go-tfe v0.22.0 h1:FBK3LscU90EhQGS/p2NJJdJt2GzwiGNqHgex8SjZ+LM= -github.com/hashicorp/go-tfe v0.22.0/go.mod h1:gyXLXbpBVxA2F/6opah8XBsOkZJxHYQmghl0OWi8keI= -github.com/hashicorp/go-tfe v0.24.0 h1:7RyYTafFXGN6I6ayASJOpw6pARtKKSPdA9KRiovKQRM= -github.com/hashicorp/go-tfe v0.24.0/go.mod h1:gyXLXbpBVxA2F/6opah8XBsOkZJxHYQmghl0OWi8keI= -github.com/hashicorp/go-tfe v0.25.0 h1:eAqKG6hpxfjiw4KJheTeFhevov1avDPJFDDI0F/OAJU= -github.com/hashicorp/go-tfe v0.25.0/go.mod h1:gyXLXbpBVxA2F/6opah8XBsOkZJxHYQmghl0OWi8keI= -github.com/hashicorp/go-tfe v0.26.0 h1:6vQshg2NW5CkN4fkM64qhX+Z5Ua7ip74n8nAJRlhKKg= -github.com/hashicorp/go-tfe v0.26.0/go.mod h1:gyXLXbpBVxA2F/6opah8XBsOkZJxHYQmghl0OWi8keI= -github.com/hashicorp/go-tfe v1.0.0-rc1 h1:ZUAfDF5en/oayJJByxm3lQCsIRbCPNpf9RqBFhb3Crs= -github.com/hashicorp/go-tfe v1.0.0-rc1/go.mod h1:gyXLXbpBVxA2F/6opah8XBsOkZJxHYQmghl0OWi8keI= -github.com/hashicorp/go-tfe v1.0.0 h1:CmwoHrOs7WJfD/yEmVjJ65+dyKeVRrgvRHBLVSQQ6Ks= -github.com/hashicorp/go-tfe v1.0.0/go.mod h1:tJF/OlAXzVbmjiimAPLplSLgwg6kZDUOy0MzHuMwvF4= -github.com/hashicorp/go-tfe v1.0.1-0.20220324182532-e004de0557a8 h1:ekTBuuEK8nIeiYanudVRYzFd2hpIDVkMbgIaes3KeTg= -github.com/hashicorp/go-tfe v1.0.1-0.20220324182532-e004de0557a8/go.mod h1:tJF/OlAXzVbmjiimAPLplSLgwg6kZDUOy0MzHuMwvF4= +github.com/hashicorp/go-tfe v1.1.0 h1:MGMdaQDdB9sWMTXAWLpdRmi5djLALR6qS5o5MC2u3bQ= +github.com/hashicorp/go-tfe v1.1.0/go.mod h1:tJF/OlAXzVbmjiimAPLplSLgwg6kZDUOy0MzHuMwvF4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= @@ -569,10 +555,6 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 h1:GZokNIeuVkl3aZHJchRrr13WCsols02MLUcz1U9is6M= -golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From 566ebe5337b07b814face4fa98917ebd617ef18f Mon Sep 17 00:00:00 2001 From: Rexredinger Date: Sun, 27 Mar 2022 21:04:22 -0400 Subject: [PATCH 31/31] Update test data syntax --- tfe/data_source_variable_set_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tfe/data_source_variable_set_test.go b/tfe/data_source_variable_set_test.go index 2c34d3676..d4e49facd 100644 --- a/tfe/data_source_variable_set_test.go +++ b/tfe/data_source_variable_set_test.go @@ -95,7 +95,7 @@ resource "tfe_variable_set" "foobar" { name = "varset-foo-%d" description = "a description" organization = tfe_organization.foobar.id - workspaces = [tfe_workspace.foobar.id] + workspace_ids = [tfe_workspace.foobar.id] } resource "tfe_variable" "envfoo" {