Managing Tags using HCL2

Hi there,

I’m trying out the new HCL2 support in Packer, and I’m a bit puzzling on how I should create and manage resource tagging.

From your document here: https://packer.io/docs/configuration/from-1.5/locals.html, I was under the impression that I should be able to use the merge() function similar to how we create tags in Terraform. However, I keep getting the following error which I’m not sure why:

Error: Unsupported argument
  on centos.pkr.hcl line 16, in source "amazon-ebs" "centos":
  16:   tags = "${merge(
An argument named "tags" is not expected here. Did you mean to define a block of
type "tags"?

On the other hand, I found a different example where we could use dynamic-blocks to manage tags: https://packer.io/docs/configuration/from-1.5/expressions.html#dynamic-blocks
This method does seem to work, but it’s not ideal if we would like to use the same set of tags for the running instance, AMI and the volume snapshots.

Could you please confirm if we can use merge() for this use case? If not, what would be your recommendation if we would like to setup a base set of tags and add a different name tag for the running instance, AMI and the volume snapshots?

Thanks!
-Ming

Hey Ming !

Thanks for trying out HCL2 on Packer !!! Please note that Packer+HCL2 is currently beta and things could change/break :slight_smile: ( for the best here ).

First let me explain the error you have here:

Error: Unsupported argument
  on centos.pkr.hcl line 16, in source "amazon-ebs" "centos":
  16:   tags = "${merge(
An argument named "tags" is not expected here. Did you mean to define a block of
type "tags"?

Here Packer expects to see something like tags {} instead of tags = {} ( for now ). So if the receiving type was a map or an array this would have worked, but in this specific case it’s a block. In HCL v1 ( the one used by Terraform 0.11) , it was possible to treat attributes and nested blocks interchangeably, but not anymore.

Now when I made Packer understand HCL2 I generated the HCL2 code from the existing go code and this seemed the best approach to make tags be blocks but looking at it better I think this needs to change, so that tags can be used just the way you tried; I believe these tags should be usable just like you are using I’m opened this new issue to fix this: https://github.com/hashicorp/packer/issues/9024

Also in the meantime I recommend using the dynamic block stanza to achieve this, for example:

dynamic "tag" {
    for_each = ${merge(
        local.common_tags,
        map(
            "${var.awesome-tag-something}.${var.something_something.name}", "awesome-tag-example"
        )
    )}
    content {
        name                = tag.key
        value               = tag.value
    }
}

I would also may be make the result of the merge into a new variable for a shorter config.

2 Likes

Thank you for the detail explanation, azr!

I do look forward to this change because it will also clear the confusion I had earlier when I was trying to understand the differences between tag and tags from your documentation here: https://packer.io/docs/builders/amazon-ebs.html#tags

I’ve subscribed the mentioned GitHub issue and will monitor the status on that one.

Cheers,
-Ming

1 Like