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

required resource update due to changes in nested attributes that have not been modified #1951

Closed
ocobles opened this issue May 9, 2024 · 7 comments · Fixed by #2060
Closed
Assignees
Labels
bug/diff Bugs in computing Diffs and planning resource changes kind/bug Some behavior is incorrect or out of spec resolution/fixed This issue was fixed

Comments

@ocobles
Copy link
Contributor

ocobles commented May 9, 2024

What happened?

I work in the development of the Equinix provider. I have an issue in multiple resources where it finds changes in pulumi preview for resources without modifications. I have discovered so far:

  • in terraform provider they work well and the resources keep unchanged
  • the affected resources are still defined in terraform sdk/v2
  • the affected fields are nested attributes of type schema.TypeSet MaxItems 1
  • all sub-fields in the nested schema are optional and computed

Example

import os
import sys
import pulumi
import pulumi_equinix as equinix

# Configuration
config = pulumi.Config()
account_num = config.require_int("accountNum")
project_id = config.require("projectId")
notification_emails = config.require_object("notificationEmails")
equinix_metro = config.get("metro") or "FR"
purchase_order_num = config.get("purchaseOrderNum") or "1234"

fabric_cloud_router = equinix.fabric.CloudRouter("cloud-router",
    name="pulumi-demo-fcr-gcp",
    type="XF_ROUTER",
    location=equinix.fabric.CloudRouterLocationArgs(
        metro_code=equinix_metro,
    ),
    package=equinix.fabric.CloudRouterPackageArgs(code="STANDARD"),
    notifications=[equinix.fabric.CloudRouterNotificationArgs(
        type="ALL", emails=notification_emails)],
    order=equinix.fabric.CloudRouterOrderArgs(
        purchase_order_number=purchase_order_num,
    ),
    account=equinix.fabric.CloudRouterAccountArgs(account_number=account_num),
    project=equinix.fabric.CloudRouterProjectArgs(project_id=project_id),
)

The issue:
image

To reproduce: run pulumi preview after a successful pulumi up

If I update the CloudRouterLocationArgs with the rest of optional/computed fields values returned it works well:

metro_name="Frankfurt",
ibx="",
region="EMEA",

import os
import sys
import pulumi
import pulumi_equinix as equinix

# Configuration
config = pulumi.Config()
account_num = config.require_int("accountNum")
project_id = config.require("projectId")
notification_emails = config.require_object("notificationEmails")
equinix_metro = config.get("metro") or "FR"
purchase_order_num = config.get("purchaseOrderNum") or "1234"

fabric_cloud_router = equinix.fabric.CloudRouter("cloud-router",
    name="pulumi-demo-fcr-gcp",
    type="XF_ROUTER",
    location=equinix.fabric.CloudRouterLocationArgs(
        metro_code=equinix_metro,
        ibx="",
        metro_name="Frankfurt",
        region="EMEA",
    ),
    package=equinix.fabric.CloudRouterPackageArgs(code="STANDARD"),
    notifications=[equinix.fabric.CloudRouterNotificationArgs(
        type="ALL", emails=notification_emails)],
    order=equinix.fabric.CloudRouterOrderArgs(
        purchase_order_number=purchase_order_num,
    ),
    account=equinix.fabric.CloudRouterAccountArgs(account_number=account_num),
    project=equinix.fabric.CloudRouterProjectArgs(project_id=project_id),
)
% pulumi preview
...
Resources:
    2 unchanged

Output of pulumi about

% pulumi about
CLI
Version 3.100.0
Go Version go1.21.5
Go Compiler gc

Plugins
NAME VERSION
equinix 0.8.0
google-native 0.32.0
python unknown

Host
OS darwin
Version 14.4.1
Arch x86_64

This project is written in python: executable='/Users/Oscar/Workspace/pulumi-equinix-fabric-cloud-router/venv/bin/python3' version='3.11.6'

Current Stack: ocobleseqx/equinix-fabric-cloud-router-2-gcp/test-fcr-gcp

Found no resources associated with test-fcr-gcp

Found no pending operations associated with test-fcr-gcp

Backend
Name pulumi.com
URL https://app.pulumi.com/ocobleseqx
User ocobleseqx
Organizations ocobleseqx
Token type personal

Dependencies:
NAME VERSION
google-cloud-compute 1.18.0
grpcio-status 1.60.1
pip 23.3.1
pulumi_equinix 0.8.0
pulumi-google-native 0.32.0
setuptools 68.2.2

Pulumi locates its logs in /var/folders/mc/fb3gq3zd4g52ykjt_rg27tpc0000gp/T/ by default

Additional context

terraform schema definition https://github.com/equinix/terraform-provider-equinix/blob/0844b8c394e50067bfc0ba3b8c50f0061405d6ee/equinix/resource_fabric_cloud_router.go#L144-L153

Contributing

Vote on this issue by adding a 👍 reaction.
To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

@ocobles ocobles added kind/bug Some behavior is incorrect or out of spec needs-triage Needs attention from the triage team labels May 9, 2024
@VenelinMartinov
Copy link
Contributor

VenelinMartinov commented May 13, 2024

Hi @ocobles, thanks for reporting and for the detailed repro. Sorry you had issues here!
Does the same issue still not reproduce in terraform if you run TF with -refresh=false?

This is a big difference between pulumi and terraform - tf runs refresh by default.

@VenelinMartinov VenelinMartinov added bug/diff Bugs in computing Diffs and planning resource changes and removed needs-triage Needs attention from the triage team labels May 13, 2024
@ocobles
Copy link
Contributor Author

ocobles commented May 14, 2024

Thanks @VenelinMartinov, I tried your suggestion and it does not detect changes in terraform

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

equinix_fabric_cloud_router.new_cloud_router: Creating...
equinix_fabric_cloud_router.new_cloud_router: Still creating... [10s elapsed]
equinix_fabric_cloud_router.new_cloud_router: Still creating... [20s elapsed]
equinix_fabric_cloud_router.new_cloud_router: Still creating... [30s elapsed]
equinix_fabric_cloud_router.new_cloud_router: Creation complete after 39s [id=eab60790-1c16-4c3f-9f7a-b259afc492f7]

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

Oscar@FF11QMD6R tf_test % tf apply -refresh=false

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are
needed.

@VenelinMartinov VenelinMartinov self-assigned this May 15, 2024
@VenelinMartinov
Copy link
Contributor

VenelinMartinov commented May 15, 2024

Hey @ocobles, I tried to compare the tf and pulumi behaviour here with some assumptions. So far they seem to match and both seem to trigger an update.

I don't have access to the equinix platform, so I've attempted to recreate the relevant schema in a test which compares TF and pulumi: #1975

Given the output I am assuming that if the equinix API receives a metroCode it returns no metroCode back but returns a metroName instead.

From the test it looks like TF also triggers an update under these conditions. I'm including the terraform plan here:

{
    "format_version": "1.2",
    "terraform_version": "1.8.2",
    "planned_values": {
        "root_module": {
            "resources": [
                {
                    "address": "crossprovider_testres.example",
                    "mode": "managed",
                    "type": "crossprovider_testres",
                    "name": "example",
                    "provider_name": "registry.terraform.io/hashicorp/crossprovider",
                    "schema_version": 0,
                    "values": {
                        "id": "r1",
                        "location": [
                            {
                                "metro_code": "FRA"
                            }
                        ]
                    },
                    "sensitive_values": {
                        "location": [
                            {}
                        ]
                    }
                }
            ]
        }
    },
    "resource_changes": [
        {
            "address": "crossprovider_testres.example",
            "mode": "managed",
            "type": "crossprovider_testres",
            "name": "example",
            "provider_name": "registry.terraform.io/hashicorp/crossprovider",
            "change": {
                "actions": [
                    "update"
                ],
                "before": {
                    "id": "r1",
                    "location": [
                        {
                            "metro_code": "",
                            "metro_name": "Frankfurt"
                        }
                    ]
                },
                "after": {
                    "id": "r1",
                    "location": [
                        {
                            "metro_code": "FRA"
                        }
                    ]
                },
                "after_unknown": {
                    "location": [
                        {
                            "metro_name": true
                        }
                    ]
                },
                "before_sensitive": {
                    "location": [
                        {}
                    ]
                },
                "after_sensitive": {
                    "location": [
                        {}
                    ]
                }
            }
        }
    ],
    "prior_state": {
        "format_version": "1.0",
        "terraform_version": "1.8.2",
        "values": {
            "root_module": {
                "resources": [
                    {
                        "address": "crossprovider_testres.example",
                        "mode": "managed",
                        "type": "crossprovider_testres",
                        "name": "example",
                        "provider_name": "registry.terraform.io/hashicorp/crossprovider",
                        "schema_version": 0,
                        "values": {
                            "id": "r1",
                            "location": [
                                {
                                    "metro_code": "",
                                    "metro_name": "Frankfurt"
                                }
                            ]
                        },
                        "sensitive_values": {
                            "location": [
                                {}
                            ]
                        }
                    }
                ]
            }
        }
    },
    "configuration": {
        "provider_config": {
            "crossprovider": {
                "name": "crossprovider",
                "full_name": "registry.terraform.io/hashicorp/crossprovider"
            }
        },
        "root_module": {
            "resources": [
                {
                    "address": "crossprovider_testres.example",
                    "mode": "managed",
                    "type": "crossprovider_testres",
                    "name": "example",
                    "provider_config_key": "crossprovider",
                    "expressions": {
                        "location": [
                            {
                                "metro_code": {
                                    "constant_value": "FRA"
                                }
                            }
                        ]
                    },
                    "schema_version": 0
                }
            ]
        }
    },
    "timestamp": "2024-05-15T13:32:31Z",
    "applyable": true,
    "complete": true,
    "errored": false
}

