Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inputs that are arrays/hashes may perpetually say they need changes due to the way the values are stored in the state #451

Open
1 task done
rnelson0 opened this issue Jul 28, 2022 · 3 comments
Assignees
Labels
bug Something isn't working needs-triage

Comments

@rnelson0
Copy link
Contributor

rnelson0 commented Jul 28, 2022

Code of Conduct

This project has a Code of Conduct that all participants are expected to understand and follow:

vRA Version

8.6.2

Terraform Version

Terraform v1.2.5
on darwin_amd64

vRA Terraform Provider Version

  • provider registry.terraform.io/vmware/vra v0.5.1

Affected Resource(s)

  • vra_deployment

I suspect others are affected due to the underlying issue, but this is the only verified resource

Terraform Configuration Files

Slightly sanitized, the inputs->tags is the relevant portion anyway

resource "vra_deployment" "vaultenterprise_bed_fuzzy" {
  for_each = toset([
    # sanitized list
  ])

  name        = each.key
  description = "Vault Enterprise server created by Terraform"

  catalog_item_id      = data.vra_catalog_item.catalog_item.id
  catalog_item_version = var.vra_catalog_item_version
  project_id           = data.vra_project.project.id

  inputs = {
    datacenter        = "Bedford"
    hostname          = each.key
    numCpu            = 4
    numMem            = 16
    OSversion         = "OL8 Development"
    puppetBranch      = "nop4dev"
    puppetRole        = "vault_server"
    vlanId            = 30
    tags              = "[{ \"key\":\"Backup\",\"value\":\"CloudEng_Daily\" }]"
  }

  timeouts {
    create = "30m"
    delete = "30m"
    update = "30m"
  }

  lifecycle {
    ignore_changes = [
      catalog_item_version,
    ]
  }
}

Expected Behavior

When there are no changes, terraform plan should show no changes

Actual Behavior

On every terraform plan, the tags entries are marked for change. No effective change is made during a terraform apply (an Update event happens on the deployment but no actual change) but the next terraform plan shows the same marked change

Steps to Reproduce

  1. terraform plan or terraform apply

Screenshots

Debug Output

Plan output:

Output:

  # vra_deployment.vaultenterprise_rch2["vaultenterprisedr62002"] will be updated in-place
  ~ resource "vra_deployment" "vaultenterprise_rch2" {
        id                        = "199e39ec-15df-47e4-acb9-c4b2e0d5e914"
      ~ inputs                    = {
          ~ "tags"              = jsonencode( # whitespace changes
                [
                    {
                        key   = "Backup"
                        value = "CloudEng_Daily"
                    },
                ]
            )
            # (9 unchanged elements hidden)
        }
        name                      = "vaultenterprisedr62002"
        # (16 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

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

The relevant portion of the state file says:

resource "vra_deployment" "vaultenterprise_bed_fuzzy" {
    blueprint_id              = "232600a8-cf24-4fcf-90ef-a59a7c63b6c0"
    blueprint_version         = "1.1.0"
    catalog_item_id           = "8793a726-e8a8-3023-b50c-6265a48cace6"
    catalog_item_version      = "1.1.0"
    created_by                = "tgoin"
    description               = "Vault Enterprise server created by Terraform"
    id                        = "d6891ef6-5d5d-4ff9-a938-9f5fc14884df"
    inputs                    = {
        "OSversion"         = "OL8 Development"
        "datacenter"        = "Bedford"
        "hostname"          = "sevaultenterprisedr102"
        "numCpu"            = "4"
        "numMem"            = "16"
        "puppetBranch"      = "nop4dev"
        "puppetRole"        = "vault_server"
        "tags"              = jsonencode(
            [
                {
                    key   = "Backup"
                    value = "CloudEng_Daily"
                },
            ]
        )
        "vlanId"            = "30"
    }
    last_request              = [
        {
            action_id       = ""
            approved_at     = "0001-01-01T00:00:00.000Z"
            blueprint_id    = "232600a8-cf24-4fcf-90ef-a59a7c63b6c0:1.1.0"
            cancelable      = false
            catalog_item_id = "8793a726-e8a8-3023-b50c-6265a48cace6:1.1.0"
            completed_at    = "0001-01-01T00:00:00.000Z"
            completed_tasks = 3
            created_at      = "2022-07-22T04:46:42.338Z"
            details         = ""
            dismissed       = false
            id              = "081d1e21-d855-402c-a444-d8a99dff99ac"
            initialized_at  = "0001-01-01T00:00:00.000Z"
            inputs          = {
                "OSversion"         = "OL8 Development"
                "datacenter"        = "Bedford"
                "hostname"          = "sevaultenterprisedr102"
                "numCpu"            = "4"
                "numMem"            = "16"
                "puppetBranch"      = "nop4dev"
                "puppetRole"        = "vault_server"
                "tags"              = "[map[key:Backup value:CloudEng_Daily]]"
                "vlanId"            = "30"
            }
            name            = "Update"
            outputs         = {}
            requested_by    = "tgoin"
            resource_ids    = []
            status          = "SUCCESSFUL"
            total_tasks     = 3
            updated_at      = "2022-07-22T04:46:52.492Z"
        },
    ]

You can see that the tags are marked in different ways:

# state definition
        "tags"              = jsonencode(
            [
                {
                    key   = "Backup"
                    value = "CloudEng_Daily"
                },
            ]
        )
# state last_request
                "tags"              = "[map[key:Backup value:CloudEng_Daily]]"
# .tf definition
    tags              = "[{ \"key\":\"Backup\",\"value\":\"CloudEng_Daily\" }]"

Changing the definition in the .tf file to use jsonencode for the tags eliminated the marked changes on every run.

    tags              = jsonencode(
        [
            {
                key   = "Backup"
                value = "CloudEng_Daily"
            },
        ]
    )
  }

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment
@rnelson0 rnelson0 added bug Something isn't working needs-triage labels Jul 28, 2022
@rnelson0
Copy link
Contributor Author

I put the tf/provider version definition from the versions.tf file, once I validate the specific versions with the user who was experiencing this issue, I will update it.

@rnelson0
Copy link
Contributor Author

I went through the provider code and I don't know either terraform or go well enough to fully pinpoint the issue, but I'm trying to learn both and if someone can help me pinpoint where this change is (if it's even in provider at all), I'm happy to start looking into a fix. Conceptually it seems like it's an issue with normalization so a well known class of problem to resolve.

@rnelson0
Copy link
Contributor Author

Updated the versions now that I've got them.

I don't think it's an ordering issue, per se - flip the input order (below) and it doesn't show up. Somehow it's not normalizing the values between jsonencode and a flat string which gives the same result.

resource "vra_deployment" "vaultenterprise_bed_fuzzy" {
  for_each = toset([
    # sanitized list
  ])

  name        = each.key
  description = "Vault Enterprise server created by Terraform"

  catalog_item_id      = data.vra_catalog_item.catalog_item.id
  catalog_item_version = var.vra_catalog_item_version
  project_id           = data.vra_project.project.id

  inputs = {
    tags              = jsonencode(
        [
            {
                key   = "Backup"
                value = "CloudEng_Daily"
            },
        ]
    )
    datacenter        = "Bedford"
    hostname          = each.key
    numCpu            = 4
    numMem            = 16
    OSversion         = "OL8 Development"
    puppetBranch      = "nop4dev"
    puppetRole        = "vault_server"
    vlanId            = 30
  }

  timeouts {
    create = "30m"
    delete = "30m"
    update = "30m"
  }

  lifecycle {
    ignore_changes = [
      catalog_item_version,
    ]
  }
}
> terraform plan

...

No changes. Your infrastructure matches the configuration.

@tenthirtyam tenthirtyam self-assigned this Jul 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs-triage
Projects
None yet
Development

No branches or pull requests

2 participants