Skip to main content

Working with Expressions

1. Writing String Expressions

Expression Type Description Example
String Concatenation Joining strings using the + operator "Hello " + "World"
String Interpolation Inserting variable values into strings using ${} "Hello ${var.name}"
Template Functions Functions for string manipulation like upper(), lower() upper("hello")

Example: String Concatenation

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"
  tags = {
    Name = "WebServer-" + var.environment
  }
}

Example: String Interpolation

output "instance_name" {
  value = "Instance ${aws_instance.web.id} is running"
}

2. Using Arithmetic Operators (+, -, *, /)

Operator Description Example Result
+ Addition 5 + 3 8
- Subtraction 10 - 4 6
* Multiplication 6 * 7 42
/ Division 20 / 4 5

Example: Basic Arithmetic in Variables

variable "length" {
  type = number
  default = 10
}

variable "width" {
  type = number
  default = 5
}

output "area" {
  value = var.length * var.width
}

3. Using Comparison Operators (==, !=, <, >)

Operator Description Examples Notes
== Equal to var.age == 25 Compares values for equality
!= Not equal to var.name != "John" Compares values for inequality
< Less than var.count < 10 Checks if the left operand is less than the right operand
> Greater than var.price > 50.0 Checks if the left operand is greater than the right operand
<= Less than or equal to var.value <= 100 Checks if the left operand is less than or equal to the right operand
>= Greater than or equal to var.score >= 80 Checks if the left operand is greater than or equal to the right operand

Example: Using Comparison Operators in Conditions

resource "aws_instance" "web" {
  ami           = "ami-12345678"
  instance_type = var.instance_type

  tags = {
    Name = "web-server"
    Env  = var.environment
  }

  # Conditionally set instance type based on environment
  instance_type = var.environment == "production" ? "t3.large" : "t3.medium"
}

4. Using Logical Operators (&&, ||, !)

Operator Description Example Result
! Logical NOT operator !true false
&& Logical AND operator true && false false
|| Logical OR operator true || false true

Example: Combining Conditions

resource "aws_instance" "web" {
  count = var.enable_web_server && var.web_instance_type != ""
  instance_type = var.web_instance_type
  ami = var.ami_id
}

Example: Negating Conditions

resource "aws_s3_bucket" "logs" {
  bucket = "my-logs-bucket"
  force_destroy = !var.retention_policy_enabled
}

5. Using Conditional Expressions (condition ? true : false)

Expression Description Example
condition ? true_value : false_value Conditional expression that evaluates to one of two values based on a boolean condition var.enabled ? "production" : "staging"

Example: Conditional Resource Creation

resource "aws_instance" "web" {
  count = var.create_web_instance ? 1 : 0
  ami           = "ami-12345678"
  instance_type = var.instance_type
}

Example: Conditional Variable Assignment

variable "environment" {
  default = "staging"
}

locals {
  region = var.environment == "production" ? "us-west-2" : "us-east-1"
}
Note: The ternary operator in Terraform is a powerful way to conditionally assign values or create resources. It's particularly useful for managing different configurations across environments.

6. Using For Expressions ([for item in list])

For expressions in Terraform allow you to iterate over collections and transform them into different data structures. The basic syntax is:

[for item in list : transformation]

Example: Transforming a List of Numbers

numbers = [for n in [1, 2, 3, 4] : n * 2]
# Result: [2, 4, 6, 8]
Expression Description Result
[for item in list : item] Identity transformation [1, 2, 3]
[for item in list : item * 2] Transforms each item [2, 4, 6]
[for item in list : item if item > 2] Filters items [3, 4]
Note: The for expression can also be used to build maps and sets, not just lists.

Example: Building a Map from a List

map_example = {
  for item in ["a", "b", "c"] :
  item => upper(item)
}
# Result: { a = "A", b = "B", c = "C" }

7. Using Splat Expressions (resource.*.attribute)

Splat expressions provide a concise way to access attributes from all instances of a resource or data source in Terraform.

