github.com/hashicorp/packer@v1.14.3/website/content/guides/hcl/variables.mdx (about) 1 --- 2 page_title: Input and Local Variables guide 3 description: |- 4 This page introduces input variables and local variables as a way to 5 parameterize a configuration. 6 --- 7 8 # Input Variables and local variables 9 10 @include 'guides/hcl2-beta-note.mdx' 11 12 This page introduces input variables and local variables as a way to 13 parameterize a configuration. Once defined, input variables are settable from a 14 default value, environment, special var files, and command line arguments. 15 Local variables can be a compound of input variables and local variables. 16 17 ## Defining Variables and locals 18 19 In the legacy JSON Packer templates, any variables we hadn't already defined in 20 the "variables" stanza of our json template could simply be passed in via the 21 command line or a `var-file`; if a variable was never defined it would generally 22 be interpolated to an empty string. 23 24 _In the HCL2 Packer templates, we must always pre-define our variables in the 25 HCL equivalent of the "variables" stanza._ 26 27 Another difference between JSON and HCL Packer templates is that in JSON packer 28 templates, the "variables" stanza, if used, was always in the same .json file 29 as the builds and builders. In HCL, it can exist in its own file if you want it 30 to. 31 32 To demonstrate, let's create a file `variables.pkr.hcl` with the following 33 contents. 34 35 -> **Note**: that the file can be named anything, since Packer loads all 36 files ending in `.pkr.hcl` in a directory. If you split your configuration 37 across multiple files, use 38 `packer build <command line flags> <source directory>` to initiate a build. 39 40 ```hcl 41 // variables.pkr.hcl 42 43 // For those variables that you don't provide a default for, you must 44 // set them from the command line, a var-file, or the environment. 45 46 variable "weekday" {} 47 48 variable "sudo_password" { 49 type = string 50 default = "mypassword" 51 // Sensitive vars are hidden from output as of Packer v1.6.5 52 sensitive = true 53 } 54 55 variable "flavor" { 56 type = string 57 default = "strawberry" 58 } 59 60 variable "exit_codes" { 61 type = list(number) 62 default = [0] 63 } 64 65 locals { 66 ice_cream_flavor = "${var.flavor}-ice-cream" 67 foo = "bar" 68 } 69 ``` 70 71 This defines several variables within your Packer configuration, each showing 72 off a different way to set them. The first variable, "weekday", is an empty 73 block `{}`, without a type or a default. 74 75 However, it's generally best to provide the type in your variable definition, 76 as you can see in variable "flavor", which we have given a type of "string", 77 and variable "exit_codes", which we have given a type of "list(number)", 78 meaning it is a list/array of numbers. 79 80 When a variable is passed from the cli or environment and the variable's type 81 is not set, Packer will expect it to be a string. But if it is passed from a 82 var-file where Packer can interpret HCL properly it can be a slice or any 83 supported type. 84 85 In addition to setting the type, the "flavor" and "exit_codes" variables also 86 provide a default. If you set a default value, then you don't need to set the 87 variable at run time. Packer will use a provided command-line var, 88 var-file, or environment var if it exists, but if not Packer will fall back to 89 this default value. 90 91 If you do not set a default value, Packer will fail immediately when you try to 92 run a `build` if you have not provided the missing variable via the 93 command-line, a var-file, or the environment. The `validate`, `inspect` and 94 `console` commands will work, but variables with unknown values will be 95 `<unknown>`. 96 97 This also defines two locals: `ice_cream_flavor` and `foo`. 98 99 -> **Note**: that it is _not_ possible to reference a variable in the 100 definition of another variable. But it _is_ possible to use locals and 101 variables in the definition of a local, as shown in the ice_cream_flavor 102 definition. 103 104 ## Using Variables and locals in Configuration 105 106 For simplicity's sake, we're going to put a null source in the same file as 107 we are putting the build configuration. This file demonstrates how to use the 108 variables we previously defined. 109 110 ```hcl 111 // null_example.pkr.hcl 112 113 source "null" "example" { 114 communicator = "none" 115 } 116 117 build { 118 sources = [ 119 "source.null.example" 120 ] 121 provisioner "shell-local" { 122 // Note that for options that are documented as template engines, 123 // we still have to use the Go template engine syntax rather than our 124 // specialized HCL2 variable syntax. This example shows a combination of 125 // an HCL2 variable and the Go template engines built into the 126 // execute_command option 127 execute_command = ["/bin/sh", "-c", "echo ${var.sudo_password}| {{.Vars}} {{.Script}}"] 128 environment_vars = ["HELLO_USER=packeruser", "UUID=${build.PackerRunUUID}"] 129 inline = ["echo the Packer run uuid is $UUID"] 130 } 131 provisioner "shell-local" { 132 inline = ["echo var.flavor is: ${var.flavor}", 133 "echo local.ice_cream_flavor is: ${local.ice_cream_flavor}"] 134 valid_exit_codes = var.exit_codes 135 } 136 } 137 ``` 138 139 As you can see in the example, you can access your variables directly by 140 giving them the `var.` or `local.` prefix. If you want to embed the variables 141 in a string, you can do so with the `${}` HCL interpolation syntax. If you are 142 using an option that is a template engine, you still need to use the Go 143 templating engine syntax `{{ .OPTION }}` for those engines. 144 145 ## Assigning Variables 146 147 There are multiple ways to assign variables. Below is also the order 148 in which variable values are chosen. The following is the descending order 149 of precedence in which variables are considered. So first defined; first used. 150 151 #### Command-line flags 152 153 You can set variables directly on the command-line with the 154 `-var` flag.: 155 156 ```shell-session 157 $ packer build \ 158 -var "weekday=Sunday" \ 159 -var "flavor=chocolate" \ 160 -var "sudo_password=hunter42" . 161 ``` 162 163 Once again, setting variables this way will not save them, and they'll 164 have to be input repeatedly as commands are executed. 165 166 If you plan to assign variables via the command line, we strongly recommend that 167 you at least set a default type instead of using empty blocks; this helps the 168 HCL parser understand what is being set. Otherwise it will interpret all of your 169 command line variables as strings. 170 171 #### From a file 172 173 To persist variable values, create a file and assign variables within 174 this file. A variable definitions file uses the same basic syntax as Packer language files, 175 but consists only of variable name assignments. 176 177 ```hcl 178 sudo_password = "partyparrot" 179 weekday = "Sunday" 180 ``` 181 182 When assigning values in a variable definitions file please make sure to quote any string values, 183 wrap list values within brackets `[...]`, and wrap maps within curly-braces `{...}`. 184 185 Given a file named `variables.pkrvars.hcl` Packer can be instructed to use the 186 variable definitions file by using the `-var-file` command line flag. 187 188 ```shell-session 189 $ packer build -var-file="variables.pkrvars.hcl" . 190 ``` 191 192 Packer will automatically load any var file that matches the name 193 `*.auto.pkrvars.hcl`, without the need to pass the file via the command line. 194 If we rename the above variable definitions file from `variables.pkrvars.hcl` to 195 `variables.auto.pkrvars.hcl`, then we can run our build simply by calling 196 197 ```shell-session 198 $ packer build . 199 ``` 200 201 You may provide as many -var-file flags as you would like: 202 203 ```shell-session 204 $ packer build \ 205 -var-file="secret.pkrvars.hcl" \ 206 -var-file="production.pkrvars.hcl" . 207 ``` 208 209 These files can also be JSON: 210 211 variables.json: 212 213 ```json 214 { 215 "weekday": "sunday", 216 "flavor": "mint" 217 } 218 ``` 219 220 ```shell-session 221 $ packer build -var-file=variables.json 222 ``` 223 224 We don't recommend saving sensitive information to version control, but you 225 can create a local secret variables file and use `-var-file` to load it. 226 227 You can use multiple `-var-file` arguments in a single command, with some 228 checked in to version control and others not checked in. For example: 229 230 ```shell-session 231 $ packer build \ 232 -var-file="secret.pkrvars.hcl" \ 233 -var-file="production.pkrvars.hcl" . 234 ``` 235 236 #### From environment variables 237 238 Packer will read environment variables in the form of `PKR_VAR_name` to find 239 the value for a variable. For example, the `PKR_VAR_access_key` variable can be 240 set to set the `access_key` variable. 241 242 ```shell-session 243 $ export PKR_VAR_weekday=Monday 244 $ packer build . 245 ``` 246 247 #### Variable Defaults 248 249 If no value is assigned to a variable via any of these methods and the 250 variable has a `default` key in its declaration, that value will be used 251 for the variable. 252 253 If all of your variables have defaults, then you can call a packer build using: 254 255 ```shell-session 256 $ packer build . 257 ``` 258 259 You can make this work for yourself using the variable example file above by 260 commenting out or removing the "weekday" variable declaration, since it is not 261 actually used in the example build. 262 263 If your variable definitions are stored in the same file as your source and 264 build, you can call the build against that specific file: 265 266 ```shell-session 267 $ packer build self_contained_example.pkr.hcl 268 ``` 269 270 #### Unspecified Values Fail 271 272 If you call `packer build` with any variables defined but not set, Packer will 273 error. 274 275 ## Variable Type Reference 276 277 ### Lists 278 279 Lists are defined either explicitly or implicitly 280 281 ```hcl 282 # implicitly by using brackets [...] 283 variable "cidrs" { default = [] } 284 285 # explicitly 286 variable "cidrs" { type = list } 287 ``` 288 289 You can specify lists in a `variables.pkrvars.hcl` file: 290 291 ```hcl 292 cidrs = [ "10.0.0.0/16", "10.1.0.0/16" ] 293 ``` 294 295 ### Maps 296 297 Maps are a way to create variables that are lookup tables. An example 298 will show this best. Let's extract our AMIs into a map and add 299 support for the `us-west-2` region as well: 300 301 ```hcl 302 variable "amis" { 303 type = map(string) 304 default = { 305 "us-east-1" = "ami-b374d5a5" 306 "us-west-2" = "ami-4b32be2b" 307 } 308 } 309 ``` 310 311 A variable can have a `map` type assigned explicitly, or it can be implicitly 312 declared as a map by specifying a default value that is a map. The above 313 demonstrates both. 314 315 Then we can `lookup` in maps like in the following: 316 317 ```hcl 318 source "amazon-ebs" "example" { 319 source_ami = "${lookup(var.amis, var.region)}" 320 instance_type = "t2.micro" 321 } 322 ``` 323 324 This introduces a new type of interpolation: a function call. The 325 `lookup` function does a dynamic lookup in a map for a key. The 326 key is `var.region`, which specifies that the value of the region 327 variables is the key. 328 329 You can also do a static lookup of a map directly with 330 `${var.amis["us-east-1"]}`. 331 332 ## Assigning Maps 333 334 We set defaults above, but maps can also be set using the `-var` and 335 `-var-file` values. For example: 336 337 ```shell-session 338 $ packer build -var 'amis={ us-east-1 = "foo", us-west-2 = "bar" }' 339 # ... 340 ``` 341 342 Here is an example of setting a map's keys from a file. Starting with these 343 variable definitions: 344 345 ```hcl 346 variable "region" {} 347 variable "amis" { 348 type = map 349 } 350 ``` 351 352 You can specify keys in a `variables.pkrvars.hcl` file: 353 354 ```hcl 355 amis = { 356 "us-east-1" = "ami-abc123" 357 "us-west-2" = "ami-def456" 358 } 359 ``` 360 361 And access them via `lookup()`: 362 363 ```hcl 364 output "ami" { 365 value = "${lookup(var.amis, var.region)}" 366 } 367 ``` 368 369 Like so: 370 371 ```shell-session 372 $ packer build -var region=us-west-2 373 ```