Variables not loading from *.auto.pkrvars.hcl files if no defaults in HCL

When trying to follow the steps in the packer tutorial (Variables | Packer - HashiCorp Learn)

the variable definitions do not get auto loaded from the files within the directory unless a default value is included in the HCL file.

packer version: Packer v1.8.0
OS: Linux 5.16.14-1-MANJARO

For the tutorial only 2 files are in use

docker-ubuntu.pkr.hcl
variables.auto.pkrvars.hcl

docker-ubuntu.pkr.hcl

packer {
  required_plugins {
    docker = {
      version = ">= 0.0.7"
      source  = "github.com/hashicorp/docker"
    }
  }
}

source "docker" "ubuntu" {
  image  = var.docker_image
  commit = true
}

source "docker" "ubuntu-bionic" {
  image  = "ubuntu:bionic"
  commit = true
}

build {
  name = "learn-packer"
  sources = [
    "source.docker.ubuntu",
    "source.docker.ubuntu-bionic"
  ]

  provisioner "shell" {
    environment_vars = [
      "FOO=hello world",
    ]
    inline = [
      "echo Adding file to Docker Container",
      "echo \"FOO is $FOO\" > example.txt",
    ]
  }
 
  post-processor "docker-tag" {
    repository = "learn-packer"
    tags       = [var.docker_tag, "packer-rocks"]
    only       = ["docker.ubuntu"]
  }

  post-processor "docker-tag" {
    repository = "learn-packer"
    tags       = ["ubuntu-bionic", "packer-rocks"]
    only       = ["docker.ubuntu-bionic"]
  }
}

variables.auto.pkrvars.hcl

docker_image = "ubuntu:groovy"
docker_tag = "ubuntu-groovy"

Then running

packer build .
Warning: Undefined variable

A "docker_image" variable was set but was not found in known variables. To
declare variable "docker_image", place this block in one of your .pkr files,
such as variables.pkr.hcl
....
--> learn-packer.docker.ubuntu-bionic: Imported Docker image: learn-packer:packer-rocks with tags learn-packer:ubuntu-bionic learn-packer:packer-rock

packer build -var-file=variables.auto.pkrvars.hcl .
Warning: Undefined variable

A "docker_image" variable was set but was not found in known variables. To
declare variable "docker_image", place this block in one of your .pkr files,
such as variables.pkr.hcl
....
--> learn-packer.docker.ubuntu-bionic: Imported Docker image: learn-packer:packer-rocks with tags learn-packer:ubuntu-bionic learn-packer:packer-rock

If I then add default variables to the hcl

docker-ubuntu.pkr.hcl

packer {
  required_plugins {
    docker = {
      version = ">= 0.0.7"
      source  = "github.com/hashicorp/docker"
    }
  }
}

variable "docker_image" {
  type    = string
  default = "ubuntu:xenial"
}

variable "docker_tag" {
  type    = string
  default = "ubuntu-xenial"
}

source "docker" "ubuntu" {
  image  = var.docker_image
  commit = true
}

source "docker" "ubuntu-bionic" {
  image  = "ubuntu:bionic"
  commit = true
}

build {
  name = "learn-packer"
  sources = [
    "source.docker.ubuntu",
    "source.docker.ubuntu-bionic"
  ]

  provisioner "shell" {
    environment_vars = [
      "FOO=hello world",
    ]
    inline = [
      "echo Adding file to Docker Container",
      "echo \"FOO is $FOO\" > example.txt",
    ]
  }
 
  post-processor "docker-tag" {
    repository = "learn-packer"
    tags       = [var.docker_tag, "packer-rocks"]
    only       = ["docker.ubuntu"]
  }

  post-processor "docker-tag" {
    repository = "learn-packer"
    tags       = ["ubuntu-bionic", "packer-rocks"]
    only       = ["docker.ubuntu-bionic"]
  }
}
packer build .
....
--> learn-packer.docker.ubuntu: Imported Docker image: learn-packer:packer-rocks with tags learn-packer:ubuntu-groovy learn-packer:packer-rocks
--> learn-packer.docker.ubuntu-bionic: Imported Docker image: learn-packer:packer-rocks with tags learn-packer:ubuntu-bionic learn-packer:packer-rocks

It does not mention in the tutorial or in the documentation for variables that a default is required in order for build command to run and seems that the build and validate commands will only run correctly if defaults are included.

2 Likes

+1 Thanks for pointing this out! Saved me a bunch of headache

The documentation is a bit confusing, especially in regards the variable definitions and declarations.

What I’ve found is that the .pkrvar.hcl files are only for variable declaration, where the .pkr.hcl files are for the variable definitions, as well as the other subsections.

I was hoping that there was a way to define the variables outside of the main pkr.hcl files but, unfortunately, that doesn’t seem to be the case.

It looks like you can have a variable definition file, variable declaration file, and a build template file. The only way I’ve got it to work is to call ./packer build .

Files:
example_def.auto.pkr.hcl

variable "image_id" {
    type = string
    default = "ami-1234"
}

example_var.auto.pkrvars.hcl

image_id = "ami-5678"

example.pkr.hcl

source "null" "test"{
}

build {
  source "null.test" {
    ssh_host = "test"
    ssh_username = "test"
    communicator = "none"
  }

  provisioner "shell-local" {
    inline = [
      "echo ${var.image_id}"
    ]
  }
}

If all of the files above are in the same folder, and you call:
./packer build <folder>

The output will be:

null.test: C:\packer>echo ami-5678
null.test: ami-5678

If the auto.pkrvars.hcl file is missing, then the variable will default to the default in the variable definition file.

Looking at a JSON convert to HCL file, using the hcl2_upgrade parameter, I think I found what I was looking for.

# The HCL2 blocks in this file can be moved to other files. For example, the variable blocks could be

# moved to their own 'variables.pkr.hcl' file, etc. Those files need to be

# suffixed with '.pkr.hcl' to be visible to Packer. To use multiple files at

# once they also need to be in the same folder. 'packer inspect folder/'

# will describe to you what is in that folder.