time_rotating constantly re-creates resource after rfc3339 + rotation_xy has passed the first time.
Community Note
- Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
- Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
- If you are interested in working on this issue or have submitted a pull request, please leave a comment
Terraform Version
Terraform v0.15.4
on darwin_amd64
+ provider registry.terraform.io/hashicorp/time v0.7.1
Affected Resource(s)
- time_rotating
Terraform Configuration Files
resource "time_rotating" "test" {
rfc3339 = "2021-06-20T12:43:13Z"
rotation_minutes = 7
}
Debug Output
Output
> terraform apply -auto-approve
time_rotating.test: Refreshing state... [id=2021-06-20T12:43:13Z]
Note: Objects have changed outside of Terraform
Terraform detected the following changes made outside of
Terraform since the last "terraform apply":
# time_rotating.test has been deleted
- resource "time_rotating" "test" {
- day = 20 -> null
- hour = 12 -> null
- id = "2021-06-20T12:43:13Z" -> null
- minute = 43 -> null
- month = 6 -> null
- rfc3339 = "2021-06-20T12:43:13Z" -> null
- rotation_minutes = 7 -> null
- rotation_rfc3339 = "2021-06-20T12:50:13Z" -> null
- second = 13 -> null
- unix = 1624192993 -> null
- year = 2021 -> null
}
Unless you have made equivalent changes to your
configuration, or ignored the relevant attributes using
ignore_changes, the following plan may include actions to
undo or respond to these changes.
──────────────────────────────────────────────────────────
Terraform used the selected providers to generate the
following execution plan. Resource actions are indicated
with the following symbols:
+ create
Terraform will perform the following actions:
# time_rotating.test will be created
+ resource "time_rotating" "test" {
+ day = (known after apply)
+ hour = (known after apply)
+ id = (known after apply)
+ minute = (known after apply)
+ month = (known after apply)
+ rfc3339 = "2021-06-20T12:43:13Z"
+ rotation_minutes = 7
+ rotation_rfc3339 = (known after apply)
+ second = (known after apply)
+ unix = (known after apply)
+ year = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
time_rotating.test: Creating...
time_rotating.test: Creation complete after 0s [id=2021-06-20T12:43:13Z]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Panic Output
Expected Behavior
- The resource is created after the first call of
terraform applyand not created again before the date rfc3339 + rotation_minutes (in the example above:2021-06-20T12:50:13Z) has passed. - After the date has passed the next call of
terraform applywill re-create the resource. If I callterraform applyagain the resource should not be re-created as long as the current date is lower than the next rotation date (would be rfc3339 + rotation_minutes * 2)
short:
- tf init
- tf apply -> initial create
- tf apply -> nop
- tf apply -> nop
- time has passed rfc3339 + rotation_minutes
- tf apply -> re-create resource
- tf apply -> nop
- time has passed rfc3339 + rotation_minutes * 2
- tf apply -> re-create resource
- tf apply -> nop ...
Actual Behavior
- As expected: The resource is created after the first call of
terraform applyand not created again before the date rfc3339 + rotation_minutes (in the example above:2021-06-20T12:50:13Z) has passed. - After the date has passed each call of
terraform applyleads to the re-creation of the resource.
short:
- tf init
- tf apply -> initial create
- tf apply -> nop
- tf apply -> nop
- time has passed rfc3339 + rotation_minutes
- tf apply -> re-create resource
- tf apply -> re-create resource
- tf apply -> re-create resource
- tf apply -> re-create resource ...
Steps to Reproduce
With the example above it should be enough to call:
terraform initterraform apply- initial creationterraform apply- re-creation
Important Factoids
References
- #0000
Thank you for your work on Terraform ❤️
Can someone confirm this issue? Is this a bug or a lack of documentation? It does work as expected without the rfc3339.
I'm experiencing this issue too.
My assumption was that the rfc3339 argument was setting the initial time for calculating the rotation time, after which the rotation_X argument would become the increment and the resource would be recreated every N rotation_X's time.
I can't see how the actual behaviour is useful.
This really needs to be fixed. I think what needs to happen is that the provider should compare the id to rotation_rfc3339 and not rotate if it's past it.
At the moment the time_rotating doesn't work like a clock. "if timestamp()>rotation_rfc3339 then delete the resource" and then terraform says "the resource does not exist - create from code" and the provider says simply "rotation_rfc3339 = rfc3339 + rot_X rotation interval "
The rotation_rfc3339 calculation is too simple and with a fixed rfc3339 ends up constantly in the past, resulting in the Delete -> create identically on every Apply to infinity. Why not have some clock arithmetic, it could be a switch like clock_rotating = true
To illustrate what we want, I think,
if rfc3339 input is not null, if rfc3339 input in the past, we want this:
v rfc3339 v id v rotation_rfc3339
| | | | x |
^+1rot_X ^+2rot_X ^+Nrot_X ^timestamp()
if rfc3339 input in the future, we want this:
v id
v rfc3339 v rotation_rfc3339
| x | | |
^timestamp() ^+1rot_X
So could it be coded like this?
if (rfc3339 input)
rfc3339 = rfc3339 input
if (rfc3339 in the past)
id = timestamp() minus ( (timestamp() - rfc3339) MOD rot_X )
else
' rfc3339 in the future
id = rfc3339
fi
else
' no rfc3339 input, use timestamp()
rfc3339 = timestamp()
id = rfc3339
fi
rotation_rfc3339 = id + rot_X
Why has this issue has not been fixed since Jun 28, 2021? How else can one create a rotating timestamp starting say 15 days from now to rotate every 30 days?
rfc3339 should be the base timestamp. It should only be used to start the rotation from.
BTW, I also ran into this bug...
The workaround requires that the rfc3339 is not defined and for the time_rotating when defining the resource. Instead seed the resource with the desired time via import.
Example command to obtain timestamps:
gdate -u +%Y-%m-%dT%H:%M:%SZ- current timegdate -u +%Y-%m-%dT%H:%M:%SZ --date="+12 hours"- 12 hours in the future
Example import command 12 hours in the future w/ daily rotation:
terraform import time_rotating.example_daily "$(gdate -u +%Y-%m-%dT%H:%M:%SZ --date="+12 hours"),,,1,,"
Looks like https://github.com/hashicorp/terraform-provider-time/pull/180 would resolve this issue.
Hi @m273d15 thanks for raising this issue, fixing this issue requires a significant rewrite in the resource's logic and will result in a breaking change for practitioners. We will consider this issue as part of a larger effort for a Time Provider major release in the future but we do not have a timeline for this at the moment.
I think another workaround is to only set rfc3339 on creation and then leave it null going forward. Seemed to work for me:
resource "time_static" "first_run_timestamp" {
rfc3339 = plantimestamp()
lifecycle {
ignore_changes = [ rfc3339 ]
}
}
resource "time_rotating" "test" {
rfc3339 = time_static.first_run_timestamp.rfc3339 == plantimestamp() ? timeadd(plantimestamp(), "-5m") : null
rotation_minutes = 10
}
Unfortunately time_static seems to have similar issues where when you set rfc3339 it will perpetually recreate it, which is why I ignore that attribute after creation.
Just commenting to say I found this after encountering the same issue those have described above - this resource is pointless if it doesn't maintain a constantly rotating time. At the moment, after the rotation period has elapsed the resource behaves like timestamp()!