terraform-provider-octopusdeploy icon indicating copy to clipboard operation
terraform-provider-octopusdeploy copied to clipboard

Modification of library variable set templates destroys existing tenants' values

Open nathanscottdaniels opened this issue 2 years ago • 0 comments

Describe the bug When adding or removing templates to a octopusdeploy_library_variable_set, [many of] the existing templates are destroyed and re-created, regardless of whether or not they changed in the plan. This results in any values that tenants have provided for those template variables being lost.

Steps to reproduce Refer to this example tf:

terraform {
  required_providers {
    octopusdeploy = {
      source = "OctopusDeployLabs/octopusdeploy"
    }
  }
}

provider "octopusdeploy" {
  address = "https://octopus.exampe.com"
  api_key = "API-YOUR_TOKEN_HERE"
}

resource "octopusdeploy_library_variable_set" "test" {
  name = "Test"
  template {
    name             = "foo"
    id               = "FOO"
    default_value    = "FOO"
  }

##  Uncomment and run again
#
#   template {
#     name             = "bar"
#     id               = "bar"
#     default_value    = "bar"
#   }

  template {
    name             = "baz"
    id               = "baz"
    default_value    = "baz"
  }
}
  1. Get you an octopus API token
  2. Place the above tf file into a directory, update the octopus connection fields, and run terraform init
  3. Execute terraform apply and create the library variable set.
  4. OPTIONAL: attach that new variable set to a project, associate a tenant, and provide a value for the baz variable for that tenant.
  5. Un-comment the bar template in the .tf file
  6. Re-run terraform apply
  7. Notice the plan output. The baz template is being changed into the bar template and a new baz template is being created.
  8. Notice that after applying, the tenant value applied to the baz template is now gone.
  9. OPTIONAL: re-comment the bar template and apply. Again, the baz template is destroyed and re-created.

Expected behavior I would expect the existing templates to be preserved. The octopus provider should detect that the baz template did not actually get removed, it merely changed its index within the list of templates. The name and id of the template did not change, which should be enough to match to baz template in the state with the baz template in the plan.

It appears terraform or the octopus provider uses only the index of the templates in the list to match state with config. This prevents users from adding new templates in the middle of the list, removing any but the last templates in the list, or re-ordering the templates.

Logs and other supporting information First run:

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # octopusdeploy_library_variable_set.test will be created
  + resource "octopusdeploy_library_variable_set" "test" {
      + id              = (known after apply)
      + name            = "Test"
      + space_id        = (known after apply)
      + variable_set_id = (known after apply)

      + template {
          + default_value = "FOO"
          + id            = "FOO"
          + name          = "foo"
        }
      + template {
          + default_value = "baz"
          + id            = "baz"
          + name          = "baz"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

octopusdeploy_library_variable_set.test: Creating...
octopusdeploy_library_variable_set.test: Creation complete after 0s [id=LibraryVariableSets-1005]
╵

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Second run:

octopusdeploy_library_variable_set.test: Refreshing state... [id=LibraryVariableSets-1005]

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply":

  # octopusdeploy_library_variable_set.test has changed
  ~ resource "octopusdeploy_library_variable_set" "test" {
        id              = "LibraryVariableSets-1005"
        name            = "Test"
        # (2 unchanged attributes hidden)

      ~ template {
          + display_settings = {}
            id               = "FOO"
            name             = "foo"
            # (1 unchanged attribute hidden)
        }
      ~ template {
          + display_settings = {}
            id               = "baz"
            name             = "baz"
            # (1 unchanged attribute hidden)
        }
    }


Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes, the following plan may include actions to undo or respond to these changes.

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # octopusdeploy_library_variable_set.test will be updated in-place
  ~ resource "octopusdeploy_library_variable_set" "test" {
        id              = "LibraryVariableSets-1005"
        name            = "Test"
        # (2 unchanged attributes hidden)

      ~ template {
          ~ default_value    = "baz" -> "bar"
          ~ id               = "baz" -> "bar"
          ~ name             = "baz" -> "bar"
            # (1 unchanged attribute hidden)
        }
      + template {
          + default_value = "baz"
          + id            = "baz"
          + name          = "baz"
        }
        # (1 unchanged block hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

octopusdeploy_library_variable_set.test: Modifying... [id=LibraryVariableSets-1005]
octopusdeploy_library_variable_set.test: Modifications complete after 0s [id=LibraryVariableSets-1005]

Environment and versions:

  • OS: Windows
  • Octopus Server Version: 2021.2.7650
  • Terraform Version: 1.1.6
  • Octopus Terraform Provider Version: 0.7.69

Additional context I attempted to debug this issue but I am not familiar with golang nor terraform provider development so I apologize for my limited help.

nathanscottdaniels avatar Apr 07 '22 17:04 nathanscottdaniels