Skip to main content

Terraform Date and Time Functions

Time and date manipulation is essential when working with infrastructure configurations, especially for setting resource lifetimes, scheduling operations, or generating timestamps. Terraform provides several built-in functions that allow you to work with dates and times efficiently within your configurations.

Introduction to Date and Time Functions

Terraform's date and time functions help you manage timestamps, calculate time differences, and format dates according to your needs. These functions are particularly useful when:

  • Setting expiration dates for resources
  • Adding timestamps to resource names
  • Calculating time periods for scheduled operations
  • Formatting dates for logging or output purposes

Let's explore the various date and time functions available in Terraform and how to use them effectively.

Core Date and Time Functions

timestamp() Function

The timestamp() function returns the current UTC timestamp in RFC 3339 format.

hcl
locals {
current_time = timestamp()
}

output "current_timestamp" {
value = local.current_time
# Example output: 2025-03-25T14:30:45Z
}

This function is useful when you need to record when resources were created or updated.

formatdate() Function

The formatdate() function formats a timestamp into a string using a specified format.

hcl
locals {
current_time = timestamp()
formatted_date = formatdate("YYYY-MM-DD hh:mm:ss", local.current_time)
}

output "formatted_date" {
value = local.formatted_date
# Example output: 2025-03-25 14:30:45
}

The format string uses the following specifiers:

SpecifierDescriptionExample
YYYYFour-digit year2025
YYTwo-digit year25
MMTwo-digit month03
MMonth without leading zero3
DDTwo-digit day of month25
DDay of month without leading zero25
hhTwo-digit hour (24-hour clock)14
hHour without leading zero14
mmTwo-digit minute30
mMinute without leading zero30
ssTwo-digit second45
sSecond without leading zero45

timeadd() Function

The timeadd() function adds a duration to a timestamp and returns a new timestamp.

hcl
locals {
current_time = timestamp()
one_hour_later = timeadd(local.current_time, "1h")
one_day_later = timeadd(local.current_time, "24h")
one_week_later = timeadd(local.current_time, "168h")
}

output "future_timestamps" {
value = {
current = local.current_time
one_hour_later = local.one_hour_later
one_day_later = local.one_day_later
one_week_later = local.one_week_later
}
}

Duration format accepts:

  • h for hours
  • m for minutes
  • s for seconds

You can combine these units, such as 1h30m for one hour and thirty minutes.

Practical Examples

Example 1: Creating Resources with Expiration Tags

A common use case is to tag resources with creation and expiration dates for tracking purposes.

hcl
locals {
current_time = timestamp()
expiration_time = timeadd(local.current_time, "720h") # 30 days later
}

resource "aws_s3_bucket" "temporary_bucket" {
bucket = "temp-data-processing-${formatdate("YYYYMMDD", local.current_time)}"

tags = {
Name = "Temporary Data Processing Bucket"
CreatedOn = formatdate("YYYY-MM-DD", local.current_time)
ExpiresOn = formatdate("YYYY-MM-DD", local.expiration_time)
ManagedBy = "Terraform"
}

lifecycle {
prevent_destroy = false
}
}

output "bucket_info" {
value = {
bucket_name = aws_s3_bucket.temporary_bucket.bucket
created_on = formatdate("YYYY-MM-DD", local.current_time)
expires_on = formatdate("YYYY-MM-DD", local.expiration_time)
}
}

Example 2: Setting Time-Based Conditions

You can use date and time functions in combination with Terraform's conditional expressions to implement time-based logic.

hcl
locals {
current_time = timestamp()
business_hours_start = formatdate("hh:mm", local.current_time) >= "08:00"
business_hours_end = formatdate("hh:mm", local.current_time) <= "17:00"
is_business_hours = local.business_hours_start && local.business_hours_end

# Set different instance sizes based on time
instance_type = local.is_business_hours ? "t3.medium" : "t3.small"
}

resource "aws_instance" "app_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = local.instance_type

tags = {
Name = "AppServer-${formatdate("YYYYMMDD-hhmmss", local.current_time)}"
DeployedDuring = local.is_business_hours ? "BusinessHours" : "NonBusinessHours"
}
}

Example 3: Creating Rotating Backup Schedule

This example demonstrates how to create a backup policy with rotating schedules using time functions.

hcl
locals {
current_time = timestamp()
day_of_week = formatdate("EEE", local.current_time)
day_of_month = formatdate("DD", local.current_time)

# Define backup types based on day
backup_type = {
"Mon" = "incremental"
"Tue" = "incremental"
"Wed" = "incremental"
"Thu" = "incremental"
"Fri" = "full"
"Sat" = "archive"
"Sun" = "verify"
}

# Special backup on first day of month
is_first_day = local.day_of_month == "01"

todays_backup = local.is_first_day ? "monthly-full" : local.backup_type[local.day_of_week]
}

