JSON encoding/decoding in Terraform: Explained with examples

Updated: February 4, 2024 By: Guest Contributor Post a comment

Introduction

Terraform, an Infrastructure as Code (IaC) tool developed by HashiCorp, is a popular choice amongst developers for automating the deployment of server and application infrastructure. With its user-friendly HCL (HashiCorp Configuration Language), Terraform allows for easy definition and provisioning of cloud services. A critical capability in this process is handling JSON data, as JSON is a ubiquitous format for configuration files and API communication. In this tutorial, we’ll dive deep into how to effectively handle JSON encoding and decoding within Terraform, backed by comprehensive examples.

Understanding JSON in Terraform

JSON, or JavaScript Object Notation, is a lightweight data-interchange format that is easy for humans to read and write and easy for machines to parse and generate. Terraform, though primarily uses HCL, can also interpret JSON syntax. This flexibility is pivotal when working with configurations or APIs that exclusively support JSON.

DECODING JSON

Decoding JSON in Terraform is extracting data from a JSON-formatted string into Terraform’s native HCL structure. This process is essential when dealing with dynamic or external data. The jsondecode() function comes to the rescue here.

Example 1: Decoding a JSON string

{
  "name": "John Doe",
  "age": 30,
  "city": "New York"
}

To decode this JSON string in Terraform, you can use:

variable "user_details" {
  type = string
  default = "{\"name\": \"John Doe\", \"age\": 30, \"city\": \"New York\"}"
}

output "user" {
  value = jsondecode(var.user_details)
}

This will convert the JSON string into an HCL object, allowing you to access its attributes like name, age, and city directly.

ENCODING JSON

Conversely, encoding JSON involves converting HCL objects into a JSON-formatted string. Terraform’s jsonencode() function enables this.

Example 2: Encoding an HCL object into a JSON string

locals {
  user_details = {
    name = "John Doe",
    age = 30,
    city = "New York"
  }
}

output "user_json" {
  value = jsonencode(locals.user_details)
}

This HCL object gets encoded into a JSON string, facilitating its use in applications or APIs requiring JSON format.

Advanced Usage: Dynamic Blocks and JSON

Dynamically generating parts of your configuration based on external data is a powerful aspect of Terraform’s functionality. The use of dynamic blocks with JSON data decodes can streamline the process.

Example 3: Using dynamic blocks with decoded JSON

variable "user_roles" {
  type = string
  default = "[{\"role\":\"admin\",\"active\":true},{\"role\":\"user\",\"active\":false}]"
}

resource "some_resource" "example" {
  dynamic "role" {
    for_each = jsondecode(var.user_roles)

    content {
      role_name = role.value.role
      role_active = role.value.active
    }
  }
}

This demonstrates how decoded JSON data can be iteratively applied to dynamic blocks, resulting in a more flexible and powerful resource configuration.

Best Practices When Dealing with JSON in Terraform

  • Validate JSON Inputs: Always ensure the JSON input is correctly formatted. Use tools like JSONLint for validation.
  • Avoid Hard-Coding Sensitive Data: Utilize Terraform’s variables and secrets management practices to protect sensitive data.
  • Utilize Terraform’s Data Sources: When working with external data, prefer data sources over hard-coded JSON strings to fetch data dynamically.

Conclusion

Understanding how to handle JSON encoding and decoding in Terraform enables better integration with other services, automation of configurations, and overall more dynamic infrastructure management. While JSON and HCL are distinct, their synergy within Terraform provides a powerful toolkit for cloud infrastructure deployment and management.