How to create an array of non-quoted identifiers
I am trying to create this structure:
resource "aws_network_acl" "main-private" {
vpc_id = aws_vpc.main.id
subnet_ids = [aws_subnet.a.id, aws_subnet.b.id, aws_subnet.c.id, aws_subnet.d.id, aws_subnet.e.id, aws_subnet.f.id]
tags {
Name = "main-private"
}
}
I'm not sure what is the best way to create the array of non-quoted identifiers - this works but I'm not sure if its optimal, and I'm thinking the tokens should wrap at some point but hclwriite doesn't seem to be doing it.
subnetIds := []string{"aws_subnet.a.id", "aws_subnet.b.id", "aws_subnet.c.id", "aws_subnet.d.id", "aws_subnet.e.id", "aws_subnet.f.id"}
var subnetTokens []hclwrite.Tokens
for _, id := range subnetIds {
tokens := hclwrite.TokensForIdentifier(id)
subnetTokens = append(subnetTokens, tokens)
}
privateNACLBody.SetAttributeRaw("subnet_ids", hclwrite.TokensForTuple(subnetTokens))
I had also come up with this which is easier on the eyes but the identifiers are quoted which they should not be:
resourceBody.SetAttributeValue("subnet_ids", cty.ListVal([]cty.Value{
cty.StringVal("aws_subnet.x.id"),
cty.StringVal("aws_subnet.y.id"),
cty.StringVal("aws_subnet.z.id"),
}),
)
An expression like aws_subnet.a.id is called a "traversal" in HCL's terminology: it "traverses" through symbols in the current scope.
Therefore you can construct tokens for an expression like that using hcl.TokensForTraversal. This API is a little weird because the hcl.Traversal type was designed primarily to represent a parsing result rather than as input to a code generator, but you can leave the various "source range" fields unpopulated when you are constructing a traversal purely for use with hclwrite.
aws_subnet.a.id is a traversal with three steps:
-
hcl.TraverseRootwithName: "aws_subnet". -
hcl.TraverseAttrwithName: "a". -
hcl.TraverseAttrwithName: "id".
You can use the hclwrite.TokensForTraversal results with hclwrite.TokensForTuple to assemble the final result.
hclwrite's auto-formatting does not currently ever introduce new line breaks that were not present in the input; it focuses only on "horizontal" whitespace and alignment, such as indenting nested blocks. I don't think there is currently any "TokensFor..." function that will produce a tuple where each element is wrapped onto a separate line, so producing that particular layout would require constructing a custom hclwrite.Tokens to use for the outer tuple.
@apparentlymart Thank you!