hashicorp / packer

Packer is a tool for creating identical machine images for multiple platforms from a single source configuration.
http://www.packer.io
Other
15.1k stars 3.33k forks source link

Dynamic block docs state "labels" is optional, but cli indicates it is required #12024

Open edqallen opened 2 years ago

edqallen commented 2 years ago

Community Note

Overview of the Issue

As the subject line states, the documentation states the following:

The labels argument (optional) is a list of strings....

However in attempting to use a build block with a dynamic source block within, the CLI outputs The argument "labels" is required, but no definition was found.

Reproduction Steps

Create a valid source block. Create a valid dynamic source block within a valid build block by moving some statements to it from the original source block. Do not create a labels statement, and then run packer validate against the result.

Packer version

1.8.3

Simplified Packer Template

External variable file has e.g. vm-name-prefix = "test-image-"

locals {
  sizes = ["small", "medium", "large"]
}

source "vsphere-iso" "standard" {
  CPUs                 = "${var.vm-cpu-num}"
  RAM                  = "${var.vm-mem-size}"
  ....etc....
}

build {
  dynamic "source" {
    for_each = local.sizes
    content {
      vm_name        = "${var.vm-name-prefix}${source.value}"
    }
  }
}

Operating system and Environment details

Ubuntu 20.04.1.

nywilken commented 1 year ago

Hi @edqallen apologies for the delayed response here. The labels argument in this case is required because the generated source blocks require a label the references the top-level source resource source "vsphere-iso" "standard". In order to get this template to work, if you haven't already figured it out you will need to update your dynamic block to look like the following.

build {
  dynamic "source" {
    for_each = local.sizes
    labels = ["vsphere-iso.standard"]
    content {
      name               = "${var.vm-name-prefix}${source.value}" # I recommend adding a name to distinguish the builds otherwise they will all have the same name.
      vm_name        = "${var.vm-name-prefix}${source.value}"
    }
  }
}

Which should result in the following build block.

build
  source "vsphere-iso.standard" {
      name = "test-image-small"
     vm_name = "test-image-small"
   }
 source "vsphere-iso.standard" {
         name = "test-image-medium"

     vm_name = "test-image-medium"
   }
source "vsphere-iso.standard" {
      name = "test-image-large"
     vm_name = "test-image-large"
   }
}

Please let me know if this answers your question.