Expression Description Example Usage
resource.name.attribute Accesses the specified attribute from all instances of a resource aws_instance.web.*.public_ip
data.name.attribute Accesses the specified attribute from all instances of a data source data.aws_subnet.subnet.*.cidr_block

Example: Accessing Public IPs from Multiple Instances

resource "aws_instance" "web" {
  count = 3
  ami           = "ami-12345678"
  instance_type = "t2.micro"
}

output "public_ips" {
  value = aws_instance.web.*.public_ip
}
Note: The splat operator returns a list of values, even if there is only one instance. If you expect a single value, consider using aws_instance.web[0].public_ip instead.

Example: Using Splat in a Variable

variable "instance_ips" {
  type = list(string)
  default = aws_instance.web.*.public_ip
}

8. Accessing Map and Object Attributes

Expression Description Example Result
map.key Access a value in a map using a key local.my_map.key1 value1
object.attribute Access an attribute in an object local.my_object.attr1 value1
map["key"] Access a value in a map using bracket notation local.my_map["key1"] value1
object["attribute"] Access an attribute in an object using bracket notation local.my_object["attr1"] value

Example: Accessing Map Attributes

locals {
  server_config = {
    name        = "web-server"
    port        = 80
    environment = "production"
  }
}

output "server_name" {
  value = local.server_config.name
}

Example: Accessing Object Attributes with Bracket Notation

locals {
  server_config = {
    name        = "web-server"
    port        = 80
    environment = "production"
  }
}

output "server_port" {
  value = local.server_config["port"]
}

9. Using String Templates

Terraform supports string templates using the templatefile() function, which allows you to embed variables and expressions into template files.

Function Description Example
templatefile() Reads a template file and renders it with provided variables templatefile("config.tmpl", { name = "example", port = 8080 })

Example: Using templatefile()

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"
  user_data     = templatefile("user-data.sh.tmpl", {
    instance_name = "web-server"
    port          = 80
  })
}

Example: Template file (user-data.sh.tmpl)

#!/bin/bash
echo "Starting web server on port ${port}"
sudo systemctl start nginx

Template files can include expressions and variable interpolations, making them powerful for generating dynamic configuration.

Note: Template files must be valid HCL or shell script syntax depending on their usage context.

10. Understanding Type Constraints

Type Description Examples Notes
string Textual data "hello" Must be enclosed in quotes
number Numeric values 42, 3.14 Can be integers or floats
bool Boolean values true, false Case-sensitive
list(<type>) Ordered collection of elements ["a", "b", "c"] Elements must be of same type
set(<type>) Unordered collection of unique elements ["a", "b", "c"] Elements must be of same type
map(<type>) Map of key-value pairs {"key1": "value1", "key2": "value2"} Values must be of same type
object({attr1 = type, ...}) Structured object with named attributes {name = "John", age = 30} Attributes must match specified types
tuple([type1, type2, ...]) Ordered list with fixed size [1, "hello", true] Each element can have different type

Example: Type Constraints in Variables

variable "server_config" {
  type = object({
    name   = string
    port   = number
    active = bool
  })
  default = {
    name   = "web-server"
    port   = 80
    active = true
  }
}

Example: Type Constraints in Outputs

output "server_ips" {
  value = [for instance in aws_instance.server : instance.private_ip]
  type  = list(string)
}
Note: Type constraints are enforced at runtime during evaluation, not compile-time.

11. Using Null Values

Expression Description Notes
null null is a special value in Terraform that represents the absence of a value. It's often used to conditionally exclude attributes or blocks from being applied.
can be used in: Conditional expressions, variable assignments, and function arguments. When a value is null, it can be ignored or skipped in certain contexts.

Example: Using null in conditional expressions

resource "aws_instance" "example" {
  ami           = var.ami_id
  instance_type = var.instance_type

  # Only set tags if they are provided
  tags = var.tags == null ? {} : var.tags
}
Note: Using null in expressions can help avoid errors when optional values are not provided, especially in modules or configurations that support optional parameters.

Was this article helpful?