Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is There a Way to Generate Anonymous Blocks with Variable References #696

Open
SachithKasthuriarachchi opened this issue Aug 29, 2024 · 1 comment

Comments

@SachithKasthuriarachchi

Hi, Is there any guide on generating something like the following in go?

data = {
    config.hcl = data.template_file.vault_config.rendered
}

Attempt

dataMap := map[string]cty.Value{
		"config.hcl": cty.StringVal("data.template_file.vault_config.rendered"),
}
body.SetAttributeValue("data", cty.ObjectVal(dataMap))

However this generates the following (with quotes)

data = {
    "config.hcl" = "data.template_file.vault_config.rendered"
}
@bschaatsbergen
Copy link
Member

bschaatsbergen commented Oct 8, 2024

Hi @SachithKasthuriarachchi,

It seems you're trying to assign a map/object type to the data attribute. From what I know, you'll need to use the lower-level API, hclsyntax, and work with tokens to achieve this. However, if you're setting the attribute like this: config.hcl = data.template_file.vault_config.rendered inside a block, it’s simpler, and you can keep using hclwrite.

Building a map/object and assigning it to an attribute

Start by using hclwrite to create a new empty file and build up the tokens for config.hcl and its value:

file := hclwrite.NewEmptyFile()
body := file.Body()

dataBody := hclwrite.NewEmptyFile().Body()

dataBody.SetAttributeTraversal("config.hcl", hcl.Traversal{
	hcl.TraverseRoot{Name: "data"},
	hcl.TraverseAttr{Name: "template_file"},
	hcl.TraverseAttr{Name: "vault_config"},
	hcl.TraverseAttr{Name: "rendered"},
})

dataTokens := dataBody.BuildTokens(nil)

If you print the dataTokens, you’ll see config.hcl = data.template_file.vault_config.rendered.

Next, we’ll set the data attribute and add the assignment for a map/object value by setting the equal token (=) and wrapping config.hcl with the opening ({) and closing brace token (}).

Here’s how we build the tokens:

dataAttrTokens := hclwrite.Tokens{
	&hclwrite.Token{
		Type:  hclsyntax.TokenEqual,
		Bytes: nil,
	},
	&hclwrite.Token{
		Type:  hclsyntax.TokenOBrace,
		Bytes: []byte("{\n"),
	},
}
dataAttrTokens = append(dataAttrTokens, dataTokens...)
dataAttrTokens = append(dataAttrTokens, &hclwrite.Token{
	Type:  hclsyntax.TokenCBrace,
	Bytes: []byte("}"),
})

This wraps the config.hcl key with an equal sign and braces.

Finally, we assign the dataAttrTokens to the data attribute to complete the map/object:

body.SetAttributeRaw("data", dataAttrTokens)
hclwrite.Format(file.Bytes())

Note that we format the file bytes to handle any whitespace issues due to the token wrangling we’ve done.

I hope this was helpful and exactly what you were looking for.​
h/t @picatz for collaborating on this with me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants