Adding jsonencode() block into a generated terraform file using golang cty

Hi
Kind of new at this, so apology in advance if I’m asking a question that was answered already.
I’m trying to generate a tf file using the golang cty library.
It’s pretty straightforward. However, I have this section:

  custom_fields = {
    alternate_contact = jsonencode({somecode})
}

How can I add the jsonencode() section into my generated tf file

Hi @guyoha!

Do you already have some code that’s generating a similar structure to what you want? It would help if you could share what you already tried as a starting point. Thanks!

Hey @apparentlymart
Yes, what I was able to achieve is to get my tf file generated but without the “jsonencode” section.

This is my code:

	moduleBody.SetAttributeValue("custom_fields", cty.ObjectVal(map[string]cty.Value{
		"alternate_contact": cty.ObjectVal(map[string]cty.Value{
			"billing": cty.ObjectVal(map[string]cty.Value{
				"email-address": cty.StringVal(""),
				"name":          cty.StringVal(""),
				"phone-number":  cty.StringVal(""),
				"title":         cty.StringVal(""),
			}),
			"operations": cty.ObjectVal(map[string]cty.Value{
				"email-address": cty.StringVal(""),
				"name":          cty.StringVal(""),
				"phone-number":  cty.StringVal(""),
				"title":         cty.StringVal(""),
			}),
			"security": cty.ObjectVal(map[string]cty.Value{
				"email-address": cty.StringVal(""),
				"name":          cty.StringVal(""),
				"phone-number":  cty.StringVal(""),
				"title":         cty.StringVal(""),
			}),
		}),
	}))

And this is what I get out of it:

  custom_fields = {
    alternate_contact = {
      billing = {
        email-address = ""
        name          = ""
        phone-number  = ""
        title         = ""
      }
      operations = {
        email-address = ""
        name          = ""
        phone-number  = ""
        title         = ""
      }
      security = {
        email-address = ""
        name          = ""
        phone-number  = ""
        title         = ""
      }
    }
   }
	file.Body().SetAttributeRaw("something",
		hclwrite.TokensForFunctionCall("jsonencode",
			hclwrite.TokensForValue(cty.ObjectVal(map[string]cty.Value{
				"foo": cty.StringVal(""),
				"bar": cty.StringVal(""),
				"baz": cty.StringVal(""),
			})),
		))

gives

something = jsonencode({
  bar = ""
  baz = ""
  foo = ""
})

Thanks @maxb the thing is that the “jsoncode” is in the second layer (below “custom_fields”) on the body block.
any suggestion how can I “SetAttributeRaw” inside a “SetAttributeValue” ?

You can’t - you have to use SetAttributeRaw instead of SetAttributeValue.

There are other helper functions such as hclwrite.TokensForObject which can help you build up an object literal, and then you can switch to hclwrite.TokensForValue to create the deeper parts of a value which are pure data, without function calls or similar.