OpenNebula / terraform-provider-opennebula

Terraform provider for OpenNebula
https://www.terraform.io/docs/providers/opennebula/
Mozilla Public License 2.0
63 stars 52 forks source link

B #468: Improve `service_template` indempotence #508

Closed vickmp closed 10 months ago

vickmp commented 10 months ago

Community Note

Description

This PR introduces an improvement t to the handling of Service Template objects in the Terraform provider for OpenNebula.

Key changes include:

  1. Custom Deep Equality Function: A custom deepEqualIgnoreEmpty function has been added to the DiffSuppressFunc for the Service Template resource. This function compares two Service Template objects, ignoring empty fields. This change allows to improve the service idempotency since there're inconsistencies between the objects stored in the Terraform state and the values returned by the OneFlow API (which does NOT return empty objects). This caused terraform to interpret false changes that now no longer occur.

  2. JSON Unmarshalling: The old and new states of the Service Template object are now unmarshalled into ServiceTemplate structs before being compared. This allows the deepEqualIgnoreEmpty function to compare the objects field by field, rather than as raw JSON strings.

References

468

New or Affected Resource(s)

Checklist

treywelsh commented 10 months ago

I applied this:

resource "opennebula_service_template" "service_template" {
  name        = "test-svc"
  permissions = "760"
  template    = <<EOF
{
    "TEMPLATE": {
        "BODY": {
            "name": "test-svc",
            "deployment": "straight",
            "description": "",
             "roles": [
             {
               "name": "vnf",
               "cardinality": 1,
               "min_vms": 1,
               "vm_template_contents": "...",
               "cooldown": 120,
               "elasticity_policies": [],
               "scheduled_policies": []
             }
             ]
        }    
    }
}
EOF
}

There is no diff when applied so it's better.

Then I updated the description field to an arbitrary string, here is the diff:

Terraform will perform the following actions:

  # opennebula_service_template.service_template must be replaced
-/+ resource "opennebula_service_template" "service_template" {
      ~ gid         = 0 -> (known after apply)
      ~ gname       = "oneadmin" -> (known after apply)
      ~ id          = "4" -> (known after apply)
        name        = "test-svc"
      ~ template    = jsonencode(
          ~ {
              ~ TEMPLATE = {
                  ~ BODY = {
                      + description = "test"
                        name        = "test-svc"
                      ~ roles       = [
                          ~ {
                              + elasticity_policies  = []
                                name                 = "vnf"
                              + scheduled_policies   = []
                              - vm_template          = 0
                                # (4 unchanged attributes hidden)
                            },
                        ]
                        # (1 unchanged attribute hidden)
                    }
                }
            } # forces replacement
        )
      ~ uid         = 0 -> (known after apply)
      ~ uname       = "oneadmin" -> (known after apply)
        # (1 unchanged attribute hidden)
    }

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

There's only a cosmetic "problem", but the provider behave as expected. We still see others diffs (other than the description change I just made) but it's only "cosmetic": there's no impact on the provider behavior due to the fact that the template field has ForceNew behavior.

At first glance it's ok regarding the effort put into this PR VS a deep rewrite of the resources.

Do you want to take a look @frousselet ?