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

PlanResourceChange Always Showing Differences #181

Closed
bflad opened this issue Sep 28, 2021 · 2 comments · Fixed by #184
Closed

PlanResourceChange Always Showing Differences #181

bflad opened this issue Sep 28, 2021 · 2 comments · Fixed by #184
Assignees
Labels
bug Something isn't working
Milestone

Comments

@bflad
Copy link
Contributor

bflad commented Sep 28, 2021

Module version

cf6f24087d3af45f583d0736c6ed841243d23653 (post v0.4.1, pre v0.4.2)

Relevant provider source code

Any schema with Computed only attributes. For example, hashicups-pf:

func (r resourceOrderType) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) {
	return tfsdk.Schema{
		Attributes: map[string]tfsdk.Attribute{
			"id": {
				Type: types.StringType,
				// When Computed is true, the provider will set value --
				// the user cannot define the value
				Computed: true,
			},
			"last_updated": {
				Type:     types.StringType,
				Computed: true,
			},
			"items": {
				// If Required is true, Terraform will throw error if user
				// doesn't specify value
				// If Optional is true, user can choose to supply a value
				Required: true,
				Attributes: tfsdk.ListNestedAttributes(map[string]tfsdk.Attribute{
					"quantity": {
						Type:     types.NumberType,
						Required: true,
					},
					"coffee": {
						Required: true,
						Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{
							"id": {
								Type:     types.NumberType,
								Required: true,
							},
							"name": {
								Type:     types.StringType,
								Computed: true,
							},
							"teaser": {
								Type:     types.StringType,
								Computed: true,
							},
							"description": {
								Type:     types.StringType,
								Computed: true,
							},
							"price": {
								Type:     types.NumberType,
								Computed: true,
							},
							"image": {
								Type:     types.StringType,
								Computed: true,
							},
						}),
					},
				}, tfsdk.ListNestedAttributesOptions{}),
			},
		},
	}, nil
}

Terraform Configuration Files

resource "hashicups_order" "edu" {
  items = [{
    coffee = {
      id = 3
    }
    quantity = 2
    }, {
    coffee = {
      id = 1
    }
    quantity = 2
    }
  ]
}

Expected Behavior

With no configuration changes (e.g. v0.4.1 behavior):

hashicups_order.edu: Refreshing state... [id=1]

No changes. Your infrastructure matches the configuration.

Actual Behavior

With no configuration changes:

$ terraform apply
...
hashicups_order.edu: Refreshing state... [id=1]

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:

  # hashicups_order.edu will be updated in-place
  ~ resource "hashicups_order" "edu" {
      ~ id           = "1" -> (known after apply)
      ~ items        = [
          ~ {
            ~ coffee   = {
              + description = (known after apply)
                id          = 3
              ~ image       = "/nomad.png" -> (known after apply)
              ~ name        = "Nomadicano" -> (known after apply)
              ~ price       = 150 -> (known after apply)
              ~ teaser      = "Drink one today and you will want to schedule another" -> (known after apply)
            }
              # (1 unchanged attribute hidden)

            ~ coffee   = {
              + description = (known after apply)
                id          = 1
              ~ image       = "/packer.png" -> (known after apply)
              ~ name        = "Packer Spiced Latte" -> (known after apply)
              ~ price       = 350 -> (known after apply)
              ~ teaser      = "Packed with goodness to spice up your images" -> (known after apply)
            }
              # (2 unchanged attributes hidden)
          },
        ]
      ~ last_updated = "Tuesday, 28-Sep-21 11:53:27 EDT" -> (known after apply)
    }

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

Steps to Reproduce

  1. terraform apply
  2. terraform apply (with no configuration changes)

References

@bflad bflad added the bug Something isn't working label Sep 28, 2021
@bflad bflad added this to the v0.4.2 milestone Sep 28, 2021
@bflad bflad self-assigned this Sep 28, 2021
@bflad
Copy link
Contributor Author

bflad commented Sep 28, 2021

The behavior added in #176 is on the right path, marking Computed only attributes as unknown during plan, however this behavior should only occur when there are configuration changes. This is further complicated that attribute and resource plan modifiers may introduce plan changes that should trigger the behavior. This may result in a two-phase approach, not sure.

bflad added a commit that referenced this issue Sep 28, 2021
…knowns for Computed-only attributes in plans

Reference: #181

Previously, any `Computed` attributes would always trigger plan differences due to the unknown marking.

