hashicorp / terraform-plugin-sdk

Terraform Plugin SDK enables building plugins (providers) to manage any service providers or custom in-house solutions
https://developer.hashicorp.com/terraform/plugin
Mozilla Public License 2.0
442 stars 233 forks source link

provider-sdk: unknown optional+computed set produces no diff value during plan #174

Open simonmcc opened 5 years ago

simonmcc commented 5 years ago

Terraform Version

Terraform v0.12.7

Terraform Configuration Files

resource "random_string" "temp_password2" {
  length      = 16
  special     = true
  min_upper   = 1
  min_lower   = 1
  min_special = 1
}

variable "users" {
  default = {
    smccartney_test1   = { superuser = ["dv1", "us1"] }
    smccartney_test2   = { superuser = ["dv1", "us2"] }
    # smccartney_test3   = { superuser = ["dv1", "us2"] }
  }
}

resource "azuread_user" "users" {
  for_each              = var.users
  display_name          = each.key
  user_principal_name   = format("%s%s", each.key, "@dummy.com")
  password              = random_string.temp_password2.result
}

resource "azuread_group" "SuperUsers_XXX" {
  name = "SuperUsers_US2"
  members = [
    for user in azuread_user.users:
      user.object_id
    if contains(lookup(var.users[user.mail_nickname], "superuser", []), "us2")
 ]
}

Debug Output

N/A

Crash Output

N/A

Expected Behavior

Adding a new user to AAD will also update the group member list as required.

Actual Behavior

On the first run, users & groups are created as expected, but on subsequent work (i.e. adding a new user), the new user is created on the first pass & the set of members will be updated on the second pass. (members list can't be calculated until the azuread_user is created & the UUID known)

Steps to Reproduce

  1. az cloud set --name AzureCloud
  2. az login
  3. terraform init
  4. terraform apply - users created, group created, users added to group: https://gist.github.com/simonmcc/ef1e01d34116f11f607a62d5c3df7ce7
  5. Uncomment smccartney_test3 = { superuser = ["dv1", "us2"] }
  6. terraform apply - user gets created, but not added to group: https://gist.github.com/simonmcc/cbe2b879cbd6e6d428e879eb0e3eb61a
  7. terraform apply - group gets updated, adding smccartney_test3's UUID: https://gist.github.com/simonmcc/726ef4a939e555019a6e942342340f43

References

jbardin commented 5 years ago

This turns out to be a bug directly in helper/schema, and has nothing really to do with for_each at all. The addition of features like for_each have only made it easier to hit this condition.

If an optional+computed set is unknown during plan, helper/schema produces no diff for that attribute, which causes the plan to keep the same attributes. Even though we allow the legacy SDK to override attributes during apply in some cases, a set data structure is forced to adhere to the plan because there is no way to determine which elements are incorrect in order to stabilize on a clean plan.