resource "aws_backup_plan" "example" {
name = "backup-plan-${formatdate("YYYYMMDD", local.current_time)}"

rule {
rule_name = "daily-${local.todays_backup}-backup"
target_vault_name = "backup-vault"
schedule = "cron(0 12 * * ? *)"

lifecycle {
delete_after = local.todays_backup == "monthly-full" ? 365 : 30
}
}

tags = {
BackupType = local.todays_backup
CreatedOn = formatdate("YYYY-MM-DD", local.current_time)
}
}

output "backup_info" {
value = {
plan_name = aws_backup_plan.example.name
backup_type = local.todays_backup
created_on = formatdate("YYYY-MM-DD", local.current_time)
}
}

Advanced Usage with Time Calculations

Working with Time Zones

While Terraform's timestamp function returns UTC time, you can use the formatdate() function with format specifiers that include time zone information:

hcl
locals {
current_utc = timestamp()

# Format with UTC time explicitly shown
utc_formatted = formatdate("YYYY-MM-DD'T'hh:mm:ss'Z'", local.current_utc)

# Add hours for different time zones (manual approach)
est_time = timeadd(local.current_utc, "-5h") # Eastern Standard Time (UTC-5)
pst_time = timeadd(local.current_utc, "-8h") # Pacific Standard Time (UTC-8)
cet_time = timeadd(local.current_utc, "1h") # Central European Time (UTC+1)
}

output "times_in_different_zones" {
value = {
utc_time = local.utc_formatted
est_time = formatdate("YYYY-MM-DD hh:mm:ss", local.est_time)
pst_time = formatdate("YYYY-MM-DD hh:mm:ss", local.pst_time)
cet_time = formatdate("YYYY-MM-DD hh:mm:ss", local.cet_time)
}
}

Calculating Time Differences

Terraform doesn't have a direct function to calculate the difference between two timestamps, but you can work around this by using the timeadd() function with a negative duration:

hcl
locals {
start_time = "2025-01-01T00:00:00Z"
end_time = "2025-01-02T12:30:45Z"

# Calculate hours between timestamps (approximate method)
# First convert to same format
formatted_start = formatdate("YYYY-MM-DD'T'hh:mm:ss'Z'", local.start_time)
formatted_end = formatdate("YYYY-MM-DD'T'hh:mm:ss'Z'", local.end_time)

# Then use a counter approach with a known increment
hours_diff = ceil((
parseint(formatdate("YYYYMMDDhhmmss", local.end_time), 10) -
parseint(formatdate("YYYYMMDDhhmmss", local.start_time), 10)
) / 10000) # Rough approximation, divide by 10000 to get to hours
}

output "time_difference" {
value = "${local.hours_diff} hours (approximate)"
}

This is a simplified approach and may not be accurate for all cases, especially when dealing with time zones or daylight saving time changes.

Understanding Terraform's Date Handling Limitations

Terraform has some limitations when it comes to date and time operations:

  1. There's no built-in function to parse arbitrary date formats into timestamps
  2. Direct subtraction of dates is not supported natively
  3. Complex calendar operations (like "last Friday of the month") require workarounds
  4. Time zone handling is manual rather than supported by native functions

For complex date calculations, consider using external tools or data sources that can provide pre-calculated values.

Best Practices for Working with Dates in Terraform

  1. Consistency: Always use UTC in your configurations to avoid time zone issues
  2. Documentation: Comment your time calculations clearly for future reference
  3. Avoid Drift: Be cautious when using timestamp() in resource attributes as it changes on every plan/apply
  4. Testing: Validate your date logic with terraform console before applying changes
  5. Variables: Use variables for time-sensitive configurations so they can be adjusted easily

Summary

Terraform's date and time functions provide flexible ways to handle timestamps in your infrastructure configurations. While not as comprehensive as dedicated date libraries in programming languages, they offer essential functionality for most infrastructure automation needs.

The key functions to remember are:

  • timestamp() - Get the current UTC time
  • formatdate() - Format a timestamp according to specific patterns
  • timeadd() - Add a duration to a timestamp

By combining these functions with Terraform's other capabilities, you can implement sophisticated time-based infrastructure patterns, resource rotation schedules, and expiration management systems.

Additional Resources

Exercises

  1. Create a Terraform configuration that provisions an AWS EC2 instance with tags indicating when it was created and when it should be reviewed (30 days later).

  2. Implement a naming convention for resources that includes the current date in the format YYYY-MM-DD-resource-name.

  3. Write a module that takes a timestamp input variable and outputs various formatted versions of that timestamp for different purposes (logging, display, file naming).

  4. Create a configuration that uses the day of the week to determine resource settings (e.g., higher capacity on weekdays, lower on weekends).



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)