mirror of
https://github.com/hashicorp/packer.git
synced 2026-02-25 10:59:43 -05:00
Merge pull request #10097 from hashicorp/more_hcl_docs
Update HCL docs with a local resource-free example to empower users t…
This commit is contained in:
commit
2cdc052d7c
5 changed files with 181 additions and 117 deletions
|
|
@ -390,7 +390,7 @@ Options:
|
|||
-parallel-builds=1 Number of builds to run in parallel. 1 disables parallelization. 0 means no limit (Default: 0)
|
||||
-timestamp-ui Enable prefixing of each ui output with an RFC3339 timestamp.
|
||||
-var 'key=value' Variable for templates, can be used multiple times.
|
||||
-var-file=path JSON file containing user variables.
|
||||
-var-file=path JSON or HCL2 file containing user variables.
|
||||
`
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ Usage: packer console [options] [TEMPLATE]
|
|||
|
||||
Options:
|
||||
-var 'key=value' Variable for templates, can be used multiple times.
|
||||
-var-file=path JSON file containing user variables. [ Note that even in HCL mode this expects file to contain JSON, a fix is comming soon ]
|
||||
-var-file=path JSON or HCL2 file containing user variables. [ Note that even in HCL mode this expects file to contain JSON, a fix is comming soon ]
|
||||
`
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ Options:
|
|||
-except=foo,bar,baz Validate all builds other than these.
|
||||
-only=foo,bar,baz Validate only these builds.
|
||||
-var 'key=value' Variable for templates, can be used multiple times.
|
||||
-var-file=path JSON file containing user variables. [ Note that even in HCL mode this expects file to contain JSON, a fix is comming soon ]
|
||||
-var-file=path JSON or HCL2 file containing user variables. [ Note that even in HCL mode this expects file to contain JSON, a fix is comming soon ]
|
||||
`
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ _packer () {
|
|||
'-parallel=[(false) Disable parallelization. (Default: false)]'
|
||||
'-parallel-builds=[(0) Number of builds to run in parallel. (Defaults to infinite: 0)]'
|
||||
'-var[("key=value") Variable for templates, can be used multiple times.]'
|
||||
'-var-file=[(path) JSON file containing user variables.]'
|
||||
'-var-file=[(path) JSON or HCL2 file containing user variables.]'
|
||||
'(-)*:files:_files -g "*.json"'
|
||||
)
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ _packer () {
|
|||
'-except=[(foo,bar,baz) Validate all builds other than these.]'
|
||||
'-only=[(foo,bar,baz) Validate only these builds.]'
|
||||
'-var[("key=value") Variable for templates, can be used multiple times.]'
|
||||
'-var-file=[(path) JSON file containing user variables.]'
|
||||
'-var-file=[(path) JSON or HCL2 file containing user variables.]'
|
||||
'(-)*:files:_files -g "*.json"'
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,54 +18,131 @@ Local variables can be a compound of input variables and local variables.
|
|||
|
||||
## Defining Variables and locals
|
||||
|
||||
Let's create a file `variables.pkr.hcl` with the following contents.
|
||||
In the legacy JSON packer templates, any variables we hadn't already defined in
|
||||
the "variables" stanza of our json template could simply be passed in via the
|
||||
command line or a var-file; if a variable was never defined it would generally
|
||||
be interpolated to an empty string.
|
||||
|
||||
*In the HCL2 packer templates, we must always pre-define our variables in the
|
||||
HCL equivalent of the "variables" stanza.*
|
||||
|
||||
Another difference between JSON and HCL packer templates is that in JSON packer
|
||||
templates, the "variables" stanza, if used, was always in the same .json file
|
||||
as the builds and builders. In HCL, it can exist in its own file if you want it
|
||||
to.
|
||||
|
||||
To demonstrate, let's create a file `variables.pkr.hcl` with the following
|
||||
contents.
|
||||
|
||||
-> **Note**: that the file can be named anything, since Packer loads all
|
||||
files ending in `.pkr.hcl` in a directory. If you split your configuration
|
||||
across multiple files, use `packer build <source directory>` to initiate
|
||||
a build.
|
||||
across multiple files, use
|
||||
`packer build <command line flags> <source directory>` to initiate a build.
|
||||
|
||||
```hcl
|
||||
# variables.pkr.hcl
|
||||
// variables.pkr.hcl
|
||||
|
||||
variable "access_key" {}
|
||||
variable "secret_key" {}
|
||||
variable "region" {
|
||||
default = "us-east-1"
|
||||
// For those variables that you don't provide a default for, you must
|
||||
// set them from the command line, a var-file, or the environment.
|
||||
|
||||
variable "weekday" {}
|
||||
|
||||
variable "sudo_password" {
|
||||
type = string
|
||||
default = "mypassword"
|
||||
// Sensitive vars are hidden from output as of Packer v1.6.5
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "flavor" {
|
||||
type = string
|
||||
default = "strawberry"
|
||||
}
|
||||
|
||||
variable "exit_codes" {
|
||||
type = list(number)
|
||||
default = [0]
|
||||
}
|
||||
|
||||
locals {
|
||||
debian_ami_name = "${var.image_id}-debian"
|
||||
ice_cream_flavor = "${var.flavor}-ice-cream"
|
||||
foo = "bar"
|
||||
}
|
||||
```
|
||||
|
||||
This defines three variables within your Packer configuration. The first
|
||||
two have empty blocks `{}`. The third sets a default. If a default value is
|
||||
set, the variable is optional. Otherwise, the variable is required.
|
||||
This also defines two locals: `debian_ami_name` and `foo`.
|
||||
This defines several variables within your Packer configuration, each showing
|
||||
off a different way to set them. The first variable, "weekday", is an empty
|
||||
block `{}`, without a type or a default.
|
||||
|
||||
-> **Note**: that it is _not_ possible to use variables in a variable definition
|
||||
but it _is_ possible to use locals and variables in a local definition.
|
||||
However, it's generally best to provide the type in your variable definition,
|
||||
as you can see in variable "flavor", which we have given a type of "string",
|
||||
and variable "exit_codes", which we have given a type of "list(number)",
|
||||
meaning it is a list/array of numbers.
|
||||
|
||||
When a variable is passed from the cli or environment and the variable's type
|
||||
is not set, Packer will expect it to be a string. But if it is passed from a
|
||||
var-file where Packer can interpret HCL properly it can be a slice or any
|
||||
supported type.
|
||||
|
||||
In addition to setting the type, the "flavor" and "exit_codes" variables also
|
||||
provide a default. If you set a default value, then you don't need to set the
|
||||
variable at run time. Packer will use a provided command-line var,
|
||||
var-file, or environment var if it exists, but if not Packer will fall back to
|
||||
this default value.
|
||||
|
||||
If you do not set a default value, Packer will fail immediately when you try to
|
||||
run a `build` if you have not provided the missing variable via the
|
||||
command-line, a var-file, or the environment. The `validate`, `inspect` and
|
||||
`console` commands will work, but variables with unknown values will be
|
||||
`<unknown>`.
|
||||
|
||||
This also defines two locals: `ice_cream_flavor` and `foo`.
|
||||
|
||||
-> **Note**: that it is _not_ possible to reference a variable in the
|
||||
definition of another variable. But it _is_ possible to use locals and
|
||||
variables in the definition of a local, as shown in the ice_cream_flavor
|
||||
definition.
|
||||
|
||||
## Using Variables and locals in Configuration
|
||||
|
||||
Next, you can define a source using the variables :
|
||||
For simplicity's sake, we're going to put a null source in the same file as
|
||||
we are putting the build configuration. This file demonstrates how to use the
|
||||
variables we previously defined.
|
||||
|
||||
```hcl
|
||||
# source.pkr.hcl
|
||||
// null_example.pkr.hcl
|
||||
|
||||
source "amazon-ebs" "debian" {
|
||||
ami_name = local.debian_ami_name
|
||||
access_key = var.aws_access_key
|
||||
secret_key = "${var.aws_secret_key}"
|
||||
region = "${var.aws_region}"
|
||||
source "null" "example" {
|
||||
communicator = "none"
|
||||
}
|
||||
|
||||
build {
|
||||
sources = [
|
||||
"source.null.example"
|
||||
]
|
||||
provisioner "shell-local" {
|
||||
// Note that for options that are documented as template engines,
|
||||
// we still have to use the golang template engine syntax rather than our
|
||||
// specialized HCL2 variable syntax. This example shows a combination of
|
||||
// an HCL2 variable and the golang template engines built into the
|
||||
// execute_command option
|
||||
execute_command = ["/bin/sh", "-c", "echo ${var.sudo_password}| {{.Vars}} {{.Script}}"]
|
||||
environment_vars = ["HELLO_USER=packeruser", "UUID=${build.PackerRunUUID}"]
|
||||
inline = ["echo the Packer run uuid is $UUID"]
|
||||
}
|
||||
provisioner "shell-local" {
|
||||
inline = ["echo var.flavor is: ${var.flavor}",
|
||||
"echo local.ice_cream_flavor is: ${local.ice_cream_flavor}"]
|
||||
valid_exit_codes = var.exit_codes
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This uses more interpolations, this time prefixed with `var.` and `local.`.
|
||||
This tells Packer that you're accessing variables. This configures the builder
|
||||
with the given variables.
|
||||
As you can see in the example, you can access your variables directly by
|
||||
giving them the `var.` or `local.` prefix. If you want to embed the variables
|
||||
in a string, you can do so with the `${}` HCL interpolation syntax. If you are
|
||||
using an option that is a template engine, you still need to use the golang
|
||||
templating engine syntax `{{ .OPTION }}` for those engines.
|
||||
|
||||
## Assigning Variables
|
||||
|
||||
|
|
@ -80,86 +157,18 @@ You can set variables directly on the command-line with the
|
|||
|
||||
```shell-session
|
||||
$ packer build \
|
||||
-var 'access_key=foo' \
|
||||
-var 'secret_key=bar'
|
||||
# ...
|
||||
-var 'weekday=Sunday' \
|
||||
-var 'flavor=chocolate' \
|
||||
-var 'sudo_password=hunter42' .
|
||||
```
|
||||
|
||||
Once again, setting variables this way will not save them, and they'll
|
||||
have to be input repeatedly as commands are executed.
|
||||
|
||||
|
||||
If you plan to assign variables via the command line, we strongly recommend that
|
||||
you at least set a default type instead of using empty blocks; this helps the
|
||||
HCL parser understand what is being set.
|
||||
|
||||
For example:
|
||||
|
||||
```hcl
|
||||
variable "pizza" {
|
||||
type = string
|
||||
}
|
||||
|
||||
source "null" "example" {
|
||||
communicator = "none"
|
||||
}
|
||||
|
||||
build {
|
||||
sources = [
|
||||
"source.null.example"
|
||||
]
|
||||
provisioner "shell-local" {
|
||||
inline = ["echo $PIZZA"]
|
||||
environment_vars = ["PIZZA=${var.pizza}"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you call the above template using the command
|
||||
|
||||
```sh
|
||||
packer build -var pizza=pineapple shell_local_variables.pkr.hcl
|
||||
```
|
||||
|
||||
then the Packer build will run successfully. However, if you define the variable
|
||||
using an empty block, the parser will not know what type the variable is, and it
|
||||
cannot infer the type from the command line, as shown in this example:
|
||||
|
||||
```hcl
|
||||
variable "pizza" {}
|
||||
|
||||
source "null" "example" {
|
||||
communicator = "none"
|
||||
}
|
||||
|
||||
build {
|
||||
sources = [
|
||||
"source.null.example"
|
||||
]
|
||||
provisioner "shell-local" {
|
||||
inline = ["echo $PIZZA"]
|
||||
environment_vars = ["PIZZA=${var.pizza}"]
|
||||
}
|
||||
}
|
||||
```
|
||||
The above template will result in the error:
|
||||
|
||||
```
|
||||
Error: Variables not allowed
|
||||
|
||||
on <value for var.pizza from arguments> line 1:
|
||||
(source code not available)
|
||||
|
||||
Variables may not be used here.
|
||||
```
|
||||
|
||||
You can work around this either by quoting the variable on the command line, or
|
||||
by adding the type to the variable block as shown in the previous example.
|
||||
Setting the expected type is the more resilient option.
|
||||
|
||||
```sh
|
||||
packer build -var 'pizza="pineapple"' shell_local_variables.pkr.hcl
|
||||
```
|
||||
HCL parser understand what is being set. Otherwise it will interpret all of your
|
||||
command line variables as strings.
|
||||
|
||||
#### From a file
|
||||
|
||||
|
|
@ -168,17 +177,48 @@ this file. Create a file named `variables.pkrvars.hcl` with the following
|
|||
contents:
|
||||
|
||||
```hcl
|
||||
access_key = "foo"
|
||||
secret_key = "bar"
|
||||
sudo_password = "partyparrot"
|
||||
weekday = "Sunday"
|
||||
```
|
||||
|
||||
For all files which match `*.auto.pkrvars.hcl` present in the current
|
||||
directory, Packer automatically loads them to populate variables. If the file
|
||||
is named something else, you can use the `-var-file` flag directly to specify a
|
||||
file. These files are the same syntax as Packer configuration files. And like
|
||||
Packer configuration files, these files can also be JSON.
|
||||
You tell Packer to use this var file using the `-var-file` command line flag.
|
||||
|
||||
We don't recommend saving usernames and password to version control, but you
|
||||
```shell-session
|
||||
$ packer build -var-file="variables.pkrvars.hcl" .
|
||||
```
|
||||
|
||||
Packer will automatically load any var file that matches the name
|
||||
`*.auto.pkrvars.hcl`, without the need to pass the file via the command line.
|
||||
if we rename the above var-file from variables.pkrvars.hcl to
|
||||
variables.auto.pkrvars.hcl, then we can run our build simply by calling
|
||||
|
||||
```shell-session
|
||||
$ packer build .
|
||||
```
|
||||
|
||||
You may provide as many -var-file flags as you would like:
|
||||
|
||||
```shell-session
|
||||
$ packer build \
|
||||
-var-file="secret.pkrvars.hcl" \
|
||||
-var-file="production.pkrvars.hcl" .
|
||||
```
|
||||
|
||||
These files can also be JSON:
|
||||
|
||||
variables.json:
|
||||
```json
|
||||
{
|
||||
"weekday": "sunday",
|
||||
"flavor": "mint"
|
||||
}
|
||||
```
|
||||
|
||||
```shell-session
|
||||
$ packer build -var-file=variables.json
|
||||
```
|
||||
|
||||
We don't recommend saving sensitive information to version control, but you
|
||||
can create a local secret variables file and use `-var-file` to load it.
|
||||
|
||||
You can use multiple `-var-file` arguments in a single command, with some
|
||||
|
|
@ -187,7 +227,7 @@ checked in to version control and others not checked in. For example:
|
|||
```shell-session
|
||||
$ packer build \
|
||||
-var-file="secret.pkrvars.hcl" \
|
||||
-var-file="production.pkrvars.hcl"
|
||||
-var-file="production.pkrvars.hcl" .
|
||||
```
|
||||
|
||||
#### From environment variables
|
||||
|
|
@ -196,18 +236,42 @@ Packer will read environment variables in the form of `PKR_VAR_name` to find
|
|||
the value for a variable. For example, the `PKR_VAR_access_key` variable can be
|
||||
set to set the `access_key` variable.
|
||||
|
||||
```shell-session
|
||||
$ export PKR_VAR_weekday=Monday
|
||||
$ packer build .
|
||||
```
|
||||
|
||||
#### Variable Defaults
|
||||
|
||||
If no value is assigned to a variable via any of these methods and the
|
||||
variable has a `default` key in its declaration, that value will be used
|
||||
for the variable.
|
||||
|
||||
#### Unspecified values fails
|
||||
If all of your variables have defaults, then you can call a packer build using:
|
||||
|
||||
If you execute `packer build` with certain variables unspecified and those are
|
||||
used somewhere, Packer will error.
|
||||
```shell-session
|
||||
$ packer build .
|
||||
```
|
||||
|
||||
## Lists
|
||||
You can make this work for yourself using the variable example file above by
|
||||
commenting out or removing the "weekday" variable declaration, since it is not
|
||||
actually used in the example build.
|
||||
|
||||
If your variable definitions are stored in the same file as your source and
|
||||
build, you can call the build against that specific file:
|
||||
|
||||
```shell-session
|
||||
$ packer build self_contained_example.pkr.hcl
|
||||
```
|
||||
|
||||
#### Unspecified Values Fail
|
||||
|
||||
If you call `packer build` with any variables defined but not set, Packer will
|
||||
error.
|
||||
|
||||
## Variable Type Reference
|
||||
|
||||
### Lists
|
||||
|
||||
Lists are defined either explicitly or implicitly
|
||||
|
||||
|
|
@ -225,7 +289,7 @@ You can specify lists in a `variables.pkrvars.hcl` file:
|
|||
cidrs = [ "10.0.0.0/16", "10.1.0.0/16" ]
|
||||
```
|
||||
|
||||
## Maps
|
||||
### Maps
|
||||
|
||||
Maps are a way to create variables that are lookup tables. An example
|
||||
will show this best. Let's extract our AMIs into a map and add
|
||||
|
|
|
|||
Loading…
Reference in a new issue