Hi @mukeshinit,
Unfortunately timeadd
is a time-oriented rather than a calendar-oriented function, and so it only supports clock time units and not anything that would involve reference to a calendar, such as years or months.
I think the closest you could get with this function would be to reframe the problem in terms of hours, using the number of hours in a typical year. Of course, that’ll not get exactly the same result in the presence of complications such as leap years and leap seconds, but it’s exactly that sort of calendar complexity that is what makes timeadd
not support “calendar units” in the first place.
Another way to approach it would be to define the rule “syntactically” instead. For example, you could say that the rule is that the end date is the instant at exactly the same wallclock time on the same month and date in the next year, regardless of the fact that this’ll end up with a different elapsed time depending on the calendar layout of the current year. You could implement that sort of syntactic approach by modifying the timestamp strings directly:
locals {
timestamp_parts = regex("^(?P<year>\\d+)(?P<remainder>-.*)$", local.current_time)
year_from_now = format("%d%s", local.timestamp_parts.year + 1, local_timestamp_parts.remainder)
}
The local.timestamp_parts
value here is splitting the initial timestamp so we can extract the year part in order to do arithmetic on it:
{
"remainder" = "-04-09T17:54:39Z"
"year" = "2021"
}
"2021" + 1
is 2022
in Terraform, because the +
operator implicitly converts all of its arguments to numbers before performing the addition, and so for me this produced the following result for local.year_from_now
:
"2022-04-09T17:54:39Z"
Another thing I want to note, by the way, is that the timestamp
function is an non-converging function and so it will return a new value each time you re-plan this configuration, which will then cause Terraform to constantly plan to update this object. I expect that isn’t what you wanted here, so that’s why I replaced timestamp()
with the local.current_time
placeholder in the example above, under the assumption that you’d populate that some other way that would remain stable on future runs.
Dealing with calendars is a non-trivial problem where correct solutions require databases that need ongoing maintenance to record special details such as leap seconds, etc, and so that’s why Terraform Core doesn’t try to get into that business.
However, as an alternative to the above workarounds within Terraform Core you might like to consider the hashicorp/time
provider as alternative. It has a resource type time_offset
which is designed to help with use-cases like yours:
resource "time_offset" "password_end" {
offset_years = 1
}
resource "azuread_application_password" "example" {
# ...
end_date = formatdate(
"YYYY-MM-DD",
time_offset.password_end.rfc3339,
)
}
A key advantage of handling this with a managed resource rather than just a function is that this uses the Terraform state as a sort of memory for what date it generated when it was “created”, so subsequent terraform plan
will use the same date. (See the docs for the resource type for some options for intentionally recreating the time_offset
when you need to.)