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

timestamp() always triggers resource replacement, even when it is interpolated #22461

Closed
eerkunt opened this issue Aug 14, 2019 · 2 comments
Closed

Comments

@eerkunt
Copy link

eerkunt commented Aug 14, 2019

Terraform Version

Terraform v0.12.6
+ provider.aws v2.23.0
+ provider.random v2.2.0

Terraform Configuration Files

resource "aws_lightsail_instance" "test" {
  name              = "test-${formatdate("YYYYMMDD", timestamp())}"
  availability_zone = "eu-west-1a"
  blueprint_id      = "ubuntu_18_04"
  bundle_id         = "small_2_0"
}

Expected Behavior

Resource replacement every day due to formatdate() interpolation with YYYYMMDD.

Actual Behavior

Resource replacement on every run.

Steps to Reproduce

  1. terraform init
  2. terraform apply

Additional Context

I also tried the same code using random_id with the code example below ;

resource "random_id" "test" {
  keepers = {
    date = formatdate("YYYYMMDD", timestamp())
  }

  byte_length = 8
}

resource "aws_lightsail_instance" "test" {
  name              = "test-${random_id.test}"
  availability_zone = "eu-west-1a"
  blueprint_id      = "ubuntu_18_04"
  bundle_id         = "small_2_0"
}

same problem. Whenever timestamp() is used, a new resource creation is triggered.

The only way I could fix this problem is to define a date variable and pass it via -var on the CLI.

References

Couldn't find any reference specific to this problem.

@teamterraform
Copy link
Contributor

Hi @eerkunt!

What you're seeing here is a result of the fact that the timestamp() function isn't evaluated until the apply step, because during planning Terraform can't predict what the time will be when you subsequently apply the plan. Consequently, the value of timestamp() isn't known and in turn the value of formatdate("YYYYMMDD", timestamp()) isn't known; it'll appear in the plan as "(known after apply)".

In general we don't recommend using timestamp() in Terraform resources because resource configurations ought to be stable and convergent. If you do use it in a context like this, you'd need to use ignore_changes to cause Terraform to ignore future changes to the value, but that won't then meet your apparent requirement of changing the name once per day.

What you are trying to do here is a little outside of Terraform's intended use-cases, so there isn't a direct way to solve it, but there are some possible approaches you could try:

  • You already identified the idea of using a variable. If this use-case includes running Terraform on a schedule so that it's guaranteed to run at least once per day then having the system that is responsible for that schedule execution set a variable value is probably the most straightforward option.

  • Another idea would be to taint the resource instance with terraform taint aws_lightsail_instance.test before you run it each day, to force Terraform to replace it, and then use ignore_changes to ensure that it won't get recreated unless it is tainted.

  • My final idea is to find a way to introduce a plan-time timestamp. Terraform doesn't have a feature for this because in normal use-cases the time of planning is not interesting, but you may be able to rely on the fact that data resources can be read during planning to achieve this. For example, you could use the external data source to run an external program that just returns the current date wrapped in a JSON object and then use that result in your lightsail instance name; Terraform will execute the program while planning (or, more accurately, while refreshing resources and reading data in preparation for planning) and retain that known result in the plan.

Since what you are doing here is not an intented use-case for the core Terraform workflow, we don't expect to add any new Terraform features to make it easier to achieve, and so we're going to close this. Hopefully the above give some ideas about how you might be able to use Terraform as a building block for solving your problem in conjunction with some other software. If you have any further questions, please feel free to start a new topic on the community forum. Thanks!

@ghost
Copy link

ghost commented Sep 15, 2019

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.

@ghost ghost locked and limited conversation to collaborators Sep 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants