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

[BUG] Provider produced invalid plan #245

Closed
1 task done
kaefferlein opened this issue Jul 25, 2022 · 6 comments
Closed
1 task done

[BUG] Provider produced invalid plan #245

kaefferlein opened this issue Jul 25, 2022 · 6 comments
Assignees
Labels

Comments

@kaefferlein
Copy link

Terraform CLI and Provider Versions

Terraform v1.2.0
on darwin_amd64

Terraform Configuration

terraform {
  required_version = ">= 1.0.2, < 2"
  required_providers {  
    tls = {
      source = "hashicorp/tls"
      version = "4.0.0"
    }
  }
}


resource "tls_private_key" "sealed_secrets_key" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

resource "tls_self_signed_cert" "sealed_secrets_cert" {
  private_key_pem = tls_private_key.sealed_secrets_key.private_key_pem

  subject {
    common_name  = local.sealed_secret_certificate_common_name
    organization = local.sealed_secret_certificate_organization
  }

  validity_period_hours = 1

  allowed_uses = [
    "key_encipherment",
    "digital_signature",
    "server_auth",
  ]

  lifecycle {
    ignore_changes = [ready_for_renewal]
  }
}

Expected Behavior

Plan should run without an error

Actual Behavior

Plan errored with the following error:

Error: Provider produced invalid plan
Provider "registry.terraform.io/hashicorp/tls" planned an invalid value for tls_self_signed_cert.sealed_secrets_cert.ready_for_renewal: planned value cty.True does not match config value cty.False nor prior value cty.False.

This is a bug in the provider, which should be reported in the provider's own issue tracker.

Steps to Reproduce

  1. terraform plan

How much impact is this issue causing?

Medium

Logs

No response

Additional Information

Pinning to version 3.4.0 fixes it, yet we want to use the current version :)

Code of Conduct

  • I agree to follow this project's Code of Conduct
@detro detro self-assigned this Jul 25, 2022
@detro
Copy link
Contributor

detro commented Jul 25, 2022

Hello @kaefferlein - Sorry you are having issues here. Let me see if I can help.

I have taken your example code, but I had to modify it a bit because it was referring locals that don't exist:

terraform {
  required_version = ">= 1.0.2, < 2"
  required_providers {  
    tls = {
      source = "hashicorp/tls"
      version = "4.0.0"
    }
  }
}


resource "tls_private_key" "sealed_secrets_key" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

resource "tls_self_signed_cert" "sealed_secrets_cert" {
  private_key_pem = tls_private_key.sealed_secrets_key.private_key_pem

  subject {
    common_name  = "test common name"
    organization = "test organization"
  }

  validity_period_hours = 1

  allowed_uses = [
    "key_encipherment",
    "digital_signature",
    "server_auth",
  ]

  lifecycle {
    ignore_changes = [ready_for_renewal]
  }
}

My terraform:

↳ terraform -v
Terraform v1.2.5
on darwin_arm64
+ provider registry.terraform.io/hashicorp/tls v4.0.0

Terraform plan looked good, but there was this at the end:

Plan: 2 to add, 0 to change, 0 to destroy.
╷
│ Warning: Redundant ignore_changes element
│
│   on main.tf line 17, in resource "tls_self_signed_cert" "sealed_secrets_cert":
│   17: resource "tls_self_signed_cert" "sealed_secrets_cert" {
│
│ Adding an attribute name to ignore_changes tells Terraform to ignore future changes to the argument in configuration after the object has been created, retaining the value originally configured.
│
│ The attribute ready_for_renewal is decided by the provider alone and therefore there can be no configured value to compare with. Including this attribute in ignore_changes has no effect. Remove the attribute from ignore_changes
│ to quiet this warning.

That is a warning from Terraform itself, and it does make sense. But it's legit to ignore.

So I applied:

Plan: 2 to add, 0 to change, 0 to destroy.
╷
│ Warning: Redundant ignore_changes element
│
│   on main.tf line 17, in resource "tls_self_signed_cert" "sealed_secrets_cert":
│   17: resource "tls_self_signed_cert" "sealed_secrets_cert" {
│
│ Adding an attribute name to ignore_changes tells Terraform to ignore future changes to the argument in configuration after the object has been created, retaining the value originally configured.
│
│ The attribute ready_for_renewal is decided by the provider alone and therefore there can be no configured value to compare with. Including this attribute in ignore_changes has no effect. Remove the attribute from ignore_changes
│ to quiet this warning.
╵

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

tls_private_key.sealed_secrets_key: Creating...
tls_private_key.sealed_secrets_key: Creation complete after 1s [id=1b14300f9cd041666b62eacd6a655e434c5a53a7]
tls_self_signed_cert.sealed_secrets_cert: Creating...
tls_self_signed_cert.sealed_secrets_cert: Creation complete after 0s [id=248626877573702354625347450909622008791]

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

And any successive plan or apply produces the same warning as above:

Warning: Redundant ignore_changes element
│
│   on main.tf line 17, in resource "tls_self_signed_cert" "sealed_secrets_cert":
│   17: resource "tls_self_signed_cert" "sealed_secrets_cert" {
│
│ Adding an attribute name to ignore_changes tells Terraform to ignore future changes to the argument in configuration after the object has been created, retaining the value originally configured.
│
│ The attribute ready_for_renewal is decided by the provider alone and therefore there can be no configured value to compare with. Including this attribute in ignore_changes has no effect. Remove the attribute from ignore_changes
│ to quiet this warning.

Can you double check:

  • your version of TF
  • the exact code you used to produce this error
  • anything else that could help us pin-point the issue?

@detro
Copy link
Contributor

detro commented Jul 25, 2022

Update.

I think I managed to make the error in question appear. I had to alter the configuration so to make the early renewal kick in sooner:

...

resource "tls_self_signed_cert" "sealed_secrets_cert" {
  private_key_pem = tls_private_key.sealed_secrets_key.private_key_pem

  subject {
    common_name  = "test common name"
    organization = "test organization"
  }

  validity_period_hours = 1
  early_renewal_hours = 1       <------

  allowed_uses = [
    "key_encipherment",
    "digital_signature",
    "server_auth",
  ]

  lifecycle {
    ignore_changes = [ready_for_renewal]
  }
}

By keeping the ignoring of ready_for_renewal (that warnings highlighted repeatedly), I get on plan:

↳ terraform plan
tls_private_key.sealed_secrets_key: Refreshing state... [id=1b14300f9cd041666b62eacd6a655e434c5a53a7]
tls_self_signed_cert.sealed_secrets_cert: Refreshing state... [id=248626877573702354625347450909622008791]
╷
│ Warning: Redundant ignore_changes element
│
│   on main.tf line 17, in resource "tls_self_signed_cert" "sealed_secrets_cert":
│   17: resource "tls_self_signed_cert" "sealed_secrets_cert" {
│
│ Adding an attribute name to ignore_changes tells Terraform to ignore future changes to the argument in configuration after the object has been created, retaining the value originally configured.
│
│ The attribute ready_for_renewal is decided by the provider alone and therefore there can be no configured value to compare with. Including this attribute in ignore_changes has no effect. Remove the attribute from ignore_changes
│ to quiet this warning.
╵
╷
│ Error: Provider produced invalid plan
│
│ Provider "registry.terraform.io/hashicorp/tls" planned an invalid value for tls_self_signed_cert.sealed_secrets_cert.ready_for_renewal: planned value cty.True does not match config value cty.False nor prior value cty.False.
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.

I'll keep looking into this, but the warnings and the error are likely to be intertwined.

@detro
Copy link
Contributor

detro commented Jul 25, 2022

@kaefferlein - Can I ask why are you using

lifecycle {
    ignore_changes = [ready_for_renewal]
  }

Is the intention to prevent the self signed cert to expire (testing/dev environment?)?

@kaefferlein
Copy link
Author

Hi @detro,

thanks for your replies so far :)

@kaefferlein - Can I ask why are you using

lifecycle {
    ignore_changes = [ready_for_renewal]
  }

Is the intention to prevent the self signed cert to expire (testing/dev environment?)?

yes, I guess so - unfortunately I can not tell you exactly why this has been done.

Do you think the ignore_changes = [ready_for_renewal] causes the issue?
But as it does not take any effect it can be removed, right?

@detro
Copy link
Contributor

detro commented Jul 26, 2022

Hi @kaefferlein, thanks for the reply.

So, the way to fix this and not have TF raise that error, is probably to increase the certificate validity in years or multiple years: it would generate a new certificate the first time you apply, and then would not expire for a long while.

The auto renewal process is at the moment a backed-in behaviour of the provider, and can't be avoided.

Setting ignore_changes = [ready_for_renewal] causes the Provider to create a temporary Plan where a change is applied to ready_for_renewal, and that is currently invalid, for the reason explained in the error.

We are discussing with the Terraform Core team on what's the best course of action is, but meanwhile, to unblock your situation, I would suggest setting validity_period_hours = 8766 (or an equivalent very long time span), and remove the ignore_changes section. This way the resource will not try to renew it.

Please let us know if this helps.

@detro
Copy link
Contributor

detro commented Jul 26, 2022

Hello again @kaefferlein.

I discussed with my team and here is the outcome.

First of all, we have identified this to be an issue with terraform itself: the Terraform Core team has already agreed to a fix (see hashicorp/terraform#31509) that addresses this regression in behaviour, and allows for "Read-Only" (i.e. Computed) attributes (ready_for_renewal in this case) to be included as part of of ignore_changes, and so allowing the behaviour you are after.

Once the fix lands, this should be signified also by the disappearance of the warning noticed above:

│ Warning: Redundant ignore_changes element
│
│   on main.tf line 17, in resource "tls_self_signed_cert" "sealed_secrets_cert":
│   17: resource "tls_self_signed_cert" "sealed_secrets_cert" {
│
│ Adding an attribute name to ignore_changes tells Terraform to ignore future changes to the argument in configuration after the object has been created, retaining the value originally configured.
│
│ The attribute ready_for_renewal is decided by the provider alone and therefore there can be no configured value to compare with. Including this attribute in ignore_changes has no effect. Remove the attribute from ignore_changes
│ to quiet this warning.

In terms of having never-expiring certificate, given the current feature set of this provider, the correct way to set that up is by setting validity_period_hours to a really big value, like 8766 hours == 1 year. This will cause 1 replacement of the certificate, the first time is applied: we suggest to use a very big number of hours.

If this "never try to auto renew" behavior is desirable by multiple practitioners, we would be happy to consider a feature request, and use it to gather and confirm interest in this change. One interesting scenario that removing or allow-disabling of auto renewal could do, is to pair it with the use of the replace_triggered_by functionality introduced in Terraform: practitioners could come up with more intricate and bespoke logic to control what/when/how the replacement of a certificate (i.e. renewal) should be triggered. This is of course outside of the scope of this issue, but it's food for thought.

Lastly, given the Terraform 1.0 Compatibility Promises, once the fix from hashicorp/terraform#31509 ships, upgrading TF should be all it is required to resolve this issue. This is also true for any TF >= 1.0.

I hope this is exhaustive and it provides ways to a resolution.

Thank you

@detro detro closed this as completed Jul 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants