Skip to main content
Terraform provides a set of built-in functions that transform and combine values within Terraform configurations. The Terraform function documentation contains a complete list. You can also use your editor autocompletion on the Fn object to find available options. Functions can handle normal and token values and will return either tokenized values or IResolvable values.

When to Use Terraform Functions

Use Terraform functions when you need to calculate new values based on runtime values that are unknown before Terraform (or OpenTofu) applies a configuration. For example, instance IDs that cloud providers assign on creation. When inputs are available before synthesizing your code (e.g. local files), we recommend transforming the values with your preferred programming language.

Usage Example

The following example uses a Data Source from the AWS Provider to fetch the Availability Zones of the given region. As this data is unknown until Terraform applies the configuration, this CDKTN application uses both Terraform Outputs and the Terraform element function. The element function gets the first element from the list of Availability Zone names.

Special functions

Property Access Helpers

To access nested properties from untyped objects or other datasources that return a dynamic datatype, use the Terraform function lookup or, for nested access, the function “Fn.lookupNested()” which is a function offered by CDKTN that allows to avoid nesting Fn.lookup calls.

Raw string helper

Another helper function offered by CDKTN is Fn.rawString which can be used to escape raw strings that contain characters that CDKTN or Terraform would try to interpret otherwise.

Operators

Use the Op object to include operators like !, +, and -.

Using Terraform built-in functions directly within strings

It is also possible to use all built-in Terraform functions without using CDKTN’s Fn.* functions described above. To write Terraform built-in functions the same as you would in HCL, simply wrap the desired string within the HCL ${ and } syntax. Note: CDKTN doesn’t do any further processing within the escaped syntax (${ and }), and thus is unable to handle nested escape syntaxes yet.

Function Availability Across Terraform and OpenTofu

CDK Terrain works with both Terraform and OpenTofu, but the two products do not support the exact same set of built-in functions. The Fn class covers the union of both: most functions are available everywhere, while a few exist in only one product or were introduced in a later release. The bindings are generated from the function metadata of every stable Terraform release since 1.5.7 and every stable OpenTofu release since 1.6.0. Functions that are not universally available are listed below. All other functions exposed on Fn are available in every supported release of both products.

Validating Function Usage at Synth Time

With the validateFunctionVersions feature flag enabled, CDK Terrain checks every function you use through Fn against the project’s declared targetVersions — the Terraform/OpenTofu version ranges your project intends to support. Projects created with cdktn init have the flag enabled by default; existing projects can opt in via cdktf.json:
A function must be available across the entire declared range of every targeted product. If it is not, synthesis fails with an actionable error instead of letting terraform plan fail later:
Raise the declared floor (e.g. "terraform": ">=1.9.0") — or drop the product you don’t support — to use the function.
The validation is purely declarative: it never executes a Terraform or OpenTofu binary, so synth behaves identically in CI, package builds, and environments without either installed. To explicitly verify the binary installed on a machine against the declared targets, opt in with "validateInstalledBinary": true, which applies to commands that execute the CLI (diff, deploy, destroy).
To disable all synth-time validations, pass skipValidation: true to your App configuration.

Limitations

  • Functions written inside raw expression strings (escape hatches such as overrides or hand-built ${...} interpolations) are not tracked and therefore not validated.
  • Provider-defined functions (provider::<name>::<function>) are validated as a family, not per-function: which functions exist depends on the provider, but calling any of them requires Terraform >= 1.8.0 or OpenTofu >= 1.7.0, and that floor is checked against your targetVersions (see Provider-Defined Functions below).

Provider-Defined Functions

Terraform (>= 1.8.0) and OpenTofu (>= 1.7.0) let providers ship their own functions, written in HCL as provider::<name>::<function>(...). When a provider declares functions, cdktn get generates typed bindings for them, reachable from the generated provider class via its functions property:
This synthesizes to ${provider::time::rfc3339_parse(...)}. The function namespace is the provider’s local name in required_providers, which the provider construct already knows — there is nothing to configure, and provider configuration aliases play no role in function namespaces. Using any provider-defined function registers a synth-time validation against your declared targetVersions (unconditionally — no feature flag, since this is new API surface): the whole declared range of every targeted product must admit provider functions (Terraform >= 1.8.0, OpenTofu
= 1.7.0).
For advanced cases (e.g. calling a function of a provider you do not instantiate), the lower-level TerraformProviderFunction.invoke(providerLocalName, functionName, args) escape hatch renders the same expression from raw parts.

Caveats

Generating bindings needs a newer OpenTofu than using them. OpenTofu supports provider-defined functions in the language from 1.7.0, but its CLI only exports provider function schemas from 1.8.0. Targeting "opentofu": ">=1.7.0" is therefore valid for synthesizing configurations that call provider functions — but running cdktn get with an OpenTofu binary older than 1.8.0 cannot see the schemas and will not generate the bindings (cdktn get warns when the fetching binary structurally cannot emit sections your targetVersions admit). This skew is intentional; the usage floor and the schema-emission floor are different boundaries. Do not call a provider’s functions inside that same provider’s configuration block. Provider-defined functions are evaluated by the provider itself, so referencing e.g. aws provider functions while configuring the AwsProvider asks Terraform/OpenTofu to evaluate an AWS function while the AWS provider is still being configured — both report a self-referential cycle. Configure the provider first; call its functions from resources, data sources, or outputs. Ephemeral values in outputs need both Fn.ephemeralasnull and sensitive. If a function result (or any other value) is derived from ephemeral data — for example an ephemeral resource’s attributes — a TerraformOutput of it must wrap the value in Fn.ephemeralasnull(...) (ephemeral values cannot appear in non-ephemeral contexts) and set sensitive: true (the value derives from secret ephemeral data). Omitting either makes terraform plan fail.