# Jsonencode example from docs fails from console

**URL:** <https://discuss.hashicorp.com/t/jsonencode-example-from-docs-fails-from-console/11064>\
**Category:** Terraform\
**Created:** [July 6, 2020, 2:25pm UTC](https://discuss.hashicorp.com/t/jsonencode-example-from-docs-fails-from-console/11064 "2020-07-06T14:25:49Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jaknn](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/jaknn/32/8031_2.png) [@jaknn](https://discuss.hashicorp.com/u/jaknn)\
**Post date:** [July 6, 2020, 2:25pm UTC](https://discuss.hashicorp.com/t/jsonencode-example-from-docs-fails-from-console/11064/1 "2020-07-06T14:25:49Z")

</div>

I am trying to build a module which produces AWS IAM policy documents using templatefile() and the string template syntax. However, I am struggling to debug errors with the interpolation and directive syntax.

I am even struggling to get the examples from the [docs](https://www.terraform.io/docs/configuration/functions/templatefile.html) working:

```auto
terraform console
> ${jsonencode({"backends": [for addr in ["10.0.0.1", "10.0.0.2"] : "${addr}:8080"],})}

Error: Invalid character

  on <console-input> line 1:
  (source code not available)

This character is not used within the language.

Error: Invalid expression

  on <console-input> line 1:
  (source code not available)

Expected the start of an expression, but found an invalid expression token.

```

Ultimately, I hope to have a policy template and allow the user to provide a list of ARNs to include in the Resource section of a statement in a policy document like this:

```auto
# file = policy.json
${jsonencode(
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": 
              [for bucket in buckets : "${s3_arn_prefix}${bucket}"],          
        }
    ]
  }
)}

# file = main.tf

# Create an IAM policy document based on the template
data "aws_iam_policy_document" "document" {
    source_json = templatefile("${path.module}/policy.json", {
      s3_arn_prefix = local.s3_arn_prefix, 
      buckets = var.buckets # a list of bucket names
      })
}

```

---

<div class="post-metadata">

**Author:** ![jaknn](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/jaknn/32/8031_2.png) [@jaknn](https://discuss.hashicorp.com/u/jaknn)\
**Post date:** [July 6, 2020, 2:53pm UTC](https://discuss.hashicorp.com/t/jsonencode-example-from-docs-fails-from-console/11064/2 "2020-07-06T14:53:50Z")

</div>

**UPDATE:**

I was able to get the IAM policy example above to work with a simpler syntax – I just pass the list of ARNs as-is to the template:

```auto
# file = policy.json
...
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": "${buckets}"
        }

# file = main.tf
data "aws_iam_policy_document" "document" {
    source_json = templatefile("${path.module}/policy.json", {
      buckets = var.buckets # buckets is a list
      })
}

```

That produces correct IAM policy JSON which can be used to create a managed policy:

```auto
...
            "Resource": [
                "arn:aws:s3:::foo",
                "arn:aws:s3:::bar"
            ]

```

---

<div class="post-metadata">

**Author:** ![apparentlymart](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/apparentlymart/32/702_2.png) [@apparentlymart](https://discuss.hashicorp.com/u/apparentlymart)\
**Post date:** [July 6, 2020, 6:12pm UTC](https://discuss.hashicorp.com/t/jsonencode-example-from-docs-fails-from-console/11064/3 "2020-07-06T18:12:05Z")

</div>

Hi @jaknn,

The example in the docs shows the function used directly without wrapping in `${` and `}`:

```auto
> templatefile("${path.module}/backends.tmpl", { port = 8080, ip_addrs = ["10.0.0.1", "10.0.0.2"] })
backend 10.0.0.1:8080
backend 10.0.0.2:8080

```

The `terraform console` prompt expects Terraform language _expressions_, not [string templates](https://www.terraform.io/docs/configuration/expressions.html#string-templates). If you want to evaluate a string template in the console then you’d also need to include quotes to indicate your intent to evaluate a template:

```auto
> "${templatefile("${path.module}/backends.tmpl", { port = 8080, ip_addrs = ["10.0.0.1", "10.0.0.2"] })}"

```

The template syntax isn’t adding anything in this case, though: the template consists only of a single interpolation sequence, and so it’s redundant.
