diff --git a/hcl2template/internal/mock.go b/hcl2template/internal/mock.go index 3c36528f3..bf746ed5c 100644 --- a/hcl2template/internal/mock.go +++ b/hcl2template/internal/mock.go @@ -74,7 +74,7 @@ var _ packer.Builder = new(MockBuilder) func (b *MockBuilder) ConfigSpec() hcldec.ObjectSpec { return b.Config.FlatMapstructure().HCL2Spec() } func (b *MockBuilder) Prepare(raws ...interface{}) ([]string, []string, error) { - return nil, nil, b.Config.Prepare(raws...) + return []string{"ID"}, nil, b.Config.Prepare(raws...) } func (b *MockBuilder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { diff --git a/hcl2template/testdata/complete/build.pkr.hcl b/hcl2template/testdata/complete/build.pkr.hcl index d26ecb4ed..ef73e65f9 100644 --- a/hcl2template/testdata/complete/build.pkr.hcl +++ b/hcl2template/testdata/complete/build.pkr.hcl @@ -11,7 +11,7 @@ build { provisioner "shell" { name = "provisioner that does something" - not_squashed = var.foo + not_squashed = "${var.foo} ${lower(build.ID)}" string = "string" int = "${41 + 1}" int64 = "${42 + 1}" diff --git a/hcl2template/types.packer_config.go b/hcl2template/types.packer_config.go index 2758c5ed1..3908c91fe 100644 --- a/hcl2template/types.packer_config.go +++ b/hcl2template/types.packer_config.go @@ -51,6 +51,7 @@ const ( inputVariablesAccessor = "var" localsAccessor = "local" sourcesAccessor = "source" + buildAccessor = "build" ) // EvalContext returns the *hcl.EvalContext that will be passed to an hcl @@ -354,24 +355,25 @@ func (cfg *PackerConfig) GetBuilds(opts packer.GetBuildsOptions) ([]packer.Build continue } - variables := map[string]cty.Value{ - sourcesAccessor: cty.ObjectVal(map[string]cty.Value{ - "type": cty.StringVal(src.Type), - "name": cty.StringVal(src.Name), - }), - } - // If the builder has provided a list of to-be-generated variables that // should be made accessible to provisioners, pass that list into // the provisioner prepare() so that the provisioner can appropriately // validate user input against what will become available. Otherwise, // only pass the default variables, using the basic placeholder data. generatedPlaceholderMap := packer.BasicPlaceholderData() - if generatedVars != nil { - for _, k := range generatedVars { - generatedPlaceholderMap[k] = fmt.Sprintf("Build_%s. "+ - common.PlaceholderMsg, k) - } + unknownBuildValues := map[string]cty.Value{} + for _, k := range generatedVars { + generatedPlaceholderMap[k] = fmt.Sprintf("Build_%s. "+ + common.PlaceholderMsg, k) + unknownBuildValues[k] = cty.StringVal("") + } + + variables := map[string]cty.Value{ + sourcesAccessor: cty.ObjectVal(map[string]cty.Value{ + "type": cty.StringVal(src.Type), + "name": cty.StringVal(src.Name), + }), + buildAccessor: cty.ObjectVal(unknownBuildValues), } provisioners, moreDiags := cfg.getCoreBuildProvisioners(src, build.ProvisionerBlocks, cfg.EvalContext(variables), generatedPlaceholderMap)