Skip to main content
In this lesson we recap how to use variables within an OpenTofu configuration. Variables let you parameterize your configuration, provide defaults, validate input, and mark values as sensitive to reduce accidental exposure in CLI output. A variable block is valid even when it declares no arguments. If no default is provided, you must supply a value at runtime (via CLI flags like -var, environment variables, or tfvars files). Within a variable block you can include:
  • default — a default value used when no other value is provided
  • description — a helpful human-readable explanation (recommended)
  • type — constrains accepted values (e.g., string, list(string), object({...}))
  • sensitive — if true, hides the value in CLI plan/apply output
Example: default, description, type, and sensitive
Setting sensitive = true suppresses the value in plan/apply output, but the value will still be recorded in the OpenTofu state file. Protect state (for example, by enabling encryption and restricting access) to keep secrets safe.

Validation rules for variables

You can add a validation block inside a variable to enforce constraints and return helpful error messages. For example, AWS AMI IDs typically start with ami-. The following variable enforces that rule and provides a custom error message.
If you pass an invalid value at the CLI, OpenTofu runs the validation and returns the error. Example CLI invocation:
Example console output:

Basic scalar types

OpenTofu supports these basic HCL scalar types: string, number, and bool (HCL uses bool rather than the word “boolean”). If you omit type, it defaults to any.
If type is omitted, the variable’s type is any by default—using explicit types is recommended to catch configuration errors early.
Examples for number and bool:

Type coercion and mismatches

  • If you provide both type and default, the default must match the declared type.
  • OpenTofu will attempt some conversions (for example, string ↔ number or string ↔ bool), but relying on coercion is error-prone.
  • If coercion is impossible (for example, type = bool with default = 1), OpenTofu will error and you must fix the mismatch.
Invalid example (this will error):

Collections and complex types

Beyond scalars, OpenTofu supports: list, set, map, object, and tuple. Use typed constructors such as list(string) or map(number) to enforce element types. Type reference table:

Lists

A list is an ordered sequence (index starts at 0). Use list(string) (or list(number), etc.) to constrain element types.
Access an element by index:

Maps

A map is a key-value collection. Use map(string) or map(number) to constrain value types.
Access a value by key:

Combining types with constraints

You can declare lists of specific types or maps of numbers. If values don’t match the declared constraint and cannot be coerced, OpenTofu will fail.

Sets

A set is an unordered collection that forbids duplicates. Use set(string) or set(number). Valid set example:
Invalid (contains duplicates; will error):

Objects

Objects model structured data with named attributes and specific types.

Tuples

A tuple is a fixed-length sequence where each element can have a different type. The default must match the exact length and element types.
If you supply the wrong number of elements or wrong element types, OpenTofu will raise an error.

Summary and best practices

  • Use default, description, type, and sensitive inside variable blocks to make configurations self-documenting and safer.
  • Prefer explicit type declarations to catch type errors early during plan/evaluation.
  • Add validation blocks to enforce format rules and provide actionable error messages.
  • Understand basic scalar types (string, number, bool) and collection/complex types (list, set, map, object, tuple).
  • Avoid relying on automatic type coercion — specify matching types or convert values explicitly.
  • Protect sensitive values stored in state (consider remote state backends with encryption and strict access controls).
Links and references
  • OpenTofu Documentation
  • HCL type information (HashiCorp) — see HCL and Terraform docs for additional examples
  • Best practices for secrets and state file security: use encrypted remote backends and access controls

Watch Video