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

time_rotating constantly re-creates resource after rfc3339 + rotation_xy has passed the first time. #44

Open
m273d15 opened this issue Jun 28, 2021 · 9 comments
Assignees

Comments

@m273d15
Copy link

m273d15 commented Jun 28, 2021

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 apply and 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 apply will re-create the resource. If I call terraform apply again 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 apply and 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 apply leads 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:

  1. terraform init
  2. terraform apply - initial creation
  3. terraform apply - re-creation

Important Factoids

References

  • #0000

Thank you for your work on Terraform ❤️

@m273d15
Copy link
Author

m273d15 commented Jul 21, 2021

Can someone confirm this issue? Is this a bug or a lack of documentation? It does work as expected without the rfc3339.

@carldjohnston
Copy link

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.

@davidcorrigan714
Copy link

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.

@mikew3432
Copy link

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

@SBGoods SBGoods self-assigned this Mar 6, 2023
@pkeecom
Copy link

pkeecom commented May 2, 2023

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.

@faultymonk
Copy link
Contributor

faultymonk commented May 4, 2023

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 time
  • gdate -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 #180 would resolve this issue.

@SBGoods
Copy link
Contributor

SBGoods commented Jun 13, 2023

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.

@Mike-Nahmias
Copy link

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.

@james-woodbridge
Copy link

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()!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants