jsondecode.com logo

JSON in Terraform — jsondecode, jsonencode & Local Values

Terraform's built-in functions jsondecode() and jsonencode() let you convert between JSON strings and Terraform values directly in HCL. No providers or external tools required.

Parse JSON with jsondecode()

jsondecode() converts a JSON string into a Terraform value — an object, list, number, string, or bool depending on the JSON type. Use it to read configuration from JSON strings or data sources.

locals {
  config_json = '{"region":"us-east-1","instance_type":"t3.micro","tags":{"env":"prod"}}'

  config = jsondecode(local.config_json)
}

output "region" {
  value = local.config.region  # "us-east-1"
}

output "env_tag" {
  value = local.config.tags.env  # "prod"
}

Read a JSON file with file() + jsondecode()

Combine file() to read a JSON file and jsondecode() to parse it. This is the standard pattern for loading external JSON configuration into Terraform.

# config.json
# { "ami": "ami-0c55b159cbfafe1f0", "instance_type": "t3.micro" }

locals {
  config = jsondecode(file("${path.module}/config.json"))
}

resource "aws_instance" "app" {
  ami           = local.config.ami
  instance_type = local.config.instance_type
}

Encode to JSON with jsonencode()

jsonencode() converts a Terraform value to a JSON string. Useful when an AWS resource or API expects a JSON policy document.

resource "aws_iam_role_policy" "example" {
  name = "example"
  role = aws_iam_role.example.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect   = "Allow"
        Action   = ["s3:GetObject", "s3:PutObject"]
        Resource = "arn:aws:s3:::my-bucket/*"
      }
    ]
  })
}

Use jsondecode() with variables

Pass a JSON string as a variable value and decode it inside the module. Useful when callers need to supply complex nested config.

variable "tags_json" {
  type        = string
  description = "JSON-encoded map of resource tags"
  default     = '{"environment":"dev","team":"platform"}'
}

locals {
  tags = jsondecode(var.tags_json)
}

resource "aws_s3_bucket" "example" {
  bucket = "my-example-bucket"
  tags   = local.tags
}

JSON type mapping

Terraform maps JSON types to HCL types automatically when you call jsondecode().

# JSON string   → HCL string
# JSON number   → HCL number
# JSON boolean  → HCL bool
# JSON null     → HCL null
# JSON array    → HCL list or tuple
# JSON object   → HCL object or map

locals {
  example = jsondecode('{"count":3,"active":true,"names":["a","b"],"meta":null}')
  # example.count  → 3       (number)
  # example.active → true    (bool)
  # example.names  → ["a","b"] (tuple)
  # example.meta   → null
}

Frequently Asked Questions

What does jsondecode() do in Terraform?

jsondecode() parses a JSON-encoded string and returns the equivalent Terraform value. It handles all JSON types: objects become HCL objects, arrays become tuples or lists, strings/numbers/booleans map directly.

How do I read a JSON file in Terraform?

Use jsondecode(file("path/to/file.json")). The file() function reads the file as a string and jsondecode() parses it into a Terraform value you can reference with dot notation.

What is the difference between jsondecode() and jsonencode()?

jsondecode() converts a JSON string into a Terraform value (parse). jsonencode() converts a Terraform value into a JSON string (serialize). They are inverses of each other.

Can I use jsondecode() with a variable?

Yes. Define a variable with type = string, pass a JSON string as its value (in terraform.tfvars or -var), and call jsondecode(var.my_var) in a local or resource argument.

How do I write an IAM policy in Terraform without a separate JSON file?

Use jsonencode() with an inline HCL object. This gives you type checking and avoids heredoc strings. Pass the result directly to the policy attribute of aws_iam_role_policy or aws_iam_policy.

Format and validate your JSON instantly

Free, no ads, no sign-up. Also converts JSON to TypeScript, YAML, CSV, and more.

Open JSON Formatter →

If jsondecode.com saved you time, share it with your team

Free forever. No ads. No sign-up. Help other developers find it.