```
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:

  # hashicups_order.edu will be updated in-place
  ~ resource "hashicups_order" "edu" {
      ~ id           = "1" -> (known after apply)
      ~ items        = [
          ~ {
            ~ coffee   = {
              + description = (known after apply)
                id          = 3
              ~ image       = "/nomad.png" -> (known after apply)
              ~ name        = "Nomadicano" -> (known after apply)
              ~ price       = 150 -> (known after apply)
              ~ teaser      = "Drink one today and you will want to schedule another" -> (known after apply)
            }
              # (1 unchanged attribute hidden)

            ~ coffee   = {
              + description = (known after apply)
                id          = 1
              ~ image       = "/packer.png" -> (known after apply)
              ~ name        = "Packer Spiced Latte" -> (known after apply)
              ~ price       = 350 -> (known after apply)
              ~ teaser      = "Packed with goodness to spice up your images" -> (known after apply)
            }
              # (2 unchanged attributes hidden)
          },
        ]
      ~ last_updated = "Tuesday, 28-Sep-21 11:53:27 EDT" -> (known after apply)
    }

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

This change limits the unknown marking to only be performed when there is actually a change between the `ProposedNewState` and `State`.

Without a configuration change:

```
No changes. Your infrastructure matches the configuration.
```

With a configuration change:

```
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:

  # hashicups_order.edu will be updated in-place
  ~ resource "hashicups_order" "edu" {
      ~ id           = "1" -> (known after apply)
      ~ items        = [
          ~ {
            ~ coffee   = {
              + description = (known after apply)
                id          = 3
              ~ image       = "/nomad.png" -> (known after apply)
              ~ name        = "Nomadicano" -> (known after apply)
              ~ price       = 150 -> (known after apply)
              ~ teaser      = "Drink one today and you will want to schedule another" -> (known after apply)
            }
              # (1 unchanged attribute hidden)

            ~ coffee   = {
              + description = (known after apply)
              ~ id          = 1 -> 2
              ~ image       = "/packer.png" -> (known after apply)
              ~ name        = "Packer Spiced Latte" -> (known after apply)
              ~ price       = 350 -> (known after apply)
              ~ teaser      = "Packed with goodness to spice up your images" -> (known after apply)
            }
              # (2 unchanged attributes hidden)
          },
        ]
      ~ last_updated = "Tuesday, 28-Sep-21 11:53:27 EDT" -> (known after apply)
    }

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

As a followup, it may be necessary to invoke two passes of attribute and resource plan modifiers to ensure any changes captured by those modifiers triggers the unknown marking. As it stands now, a plan with no configuration changes, but changes due to plan modifiers will not correctly trigger the unknown marking. See also: #183
@kmoe kmoe closed this as completed in #184 Sep 29, 2021
kmoe added a commit that referenced this issue Sep 29, 2021
…knowns for Computed-only attributes in plans (#184)

* tfsdk: Check ProposedNewState for State differences before marking unknowns for Computed-only attributes in plans

Reference: #181

Previously, any `Computed` attributes would always trigger plan differences due to the unknown marking.

```
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:

  # hashicups_order.edu will be updated in-place
  ~ resource "hashicups_order" "edu" {
      ~ id           = "1" -> (known after apply)
      ~ items        = [
          ~ {
            ~ coffee   = {
              + description = (known after apply)
                id          = 3
              ~ image       = "/nomad.png" -> (known after apply)
              ~ name        = "Nomadicano" -> (known after apply)
              ~ price       = 150 -> (known after apply)
              ~ teaser      = "Drink one today and you will want to schedule another" -> (known after apply)
            }
              # (1 unchanged attribute hidden)

            ~ coffee   = {
              + description = (known after apply)
                id          = 1
              ~ image       = "/packer.png" -> (known after apply)
              ~ name        = "Packer Spiced Latte" -> (known after apply)
              ~ price       = 350 -> (known after apply)
              ~ teaser      = "Packed with goodness to spice up your images" -> (known after apply)
            }
              # (2 unchanged attributes hidden)
          },
        ]
      ~ last_updated = "Tuesday, 28-Sep-21 11:53:27 EDT" -> (known after apply)
    }

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

This change limits the unknown marking to only be performed when there is actually a change between the `ProposedNewState` and `State`.

Without a configuration change:

```
No changes. Your infrastructure matches the configuration.
```

With a configuration change:

```
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:

  # hashicups_order.edu will be updated in-place
  ~ resource "hashicups_order" "edu" {
      ~ id           = "1" -> (known after apply)
      ~ items        = [
          ~ {
            ~ coffee   = {
              + description = (known after apply)
                id          = 3
              ~ image       = "/nomad.png" -> (known after apply)
              ~ name        = "Nomadicano" -> (known after apply)
              ~ price       = 150 -> (known after apply)
              ~ teaser      = "Drink one today and you will want to schedule another" -> (known after apply)
            }
              # (1 unchanged attribute hidden)

            ~ coffee   = {
              + description = (known after apply)
              ~ id          = 1 -> 2
              ~ image       = "/packer.png" -> (known after apply)
              ~ name        = "Packer Spiced Latte" -> (known after apply)
              ~ price       = 350 -> (known after apply)
              ~ teaser      = "Packed with goodness to spice up your images" -> (known after apply)
            }
              # (2 unchanged attributes hidden)
          },
        ]
      ~ last_updated = "Tuesday, 28-Sep-21 11:53:27 EDT" -> (known after apply)
    }

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

As a followup, it may be necessary to invoke two passes of attribute and resource plan modifiers to ensure any changes captured by those modifiers triggers the unknown marking. As it stands now, a plan with no configuration changes, but changes due to plan modifiers will not correctly trigger the unknown marking. See also: #183


Co-authored-by: Katy Moe <katy@katy.moe>
@github-actions
Copy link

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 30, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
1 participant