1

I have inherited a Packer project that has an odd syntax in the "default" field of the variable definitions. I have a pkrvars file that I am assigning the variables in, using the variable name block (e.g sshkey, subscription_id, etc).

What is the purpose of the #{variablename}# syntax?

I know that the team was working on automating these images with terraform and azure devops, but my searches haven't turned up much yet. The packer documentation and articles that I find all use the ${variablename} syntax to use variables. I think that it is some syntax for getting the azure devops pipeline defined variables, but was hoping to find some documentation to read about it (and improve my understanding).

variable "sshkey" {
  type    = string
  default = "#{sshkey}#"
}

variable "subscription_id" {
  type    = string
  default = "#{subscriptionid}#"
}

variable "tenant_id" {
  type    = string
  default = "#{tenantid}#"
}

variable "vm_size" {
  type    = string
  default = "#{vmsize}#"
}
Matthew Schuchard
  • 25,172
  • 3
  • 47
  • 67
Emeria
  • 168
  • 1
  • 14
  • 2
    This syntax in question is not HCL2 syntax. This is a specific convention that the previous person apparently used to stub `default` arguments with useless values for whatever reason (perhaps to `validate` Packer templates without inputting variables or variable files, or for some other reason). These default values would all need to be overridden during actual `packer build`. Your pipeline would presumably supply those overrides. I can convert this into an answer if this fully satisfies your question. – Matthew Schuchard Aug 27 '21 at 14:49
  • 1
    Also these default arguments in the variable declaration would all be removed by best practices to signify they are required and not optional. Otherwise you would encounter runtime errors that should be earlier workflow compilation errors instead. – Matthew Schuchard Aug 27 '21 at 14:54
  • 1
    I think you are correct. You can convert this to the answer! – Emeria Aug 27 '21 at 15:18

1 Answers1

2

In HCL2 syntax variable declarations contain various arguments as can be viewed in the documentation. This specific question is around the default argument, which supplies a value for the default value for a variable in a Packer template. This value must not be a dynamic expression, interpolated, etc.

In this situation, the values are literal strings such as #{sshkey}#. This signifies that literal string will be passed as the default value for the variable, which almost certainly will cause a runtime error against the source and/or build API as the value is a placeholder. These values would all need to be replaced with Packer input variables or variables files during an execution. If you are using Azure DevOps, I would have to assume this occurs within the pipeline where the values or files are passed as arguments to packer build or other Packer commands.

These default argument values currently would cause runtime errors if a value is not input for each, because they falsely cause the variables to be interpreted as optional instead of required. Best practices would involve removing these default arguments such that Packer would error during compilation/pre-check instead of runtime if an input is missing. This would improve workflow efficiency and debugging.

The best guess as to why these values were stubbed in the default arguments is perhaps to avoid missing variable input errors during a packer validate as part of CI or personal workflows. However, if packer validate is executed on the project directory instead of on the specific template and *.pkrvars.hcl are present, or if a file is supplied as an argument for the variables file, Packer would then also successfully validate the template(s) without these side issues.

Matthew Schuchard
  • 25,172
  • 3
  • 47
  • 67
  • After some more digging today, I started to get into the pipelines in AzureDevOps and they are using an extension called ReplaceTokens (https://marketplace.visualstudio.com/items?itemName=qetza.replacetokens). It looks like they run a step in the pipeline that replaces #{}# values with the actual values defined in a variables.yml file. – Emeria Aug 27 '21 at 18:19
  • 1
    @Emeria That should be replaced in the pipeline with variable file inputs instead. That would be much more stable and easier for you. – Matthew Schuchard Aug 27 '21 at 19:07