How to Use Terraform Split String to Manipulate Key-Value Pairs

Use Terraform’s built-in split(separator, string) function to divide strings into lists, then iterate over the results with for expressions to extract and manipulate key-value pairs.

The terraform split string capability is essential for parsing configuration data, environment variables, and resource tags that arrive as delimited strings. In the hashicorp/terraform repository, this function is registered in internal/lang/functions.go where the HCL name "split" is bound to stdlib.SplitFunc【1†L160-L170】【1†L370-L380】, with the concrete implementation residing in internal/lang/funcs/string.go.

Understanding the Split Function Signature

Terraform’s split function follows a strict signature that determines how it handles delimiters and empty values.

split(separator, string) → list(string)
  • separator: A literal string that marks the boundary between elements. This is not a regular expression.
  • string: The input string to divide.
  • Return value: A list of strings containing the substrings between separators. If the separator does not occur in the string, the function returns a single-element list containing the original string.

According to the source code in internal/lang/functions.go, this behavior is provided by the HCL standard library’s SplitFunc, which Terraform imports and registers during expression evaluation【1†L160-L170】.

Converting Delimited Key-Value Strings to Maps

A common pattern involves transforming a comma-separated string of key=value pairs into a Terraform map for use in resource tags or environment configurations.

variable "raw_tags" {
  description = "Comma-separated key=value pairs"
  type        = string
  default     = "env=prod,owner=alice,team=ops"
}

locals {
  # Step 1: Split the string into a list of "key=value" strings

  tag_pairs = split(",", var.raw_tags)

  # Step 2: Iterate and split each pair on "=" to build a map

  tag_map = {
    for pair in local.tag_pairs :
    split("=", pair)[0] => split("=", pair)[1]
  }
}

This produces the following map structure:

{
  env   = "prod"
  owner = "alice"
  team  = "ops"
}

The split function is invoked twice: first to break the outer delimiter (comma), then to separate each key from its value. Because split always returns a list, you can safely index into the result with [0] and [1] when you know the format contains exactly one = per pair.

Handling Dynamic Delimiters and Edge Cases

When working with user-provided data, you may encounter inconsistent formatting or variable delimiters.

Normalizing Complex Separators

If your input uses multiple spaces or mixed delimiters, preprocess the string with replace before splitting:

locals {
  messy_input = "env=prod  owner=alice   team=ops"
  # Collapse multiple spaces to single space, then split

  normalized = split(" ", replace(local.messy_input, "/\\s+/", " "))
}

Safely Handling Missing Separators

Because split returns the original string as a single-element list when the separator is absent, you can use this property to provide default values:

locals {
  maybe_csv = "single_value"
  items     = split(",", local.maybe_csv) # Returns ["single_value"]

  first_item = local.items[0]
}

Summary

  • Function Location: The split function is registered in internal/lang/functions.go as stdlib.SplitFunc and implemented in internal/lang/funcs/string.go【1†L160-L170】.
  • Signature: split(separator, string) returns a list(string), making it ideal for parsing delimited data.
  • Key-Value Pattern: Combine split with for expressions to convert comma-separated key=value strings into Terraform maps.
  • Edge Case Handling: The function returns the original string as a single-element list when the separator is not found, enabling safe default handling.

Frequently Asked Questions

How does Terraform's split function handle empty strings?

When you pass an empty string as the second argument to split, the function returns a list containing a single empty string element: [""]. If you split an empty string by a separator that doesn't exist, you receive exactly one element containing the empty input. This behavior is consistent with the HCL standard library implementation stdlib.SplitFunc used by Terraform.

Can I use regular expressions as separators in Terraform split?

No, the split function does not support regular expressions. The separator must be a literal string. If you need to split on a complex pattern (such as multiple consecutive spaces or mixed delimiters), you must first preprocess the string using the replace function with a regex pattern, then pass the normalized result to split. For full regex-based splitting, consider using regexall to find all matches instead.

What is the difference between split and splitlist in Terraform?

Terraform provides split for dividing strings, while splitlist is not a built-in function. You may be thinking of split combined with other list manipulation functions like slice, element, or flatten. To extract specific segments after splitting, use standard list indexing (e.g., split(",", var.string)[0]) or the element function. The split function always returns a list of strings that you can manipulate with any Terraform collection function.

How do I handle key-value pairs where values contain the delimiter?

When values themselves contain the delimiter character (e.g., a comma inside a value), simple splitting produces incorrect results. You should either escape the delimiter in your source data or use a different delimiter that does not appear in values. Alternatively, parse the string using the regexall function with a pattern that accounts for quoted values or specific key-value boundaries. For complex parsing requirements, consider preprocessing the data outside Terraform or using a dedicated parser resource.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s https://instagit.com/install.md

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client