It could be the case that either my repro or the framework is going wrong somewher, let me know if I've missed something!

@ocobles
Copy link
Contributor Author

ocobles commented May 16, 2024

API always returns a value for metroCode. I did some more tests., always using metro_code for the create request

  1. Without making any changes to the provider, in my Pulumi example, if I remove metro_code in the second pulumi up attempt, it doesn't detect any changes
    location=equinix.fabric.CloudRouterLocationArgs(
        # metro_code="FR",
    ),
  1. Without making any changes to the provider, in my Pulumi example, if I add metro_name, region and ibx in the second pulumi up attempt, it doesn't detect any changes
    location=equinix.fabric.CloudRouterLocationArgs(
        metro_code="FR",
        metro_name="Frankfurt",
        region="EMEA",
        ibx="",
    ),
  1. Patching upstream tf provider to make metro_code required, it doesn't detect any changes in the second pulumi up attempt
+	schemaMap["metro_code"].Required = true
+	schemaMap["metro_code"].Optional = false
+	schemaMap["metro_code"].Computed = false

@VenelinMartinov
Copy link
Contributor

VenelinMartinov commented May 16, 2024

Can you post the state of the resource after the first pulumi up?

API always returns a value for metroCode.

This seems to contradict the diff which pulumi shows there and

if I remove metro_code in the second pulumi up attempt, it doesn't detect any changes

Very curious about the behaviour.

@VenelinMartinov VenelinMartinov added needs-repro Needs repro steps before it can be triaged or fixed awaiting-feedback Blocked on input from the author labels May 22, 2024
@ocobles
Copy link
Contributor Author

ocobles commented May 22, 2024

This is how it looks after first pulumi up in both Pulumi and API

image
image

@mikhailshilkov mikhailshilkov added needs-triage Needs attention from the triage team and removed awaiting-feedback Blocked on input from the author labels May 23, 2024
@VenelinMartinov
Copy link
Contributor

Hi @ocobles, thanks a lot for getting back to me and sorry for the slow response on my part!

I've been able to repro the issue with the information you provided in #1975, we'll look into prioritising it!

@VenelinMartinov VenelinMartinov removed needs-triage Needs attention from the triage team needs-repro Needs repro steps before it can be triaged or fixed labels May 30, 2024
VenelinMartinov added a commit that referenced this issue Jun 6, 2024
This updates our `objchange` algorithm with the newest one from the
OpenTofu repo. This fixes an issue with the way unknown sets are
presented to TF.

fixes #1951
@pulumi-bot pulumi-bot added the resolution/fixed This issue was fixed label Jun 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/diff Bugs in computing Diffs and planning resource changes kind/bug Some behavior is incorrect or out of spec resolution/fixed This issue was fixed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants