Merge pull request #9291 from hashicorp/f-singular-build-source-blocks

Allow to set source fields from a new `build.source` block
pull/9245/head
Adrien Delorme 6 years ago committed by GitHub
commit 1147ef9a36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -14,6 +14,8 @@
read more about this[GH-8437]
### FEATURES:
* HCL2/core: it is now possible to set source fields from the `build` block
[GH-9291]
* **New post-processor** Yandex Export [GH-9124]
### IMPROVEMENTS:

@ -191,7 +191,7 @@ func (p *Parser) decodeConfig(f *hcl.File, cfg *PackerConfig) hcl.Diagnostics {
}
ref := source.Ref()
if existing := cfg.Sources[ref]; existing != nil {
if existing, found := cfg.Sources[ref]; found {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Duplicate " + sourceLabel + " block",
@ -205,7 +205,7 @@ func (p *Parser) decodeConfig(f *hcl.File, cfg *PackerConfig) hcl.Diagnostics {
}
if cfg.Sources == nil {
cfg.Sources = map[SourceRef]*SourceBlock{}
cfg.Sources = map[SourceRef]SourceBlock{}
}
cfg.Sources[ref] = source

@ -5,6 +5,10 @@ build {
"source.virtualbox-iso.ubuntu-1204",
]
source "source.amazon-ebs.ubuntu-1604" {
string = "setting from build section"
}
provisioner "shell" {
name = "provisioner that does something"
not_squashed = var.foo

@ -1,3 +1,9 @@
source "amazon-ebs" "ubuntu-1604" {
int = 42
}
source "virtualbox-iso" "ubuntu-1204" {
string = "string"
int = 42
@ -85,4 +91,4 @@ source "virtualbox-iso" "ubuntu-1204" {
["c","d"]
]
}
}
}

@ -19,6 +19,7 @@ const (
var buildSchema = &hcl.BodySchema{
Blocks: []hcl.BlockHeaderSchema{
{Type: buildFromLabel, LabelNames: []string{"type"}},
{Type: sourceLabel, LabelNames: []string{"reference"}},
{Type: buildProvisionerLabel, LabelNames: []string{"type"}},
{Type: buildPostProcessorLabel, LabelNames: []string{"type"}},
},
@ -56,7 +57,7 @@ func (p *Parser) decodeBuildConfig(block *hcl.Block) (*BuildBlock, hcl.Diagnosti
build := &BuildBlock{}
var b struct {
FromSources []string `hcl:"sources"`
FromSources []string `hcl:"sources,optional"`
Config hcl.Body `hcl:",remain"`
}
diags := gohcl.DecodeBody(block.Body, nil, &b)
@ -92,6 +93,13 @@ func (p *Parser) decodeBuildConfig(block *hcl.Block) (*BuildBlock, hcl.Diagnosti
}
for _, block := range content.Blocks {
switch block.Type {
case sourceLabel:
ref, moreDiags := p.decodeBuildSource(block)
diags = append(diags, moreDiags...)
if moreDiags.HasErrors() {
continue
}
build.Sources = append(build.Sources, ref)
case buildProvisionerLabel:
p, moreDiags := p.decodeProvisioner(block)
diags = append(diags, moreDiags...)

@ -49,7 +49,7 @@ func (p *Parser) decodePostProcessor(block *hcl.Block) (*PostProcessorBlock, hcl
return postProcessor, diags
}
func (cfg *PackerConfig) startPostProcessor(source *SourceBlock, pp *PostProcessorBlock, ectx *hcl.EvalContext, generatedVars map[string]string) (packer.PostProcessor, hcl.Diagnostics) {
func (cfg *PackerConfig) startPostProcessor(source SourceBlock, pp *PostProcessorBlock, ectx *hcl.EvalContext, generatedVars map[string]string) (packer.PostProcessor, hcl.Diagnostics) {
// ProvisionerBlock represents a detected but unparsed provisioner
var diags hcl.Diagnostics

@ -77,7 +77,7 @@ func (p *Parser) decodeProvisioner(block *hcl.Block) (*ProvisionerBlock, hcl.Dia
return provisioner, diags
}
func (cfg *PackerConfig) startProvisioner(source *SourceBlock, pb *ProvisionerBlock, ectx *hcl.EvalContext, generatedVars map[string]string) (packer.Provisioner, hcl.Diagnostics) {
func (cfg *PackerConfig) startProvisioner(source SourceBlock, pb *ProvisionerBlock, ectx *hcl.EvalContext, generatedVars map[string]string) (packer.Provisioner, hcl.Diagnostics) {
var diags hcl.Diagnostics
provisioner, err := cfg.provisionersSchemas.Start(pb.PType)

@ -18,7 +18,7 @@ type PackerConfig struct {
Basedir string
// Available Source blocks
Sources map[SourceRef]*SourceBlock
Sources map[SourceRef]SourceBlock
// InputVariables and LocalVariables are the list of defined input and
// local variables. They are of the same type but are not used in the same
@ -194,7 +194,7 @@ func (c *PackerConfig) evaluateLocalVariable(local *Local) hcl.Diagnostics {
// getCoreBuildProvisioners takes a list of provisioner block, starts according
// provisioners and sends parsed HCL2 over to it.
func (cfg *PackerConfig) getCoreBuildProvisioners(source *SourceBlock, blocks []*ProvisionerBlock, ectx *hcl.EvalContext, generatedVars map[string]string) ([]packer.CoreBuildProvisioner, hcl.Diagnostics) {
func (cfg *PackerConfig) getCoreBuildProvisioners(source SourceBlock, blocks []*ProvisionerBlock, ectx *hcl.EvalContext, generatedVars map[string]string) ([]packer.CoreBuildProvisioner, hcl.Diagnostics) {
var diags hcl.Diagnostics
res := []packer.CoreBuildProvisioner{}
for _, pb := range blocks {
@ -234,7 +234,7 @@ func (cfg *PackerConfig) getCoreBuildProvisioners(source *SourceBlock, blocks []
// getCoreBuildProvisioners takes a list of post processor block, starts
// according provisioners and sends parsed HCL2 over to it.
func (cfg *PackerConfig) getCoreBuildPostProcessors(source *SourceBlock, blocks []*PostProcessorBlock, ectx *hcl.EvalContext, generatedVars map[string]string) ([]packer.CoreBuildPostProcessor, hcl.Diagnostics) {
func (cfg *PackerConfig) getCoreBuildPostProcessors(source SourceBlock, blocks []*PostProcessorBlock, ectx *hcl.EvalContext, generatedVars map[string]string) ([]packer.CoreBuildPostProcessor, hcl.Diagnostics) {
var diags hcl.Diagnostics
res := []packer.CoreBuildPostProcessor{}
for _, ppb := range blocks {
@ -262,15 +262,17 @@ func (cfg *PackerConfig) GetBuilds(opts packer.GetBuildsOptions) ([]packer.Build
for _, build := range cfg.Builds {
for _, from := range build.Sources {
src, found := cfg.Sources[from]
src, found := cfg.Sources[from.Ref()]
if !found {
diags = append(diags, &hcl.Diagnostic{
Summary: "Unknown " + sourceLabel + " " + from.String(),
Subject: build.HCL2Ref.DefRange.Ptr(),
Severity: hcl.DiagError,
Detail: fmt.Sprintf("Known: %v", cfg.Sources),
})
continue
}
src.addition = from.addition
// Apply the -only and -except command-line options to exclude matching builds.
buildName := fmt.Sprintf("%s.%s", src.Type, src.Name)

@ -1,10 +1,9 @@
package hcl2template
import (
"path/filepath"
"testing"
"time"
. "github.com/hashicorp/packer/hcl2template/internal"
"github.com/hashicorp/packer/packer"
"github.com/zclconf/go-cty/cty"
)
@ -72,12 +71,16 @@ func TestParser_complete(t *testing.T) {
}),
},
},
Sources: map[SourceRef]*SourceBlock{
refVBIsoUbuntu1204: {Type: "virtualbox-iso", Name: "ubuntu-1204"},
Sources: map[SourceRef]SourceBlock{
refVBIsoUbuntu1204: {Type: "virtualbox-iso", Name: "ubuntu-1204"},
refAWSEBSUbuntu1204: {Type: "amazon-ebs", Name: "ubuntu-1604"},
},
Builds: Builds{
&BuildBlock{
Sources: []SourceRef{refVBIsoUbuntu1204},
Sources: []SourceRef{
refVBIsoUbuntu1204,
refAWSEBSUbuntu1204,
},
ProvisionerBlocks: []*ProvisionerBlock{
{
PType: "shell",
@ -125,136 +128,40 @@ func TestParser_complete(t *testing.T) {
},
},
},
},
false,
},
{"dir with no config files",
defaultParser,
parseTestArgs{"testdata/empty", nil, nil},
nil,
true, true,
nil,
false,
},
{name: "inexistent dir",
parser: defaultParser,
args: parseTestArgs{"testdata/inexistent", nil, nil},
parseWantCfg: nil,
parseWantDiags: true,
parseWantDiagHasErrors: true,
},
{name: "folder named build.pkr.hcl with an unknown src",
parser: defaultParser,
args: parseTestArgs{"testdata/build.pkr.hcl", nil, nil},
parseWantCfg: &PackerConfig{
Basedir: "testdata/build.pkr.hcl",
Builds: Builds{
&BuildBlock{
Sources: []SourceRef{refAWSEBSUbuntu1204, refVBIsoUbuntu1204},
ProvisionerBlocks: []*ProvisionerBlock{
{PType: "shell"},
{PType: "file"},
},
PostProcessors: []*PostProcessorBlock{
{PType: "amazon-import"},
},
},
},
},
parseWantDiags: false,
parseWantDiagHasErrors: false,
getBuildsWantBuilds: []packer.Build{},
getBuildsWantDiags: true,
},
{name: "unknown block type",
parser: defaultParser,
args: parseTestArgs{"testdata/unknown", nil, nil},
parseWantCfg: &PackerConfig{
Basedir: "testdata/unknown",
},
parseWantDiags: true,
parseWantDiagHasErrors: true,
},
{"provisioner with wrappers pause_before and max_retriers",
defaultParser,
parseTestArgs{"testdata/build/provisioner_paused_before_retry.pkr.hcl", nil, nil},
&PackerConfig{
Basedir: filepath.Join("testdata", "build"),
Sources: map[SourceRef]*SourceBlock{
refVBIsoUbuntu1204: {Type: "virtualbox-iso", Name: "ubuntu-1204"},
},
Builds: Builds{
&BuildBlock{
Sources: []SourceRef{refVBIsoUbuntu1204},
ProvisionerBlocks: []*ProvisionerBlock{
{
PType: "shell",
PauseBefore: time.Second * 10,
MaxRetries: 5,
&packer.CoreBuild{
Type: "amazon-ebs.ubuntu-1604",
Prepared: true,
Builder: &MockBuilder{
Config: MockConfig{
NestedMockConfig: NestedMockConfig{
String: "setting from build section",
Int: 42,
Tags: []MockTag{},
},
NestedSlice: []NestedMockConfig{},
},
},
},
},
false, false,
[]packer.Build{
&packer.CoreBuild{
Type: "virtualbox-iso.ubuntu-1204",
Prepared: true,
Builder: emptyMockBuilder,
Provisioners: []packer.CoreBuildProvisioner{
{
PType: "shell",
Provisioner: &packer.RetriedProvisioner{
MaxRetries: 5,
Provisioner: &packer.PausedProvisioner{
PauseBefore: time.Second * 10,
Provisioner: emptyMockProvisioner,
},
},
PType: "shell",
PName: "provisioner that does something",
Provisioner: basicMockProvisioner,
},
{PType: "file", Provisioner: basicMockProvisioner},
},
PostProcessors: [][]packer.CoreBuildPostProcessor{},
},
},
false,
},
{"provisioner with wrappers timeout",
defaultParser,
parseTestArgs{"testdata/build/provisioner_timeout.pkr.hcl", nil, nil},
&PackerConfig{
Basedir: filepath.Join("testdata", "build"),
Sources: map[SourceRef]*SourceBlock{
refVBIsoUbuntu1204: {Type: "virtualbox-iso", Name: "ubuntu-1204"},
},
Builds: Builds{
&BuildBlock{
Sources: []SourceRef{refVBIsoUbuntu1204},
ProvisionerBlocks: []*ProvisionerBlock{
PostProcessors: [][]packer.CoreBuildPostProcessor{
{
{
PType: "shell",
Timeout: time.Second * 10,
PType: "amazon-import",
PName: "something",
PostProcessor: basicMockPostProcessor,
},
},
},
},
},
false, false,
[]packer.Build{
&packer.CoreBuild{
Type: "virtualbox-iso.ubuntu-1204",
Prepared: true,
Builder: emptyMockBuilder,
Provisioners: []packer.CoreBuildProvisioner{
{
PType: "shell",
Provisioner: &packer.TimeoutProvisioner{
Timeout: time.Second * 10,
Provisioner: emptyMockProvisioner,
{
PType: "amazon-import",
PostProcessor: basicMockPostProcessor,
},
},
},
PostProcessors: [][]packer.CoreBuildPostProcessor{},
},
},
false,

@ -16,10 +16,24 @@ type SourceBlock struct {
Name string
block *hcl.Block
// addition will be merged into block to allow user to override builder settings
// per build.source block.
addition hcl.Body
}
// decodeBuildSource reads a used source block from a build:
// build {
// source "type.example" {}
// }
func (p *Parser) decodeBuildSource(block *hcl.Block) (SourceRef, hcl.Diagnostics) {
ref := sourceRefFromString(block.Labels[0])
ref.addition = block.Body
return ref, nil
}
func (p *Parser) decodeSource(block *hcl.Block) (*SourceBlock, hcl.Diagnostics) {
source := &SourceBlock{
func (p *Parser) decodeSource(block *hcl.Block) (SourceBlock, hcl.Diagnostics) {
source := SourceBlock{
Type: block.Labels[0],
Name: block.Labels[1],
block: block,
@ -33,13 +47,13 @@ func (p *Parser) decodeSource(block *hcl.Block) (*SourceBlock, hcl.Diagnostics)
Detail: fmt.Sprintf("known builders: %v", p.BuilderSchemas.List()),
Severity: hcl.DiagError,
})
return nil, diags
return source, diags
}
return source, diags
}
func (cfg *PackerConfig) startBuilder(source *SourceBlock, ectx *hcl.EvalContext, opts packer.GetBuildsOptions) (packer.Builder, hcl.Diagnostics, []string) {
func (cfg *PackerConfig) startBuilder(source SourceBlock, ectx *hcl.EvalContext, opts packer.GetBuildsOptions) (packer.Builder, hcl.Diagnostics, []string) {
var diags hcl.Diagnostics
builder, err := cfg.builderSchemas.Start(source.Type)
@ -52,7 +66,12 @@ func (cfg *PackerConfig) startBuilder(source *SourceBlock, ectx *hcl.EvalContext
return builder, diags, nil
}
decoded, moreDiags := decodeHCL2Spec(source.block.Body, ectx, builder)
body := source.block.Body
if source.addition != nil {
body = hcl.MergeBodies([]hcl.Body{source.block.Body, source.addition})
}
decoded, moreDiags := decodeHCL2Spec(body, ectx, builder)
diags = append(diags, moreDiags...)
if moreDiags.HasErrors() {
return nil, diags, nil
@ -92,6 +111,19 @@ func (source *SourceBlock) Ref() SourceRef {
type SourceRef struct {
Type string
Name string
// The content of this body will be merged into a new block to allow to
// override builder settings per build section.
addition hcl.Body
}
// the 'addition' field makes of ref a different entry in the sources map, so
// Ref is here to make sure only one is returned.
func (r *SourceRef) Ref() SourceRef {
return SourceRef{
Type: r.Type,
Name: r.Name,
}
}
// NoSource is the zero value of sourceRef, representing the absense of an

@ -16,7 +16,7 @@ func TestParse_source(t *testing.T) {
parseTestArgs{"testdata/sources/basic.pkr.hcl", nil, nil},
&PackerConfig{
Basedir: filepath.Join("testdata", "sources"),
Sources: map[SourceRef]*SourceBlock{
Sources: map[SourceRef]SourceBlock{
{
Type: "virtualbox-iso",
Name: "ubuntu-1204",
@ -65,7 +65,7 @@ func TestParse_source(t *testing.T) {
parseTestArgs{"testdata/sources/duplicate.pkr.hcl", nil, nil},
&PackerConfig{
Basedir: filepath.Join("testdata", "sources"),
Sources: map[SourceRef]*SourceBlock{
Sources: map[SourceRef]SourceBlock{
{
Type: "virtualbox-iso",
Name: "ubuntu-1204",

@ -162,15 +162,17 @@ func TestParse_variables(t *testing.T) {
Name: "foo",
},
},
Sources: map[SourceRef]*SourceBlock{
SourceRef{"null", "null-builder"}: &SourceBlock{
Sources: map[SourceRef]SourceBlock{
SourceRef{"null", "null-builder", nil}: SourceBlock{
Name: "null-builder",
Type: "null",
},
},
Builds: Builds{
&BuildBlock{
Sources: []SourceRef{SourceRef{"null", "null-builder"}},
Sources: []SourceRef{
{"null", "null-builder", nil},
},
},
},
},

@ -14,6 +14,15 @@ export default [
'syntax',
'expressions',
'syntax-json',
{
category: 'blocks',
content: [
{
category: 'build',
content: [ 'source', 'provisioner', 'post-processor' ],
},
'locals', 'source', 'variable' ],
},
{
category: 'functions',
content: [

@ -0,0 +1,35 @@
---
description: >
The source block defines what builders are started.
layout: docs
page_title: build - Blocks
sidebar_title: <tt>build</tt>
---
# The `build` block
`@include 'from-1.5/beta-hcl2-note.mdx'`
The `build` block defines what builders are started, how to `provision` them
and if necessary what to do with their artifacts using `post-process`.
`@include 'from-1.5/builds/example-block.mdx'`
Define [top-level `source` blocks](/docs/from-1.5/blocks/source) to configure
your builders. The list of available builders can be found in the
[builders](/docs/builders) section.
To use builders in a `build` block you can either:
* Set the `sources` array of string with references to defined sources.
* Define [build-level `source` blocks](/docs/from-1.5/blocks/build/source) or
`sources` to use builders. This also allows you to set specific fields.
## Related
* A list of [community
builders](/community-tools#community-builders) is available.
* Create your own [custom builder](/docs/extending/custom-builders) !

@ -0,0 +1,29 @@
---
description: >
The post-processor block defines how a post-processor is configured.
layout: docs
page_title: post-processor - build - Blocks
sidebar_title: <tt>post-processor</tt>
---
# The `post-processor` block
`@include 'from-1.5/beta-hcl2-note.mdx'`
The `post-processor` block defines how a post-processor is configured.
```hcl
# builds.pkr.hcl
build {
# ...
post-processor "checksum" {
checksum_types = [ "md5", "sha512" ]
keep_input_artifact = true
}
}
```
Post-processors run after the image is built by the builder and provisioned by
the provisioner(s). Post-processors are optional, and they can be used to
upload artifacts, re-package, or more. The list of available post-processors
can be found in the [post-processors](/docs/post-processors) section.

@ -0,0 +1,32 @@
---
description: >
The provisioner block defines how a provisioner is configured.
layout: docs
page_title: provisioner - build - Blocks
sidebar_title: <tt>provisioner</tt>
---
# The `provisioner` block
`@include 'from-1.5/beta-hcl2-note.mdx'`
The `provisioner` block defines how a provisioner is configured.
```hcl
# builds.pkr.hcl
build {
# ...
provisioner "shell" {
inline = [
"echo provisioning all the things",
"echo the value of 'foo' is '${var.foo}'",
]
}
}
```
Provisioners use builtin and third-party software to install and configure the
machine image after booting. Provisioners prepare the system for use.
The list of available provisioners can be found in the
[provisioners](/docs/provisioners) section.

@ -0,0 +1,30 @@
---
description: >
A source block nested in a build block allows you to use an already defined
source and to set specific fields.
layout: docs
page_title: source - build - Blocks
sidebar_title: <tt>source</tt>
---
# The `source` block
`@include 'from-1.5/beta-hcl2-note.mdx'`
A `source` block nested in a `build` block allows to use an already defined
source and to set specific fields.
```hcl
# builds.pkr.hcl
build {
source "amazon-ebs.example" {
output = "specific-value"
}
# ...
}
```
-> **Note:** It is **not allowed** to set the same field in a top-level source
block and in a used source block. For example, if in the above example, the
top-level "amazon-ebs.example" source block also had an `output` field;
Packer would error.

@ -0,0 +1,31 @@
---
layout: docs
page_title: Blocks - Configuration Language
sidebar_title: Blocks
description: |-
The HCL language has a number of blocks that can be used to configure builds.
---
# Built-in Blocks
`@include 'from-1.5/beta-hcl2-note.mdx'`
The Packer - HCL2 language includes a number of built-in blocks that you can
use. A block is a container for configuration.
Blocks can be defined in multiple files and `packer build folder` will build
using solely the files from a directory named `folder`.
Packer does not support user-defined blocks and so only the blocks built in to
the language are available for use. The navigation for this section includes a
list of all of the available built-in HCL2 blocks.
## Config example:
`@include 'from-1.5/variables/foo-block.mdx'`
`@include 'from-1.5/locals/example-block.mdx'`
`@include 'from-1.5/sources/example-block.mdx'`
`@include 'from-1.5/builds/example-block.mdx'`

@ -0,0 +1,23 @@
---
description: >
The locals block also called the local-variable block defines locals within
your Packer configuration.
layout: docs
page_title: locals - Blocks
sidebar_title: <tt>locals</tt>
---
# The `locals` block
`@include 'from-1.5/beta-hcl2-note.mdx'`
The `locals` block, also called the `local-variable` block, defines locals within
your Packer configuration.
`@include 'from-1.5/locals/example-block.mdx'`
# More on variables
- Read the [full locals](/docs/from-1.5/locals) description for a more
thorough read.
- Read the [variables guide](/guides/hcl/variables) for more examples.

@ -0,0 +1,50 @@
---
description: >
The top-level source block defines reusable builder configuration blocks
layout: docs
page_title: source - Blocks
sidebar_title: <tt>source</tt>
---
# The `source` block
`@include 'from-1.5/beta-hcl2-note.mdx'`
The top-level `source` block defines reusable builder configuration blocks:
`@include 'from-1.5/sources/example-block.mdx'`
You can start builders by refering to those source blocks form a [`build`
block](/docs/from-1.5/blocks/build), for example :
```hcl
build {
source = [
# Here Packer will use a default ami_name when saving the image.
"sources.amazon-ebs.example",
"sources.amazon-ebs.foo",
]
}
```
The build-level [`source` block](/docs/from-1.5/blocks/build/source) allows to
set specific source fields.
```hcl
build {
source "sources.amazon-ebs.example" {
# Here Packer will use the provided ami_name instead of defaulting it.
ami_name = "specific"
}
}
```
## Related
* The list of available builders can be found in the [builders](/docs/builders)
section.
* A list of [community
builders](/community-tools#community-builders) is available.
* Create your own [custom builder](/docs/extending/custom-builders) !

@ -0,0 +1,37 @@
---
description: >
The variable block, also called the input-variable block, defines variables
within your Packer configuration.
layout: docs
page_title: variable - Blocks
sidebar_title: <tt>variable</tt>
---
# The `variable` block
`@include 'from-1.5/beta-hcl2-note.mdx'`
The `variable` block, also called the `input-variable` block, defines variables
within your Packer configuration. An input-variable cannot be used in another
input variable: we recommend using [locals](/docs/from-1.5/blocks/locals) for that instead.
`@include 'from-1.5/variables/foo-block.mdx'`
## Default value
If a default value is set, the variable is optional. Otherwise, the variable
**must** be set.
`@include 'from-1.5/variables/assignment.mdx'`
Example of a variable assignment from a file:
`@include 'from-1.5/variables/foo-pkrvar.mdx'`
`@include 'from-1.5/variables/must-be-set.mdx'`
# More on variables
- Read the [full variables](/docs/from-1.5/variables) description for a more
thorough read.
- Read the [variables guide](/guides/hcl/variables) for more examples.

@ -9,11 +9,7 @@ description: |-
# Expressions
-> **Note:** This page is about HCL2 in Packer 1.5 and later. HCL2 support for
Packer is still in Beta. Please see the [Packer Issue
Tracker](https://github.com/hashicorp/packer/issues/9176) for a list of
supported features. For the old-style stable configuration language see
[template docs](/docs/templates).
`@include 'from-1.5/beta-hcl2-note.mdx'`
_Expressions_ are used to refer to or compute values within a configuration.
The simplest expressions are just literal values, like `"hello"` or `5`, but

@ -9,9 +9,7 @@ description: |-
# Built-in Functions
-> **Note:** This page is about HCL2 in Packer 1.5 and later. HCL2 support for
Packer is still in Beta. For the old-style stable configuration language see
[template docs](/docs/templates).
`@include 'from-1.5/beta-hcl2-note.mdx'`
The HCL language includes a number of built-in functions that you can
call from within expressions to transform and combine values. The general

@ -10,11 +10,7 @@ description: |-
# HCL Configuration Language
-> **Note:** This page is about HCL2 in Packer 1.5 and later. HCL2 support for
Packer is still in Beta. Please see the [Packer Issue
Tracker](https://github.com/hashicorp/packer/issues/9176) for a list of
supported features. For the old-style stable configuration language see
[template docs](/docs/templates).
`@include 'from-1.5/beta-hcl2-note.mdx'`
Packer uses the Hashicorp Configuration Language - HCL - designed to allow
concise descriptions of the required steps to get to a build file. This page

@ -9,11 +9,7 @@ description: >-
# Local Values
-> **Note:** This page is about HCL2 in Packer 1.5 and later. HCL2 support for
Packer is still in Beta. Please see the [Packer Issue
Tracker](https://github.com/hashicorp/packer/issues/9176) for a list of
supported features. For the old-style stable configuration language see
[template docs](/docs/templates).
`@include 'from-1.5/beta-hcl2-note.mdx'`
Local values assign a name to an expression, that can then be used multiple
times within a folder.

@ -9,11 +9,7 @@ description: |-
# JSON Configuration Syntax
-> **Note:** This page is about HCL2 in Packer 1.5 and later. Whilst HCL2
supports JSON the JSON - JSON and the HCL2 - JSON have differents formats for
Packer. HCL2 support for Packer is still in Beta. For the old-style stable
configuration language see [template
docs](/docs/templates).
`@include 'from-1.5/beta-hcl2-note.mdx'`
Most Packer configurations are written in [the native HCL
syntax](/docs/from-1.5/syntax), which is designed to be easy for humans to read and

@ -10,11 +10,7 @@ description: |-
# HCL Configuration Syntax
-> **Note:** This page is about HCL2 in Packer 1.5 and later. HCL2 support for
Packer is still in Beta. Please see the [Packer Issue
Tracker](https://github.com/hashicorp/packer/issues/9176) for a list of
supported features. For the old-style stable configuration language see
[template docs](/docs/templates).
`@include 'from-1.5/beta-hcl2-note.mdx'`
Other pages in this section have described various configuration constructs
that can appear in HCL. This page describes the lower-level syntax of the

@ -9,11 +9,7 @@ description: |-
# Input Variables
-> **Note:** This page is about HCL2 in Packer 1.5 and later. HCL2 support for
Packer is still in Beta. Please see the [Packer Issue
Tracker](https://github.com/hashicorp/packer/issues/9176) for a list of
supported features. For the old-style stable configuration language see
[template docs](/docs/templates).
`@include 'from-1.5/beta-hcl2-note.mdx'`
Input variables serve as parameters for a Packer build, allowing aspects of the
build to be customized without altering the build's own source code.
@ -155,15 +151,7 @@ documentation about the build, and so it should be written from the perspective
of the user of the build rather than its maintainer. For commentary for build
maintainers, use comments.
## Assigning Values to build Variables
When variables are declared in the build of your configuration, they can be set
in a number of ways:
- Individually, with the `-var` command line option.
- In variable definitions (`.pkrvars.hcl`) files, either specified on the
command line or automatically loaded.
- As environment variables.
`@include 'from-1.5/variables/assignment.mdx'`
The following sections describe these options in more detail.
@ -285,40 +273,7 @@ precedence over earlier ones:
~> **Important:** Variables with map and object values behave the same way as
other variables: the last value found overrides the previous values.
### A variable value must be known:
Take the following variable for example:
```hcl
variable "foo" {
type = string
```
Here `foo` must have a known value but you can default it to `null` to make
this behavior optional :
| | no default | `default = null` | `default = "xy"` |
| :---------------------------: | :--------------------------: | :--------------: | :--------------: |
| foo unused | error, "foo needs to be set" | - | - |
| var.foo | error, "foo needs to be set" | null¹ | xy |
| `PKR_VAR_foo=yz`<br />var.foo | yz | yz | yz |
| `-var foo=yz`<br />var.foo | yz | yz | yz |
1: Null is a valid value. Packer will only error when the receiving field needs
a value, example:
```hcl
variable "example" {
type = string
default = null
}
source "example" "foo" {
arg = var.example
}
```
In the above case, as long as "arg" is optional for an "example" source, there is no error and arg wont be set.
`@include 'from-1.5/variables/must-be-set.mdx'`
### Setting an unknown variable will not always fail:

@ -5,10 +5,6 @@
- [packer-builder-arm-image](https://github.com/solo-io/packer-builder-arm-image) - simple builder lets you extend on existing system images.
- [packer-builder-arm](https://github.com/mkaczanowski/packer-builder-arm) - flexible builder lets you extend or build images from scratch with variety of options (ie. custom partition table).
- [vSphere builder](https://github.com/jetbrains-infra/packer-builder-vsphere) -
A builder for interacting directly with the vSphere API rather than the esx
host directly.
- [Vultr builder](https://github.com/vultr/packer-builder-vultr) - A builder
for creating [Vultr](https://www.vultr.com/) snapshots.

@ -0,0 +1,5 @@
-> **Note:** This page is about HCL2 in Packer 1.5 and later. HCL2 support for
Packer is still in Beta. Please see the [Packer Issue
Tracker](https://github.com/hashicorp/packer/issues/9176) for a list of
supported features. For the old-style stable configuration language see
[template docs](/docs/templates).

@ -0,0 +1,28 @@
```hcl
# build.pkr.hcl
build {
sources = [
# use the plural `sources` block to simply use sources
# without changing any field.
"source.amazon-ebs.example",
]
source "source.amazon-ebs.example" {
# Use the singular `source` block set
# specific fields.
# Note that fields cannot be overwritten, in other words, you cannot
# set the 'output' field from the top-level source block and here.
output = "different value"
name = var.foo
}
provisioner "shell-local" {
inline = ["echo Hello World"]
}
post-processor "shell-local" {
inline = ["echo Hello World"]
}
}
```

@ -0,0 +1,9 @@
```hcl
# locals.pkr.hcl
locals {
# locals can be bare values like:
wee = local.baz
# locals can also be set with input variables :
baz = "Foo is '${var.foo}'"
}
```

@ -0,0 +1,6 @@
```hcl
# sources.pkr.hcl
source "amazon-ebs" "example" {
// ...
}
```

@ -0,0 +1,8 @@
## Assigning Values to build Variables
Once a variable is declared in your configuration, you can set it:
- Individually, with the `-var foo=bar` command line option.
- In variable definitions (`.pkrvars.hcl`) files, either specified on the
command line or automatically loaded.
- As environment variables, for example: `PKR_VAR_foo=bar`

@ -0,0 +1,8 @@
```hcl
# variables.pkr.hcl
variable "foo" {
type = string
default = "the default value of the `foo` variable"
description = "description of the `foo` variable"
}
```

@ -0,0 +1,4 @@
```hcl
# foo.pkrvars.hcl
foo = "value"
```

@ -0,0 +1,34 @@
## A variable value must be known:
Take the following variable for example:
```hcl
variable "foo" {
type = string
```
Here `foo` must have a known value but you can default it to `null` to make
this behavior optional :
| | no default | `default = null` | `default = "xy"` |
| :---------------------------: | :--------------------------: | :--------------: | :--------------: |
| foo unused | error, "foo needs to be set" | - | - |
| var.foo | error, "foo needs to be set" | null¹ | xy |
| `PKR_VAR_foo=yz`<br />var.foo | yz | yz | yz |
| `-var foo=yz`<br />var.foo | yz | yz | yz |
1: Null is a valid value. Packer will only error when the receiving field needs
a value, example:
```hcl
variable "example" {
type = string
default = null
}
source "example" "foo" {
arg = var.example
}
```
In the above case, as long as "arg" is optional for an "example" source, there is no error and arg wont be set.
Loading…
Cancel
Save