Early variable eval & provider functions

What OpenTofu can do that Terraform cannot.

Advanced12 min · lesson 10 of 12

Beyond encryption, OpenTofu has added language capabilities Terraform does not have, and they solve real papercuts. The best-known is early (dynamic) variable evaluation: Terraform forbids variables in backend and module-source configuration because those are resolved before variables — so you cannot parameterize a backend key or a module version by variable. OpenTofu evaluates certain values earlier, letting you use variables where Terraform hard-stops.

backend.tofu
# in OpenTofu you can parameterize things Terraform rejects here:
terraform {
backend "s3" {
bucket = "acme-tofu-state"
key = "${var.environment}/network.tfstate" # var in backend => OK in tofu
}
}
# and module sources:
module "vpc" {
source = "acme/vpc/aws"
version = var.vpc_module_version # variable module version => OK in tofu
}

Provider-defined functions in HCL

OpenTofu also supports provider-defined functions — a provider can expose custom functions you call directly in HCL (provider::name::function(...)), so common transformations no longer need a null_resource or an external data hack. Combined with a growing set of built-in functions, it makes configurations that were awkward in Terraform expressible directly.

main.tofu
# a provider-contributed function, called inline
locals {
parsed = provider::aws::arn_parse(aws_s3_bucket.logs.arn)
}
output "bucket_account" { value = local.parsed.account_id }
These features are OpenTofu-only — mark them
The moment you use early variable evaluation or provider-defined functions, the configuration no longer runs under Terraform. That is fine when you have committed to OpenTofu, but document it (and consider putting tofu-only logic in .tofu files) so nobody assumes the repo is still portable and wastes time debugging why terraform rejects it.