github.com/raghuse92/packer@v1.3.2/website/source/docs/templates/user-variables.html.md (about) 1 --- 2 description: | 3 User variables allow your templates to be further configured with variables 4 from the command-line, environment variables, or files. This lets you 5 parameterize your templates so that you can keep secret tokens, 6 environment-specific data, and other types of information out of your 7 templates. This maximizes the portability and shareability of the template. 8 layout: docs 9 page_title: 'User Variables - Templates' 10 sidebar_current: 'docs-templates-user-variables' 11 --- 12 13 # Template User Variables 14 15 User variables allow your templates to be further configured with variables from 16 the command-line, environment variables, Vault, or files. This lets you parameterize 17 your templates so that you can keep secret tokens, environment-specific data, 18 and other types of information out of your templates. This maximizes the 19 portability of the template. 20 21 Using user variables expects you to know how [configuration 22 templates](/docs/templates/engine.html) work. If you don't know 23 how configuration templates work yet, please read that page first. 24 25 ## Usage 26 27 User variables must first be defined in a `variables` section within 28 your template. Even if you want a user variable to default to an empty 29 string, it must be defined. This explicitness helps reduce the time it 30 takes for newcomers to understand what can be modified using variables 31 in your template. 32 33 The `variables` section is a key/value mapping of the user variable name 34 to a default value. A default value can be the empty string. An example 35 is shown below: 36 37 ``` json 38 { 39 "variables": { 40 "aws_access_key": "", 41 "aws_secret_key": "" 42 }, 43 44 "builders": [{ 45 "type": "amazon-ebs", 46 "access_key": "{{user `aws_access_key`}}", 47 "secret_key": "{{user `aws_secret_key`}}", 48 // ... 49 }] 50 } 51 ``` 52 53 In the above example, the template defines two user variables: 54 `aws_access_key` and `aws_secret_key`. They default to empty values. 55 Later, the variables are used within the builder we defined in order to 56 configure the actual keys for the Amazon builder. 57 58 If the default value is `null`, then the user variable will be 59 *required*. This means that the user must specify a value for this 60 variable or template validation will fail. 61 62 User variables are used by calling the `{{user}}` function in the form of 63 <code>{{user \`variable\`}}</code>. This function can be used in *any value* 64 but `type` within the template: in builders, provisioners, *anywhere outside 65 the `variables` section*. User variables are available globally within the rest 66 of the template. 67 68 ## Environment Variables 69 70 Environment variables can be used within your template using user variables. 71 The `env` function is available *only* within the default value of a user 72 variable, allowing you to default a user variable to an environment variable. 73 An example is shown below: 74 75 ```json 76 { 77 "variables": { 78 "my_secret": "{{env `MY_SECRET`}}", 79 } 80 } 81 ``` 82 83 This will default "my\_secret" to be the value of the "MY\_SECRET" environment 84 variable (or an empty string if it does not exist). 85 86 -> **Why can't I use environment variables elsewhere?** User variables are 87 the single source of configurable input to a template. We felt that having 88 environment variables used *anywhere* in a template would confuse the user 89 about the possible inputs to a template. By allowing environment variables 90 only within default values for user variables, user variables remain as the 91 single source of input to a template that a user can easily discover using 92 `packer inspect`. 93 94 -> **Why can't I use `~` for home variable?** `~` is an special variable 95 that is evaluated by shell during a variable expansion. As Packer doesn't run 96 inside a shell, it won't expand `~`. 97 98 ## Consul keys 99 100 Consul keys can be used within your template using the `consul_key` function. 101 This function is available *only* within the default value of a user variable, 102 for reasons similar to environment variables above. 103 104 ```json 105 { 106 "variables": { 107 "soft_versions": "{{ consul_key `my_image/softs_versions/next` }}" 108 } 109 } 110 ``` 111 112 This will default `soft_versions` to the value of the key `my_image/softs_versions/next` 113 in consul. 114 115 The configuration for consul (address, tokens, ...) must be specified as environment variables, 116 as specified in the [Documentation](https://www.consul.io/docs/commands/index.html#environment-variables). 117 118 ## Vault Variables 119 120 Secrets can be read from [Vault](https://www.vaultproject.io/) and used within 121 your template as user variables. the `vault` function is available *only* 122 within the default value of a user variable, allowing you to default a user 123 variable to an environment variable. 124 125 An example of using a v2 kv engine: 126 127 If you store a value in vault using `vault kv put secret/hello foo=world`, you 128 can access it using the following template engine: 129 130 ```json 131 { 132 "variables": { 133 "my_secret": "{{ vault `/secret/data/hello` `foo`}}" 134 } 135 } 136 ``` 137 which will assign "my_secret": "world" 138 139 An example of using a v1 kv engine: 140 141 If you store a value in vault using: 142 143 ``` 144 vault secrets enable -version=1 -path=secrets kv 145 vault kv put secrets/hello foo=world 146 ``` 147 148 You can access it using the following template engine: 149 150 ``` 151 { 152 "variables": { 153 "VAULT_SECRETY_SECRET": "{{ vault `secrets/hello` `foo`}}" 154 } 155 } 156 ``` 157 158 This example accesses the Vault path 159 `secret/data/foo` and returns the value stored at the key `bar`, storing it as 160 "my_secret". 161 162 In order for this to work, you must set the environment variables `VAULT_TOKEN` 163 and `VAULT_ADDR` to valid values. 164 165 ## Using array values 166 167 Some templates call for array values. You can use template variables for these, 168 too. For example, the `amazon-ebs` builder has a configuration parameter called 169 `ami_regions`, which takes an array of regions that it will copy the AMI to. 170 You can parameterize this by using a variable that is a list of regions, joined 171 by a `,`. For example: 172 173 ```json 174 { 175 "variables": { 176 "destination_regions": "us-west-1,us-west-2" 177 }, 178 "builders": [ 179 { 180 "ami_name": "packer-qs-{{timestamp}}", 181 "instance_type": "t2.micro", 182 "region": "us-east-1", 183 "source_ami_filter": { 184 "filters": { 185 "name": "*ubuntu-xenial-16.04-amd64-server-*", 186 "root-device-type": "ebs", 187 "virtualization-type": "hvm" 188 }, 189 "most_recent": true, 190 "owners": [ 191 "099720109477" 192 ] 193 }, 194 "ami_regions": "{{user `destination_regions`}}", 195 "ssh_username": "ubuntu", 196 "type": "amazon-ebs" 197 } 198 ] 199 } 200 ``` 201 202 ## Setting Variables 203 204 Now that we covered how to define and use user variables within a 205 template, the next important point is how to actually set these 206 variables. Packer exposes two methods for setting user variables: from 207 the command line or from a file. 208 209 ### From the Command Line 210 211 To set user variables from the command line, the `-var` flag is used as 212 a parameter to `packer build` (and some other commands). Continuing our 213 example above, we could build our template using the command below. The 214 command is split across multiple lines for readability, but can of 215 course be a single line. 216 217 ``` text 218 $ packer build \ 219 -var 'aws_access_key=foo' \ 220 -var 'aws_secret_key=bar' \ 221 template.json 222 ``` 223 224 As you can see, the `-var` flag can be specified multiple times in order to set 225 multiple variables. Also, variables set later on the command-line override 226 any earlier set variable of the same name. 227 228 **warning** 229 If you are calling Packer from cmd.exe, you should double-quote your variables 230 rather than single-quoting them. For example: 231 232 `packer build -var "aws_secret_key=foo" template.json` 233 234 ### From a File 235 236 Variables can also be set from an external JSON file. The `-var-file` flag reads 237 a file containing a key/value mapping of variables to values and sets 238 those variables. An example JSON file may look like this: 239 240 ``` json 241 { 242 "aws_access_key": "foo", 243 "aws_secret_key": "bar" 244 } 245 ``` 246 247 It is a single JSON object where the keys are variables and the values are the 248 variable values. Assuming this file is in `variables.json`, we can build our 249 template using the following command: 250 251 ``` text 252 On Linux : 253 $ packer build -var-file=variables.json template.json 254 On Windows : 255 packer build -var-file variables.json template.json 256 ``` 257 258 The `-var-file` flag can be specified multiple times and variables from multiple 259 files will be read and applied. As you'd expect, variables read from files 260 specified later override a variable set earlier. 261 262 Combining the `-var` and `-var-file` flags together also works how you'd 263 expect. Variables set later in the command override variables set 264 earlier. So, for example, in the following command with the above 265 `variables.json` file: 266 267 ``` text 268 $ packer build \ 269 -var 'aws_access_key=bar' \ 270 -var-file=variables.json \ 271 -var 'aws_secret_key=baz' \ 272 template.json 273 ``` 274 275 Results in the following variables: 276 277 | Variable | Value | 278 |------------------|-------| 279 | aws\_access\_key | foo | 280 | aws\_secret\_key | baz | 281 282 # Sensitive Variables 283 284 If you use the environment to set a variable that is sensitive, you probably 285 don't want that variable printed to the Packer logs. You can make sure that 286 sensitive variables won't get printed to the logs by adding them to the 287 "sensitive-variables" list within the Packer template: 288 289 ``` json 290 { 291 "variables": { 292 "my_secret": "{{env `MY_SECRET`}}", 293 "not_a_secret": "plaintext", 294 "foo": "bar" 295 }, 296 297 "sensitive-variables": ["my_secret", "foo"], 298 ... 299 } 300 ``` 301 302 The above snippet of code will function exactly the same as if you did not set 303 "sensitive-variables", except that the Packer UI and logs will replace all 304 instances of "bar" and of whatever the value of "my_secret" is with 305 `<sensitive>`. This allows you to be confident that you are not printing 306 secrets in plaintext to our logs by accident. 307 308 # Recipes 309 310 ## Making a provisioner step conditional on the value of a variable 311 312 There is no specific syntax in Packer templates for making a provisioner 313 step conditional, depending on the value of a variable. However, you may 314 be able to do this by referencing the variable within a command that 315 you execute. For example, here is how to make a `shell-local` 316 provisioner only run if the `do_nexpose_scan` variable is non-empty. 317 318 ``` json 319 { 320 "type": "shell-local", 321 "command": "if [ ! -z \"{{user `do_nexpose_scan`}}\" ]; then python -u trigger_nexpose_scan.py; fi" 322 } 323 ``` 324 325 ## Using HOME Variable 326 327 In order to use `$HOME` variable, you can create a `home` variable in Packer: 328 329 ``` json 330 { 331 "variables": { 332 "home": "{{env `HOME`}}" 333 } 334 } 335 ``` 336 337 And this will be available to be used in the rest of the template, i.e.: 338 339 ``` json 340 { 341 "builders": [ 342 { 343 "type":"google", 344 "account_file": "{{ user `home` }}/.secrets/gcp-{{ user `env` }}.json" 345 } 346 ] 347 } 348 ```