github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/website/content/docs/job-specification/template.mdx (about) 1 --- 2 layout: docs 3 page_title: template Stanza - Job Specification 4 sidebar_title: template 5 description: |- 6 The "template" block instantiates an instance of a template renderer. This 7 creates a convenient way to ship configuration files that are populated from 8 environment variables, Consul data, Vault secrets, or just general 9 configurations within a Nomad task. 10 --- 11 12 # `template` Stanza 13 14 <Placement groups={['job', 'group', 'task', 'template']} /> 15 16 The `template` block instantiates an instance of a template renderer. This 17 creates a convenient way to ship configuration files that are populated from 18 environment variables, Consul data, Vault secrets, or just general 19 configurations within a Nomad task. 20 21 ```hcl 22 job "docs" { 23 group "example" { 24 task "server" { 25 template { 26 source = "local/redis.conf.tpl" 27 destination = "local/redis.conf" 28 change_mode = "signal" 29 change_signal = "SIGINT" 30 } 31 } 32 } 33 } 34 ``` 35 36 Nomad utilizes a tool called [Consul Template][ct]. Since Nomad v0.5.3, the 37 template can reference [Nomad's runtime environment variables][env]. Since Nomad 38 v0.5.6, the template can reference [Node attributes and metadata][nodevars]. For 39 a full list of the API template functions, please refer to the [Consul Template 40 README][ct]. Since Nomad v0.6.0, templates can be read as environment variables. 41 42 ## `template` Parameters 43 44 - `change_mode` `(string: "restart")` - Specifies the behavior Nomad should take 45 if the rendered template changes. Nomad will always write the new contents of 46 the template to the specified destination. The possible values below describe 47 Nomad's action after writing the template to disk. 48 49 - `"noop"` - take no action (continue running the task) 50 - `"restart"` - restart the task 51 - `"signal"` - send a configurable signal to the task 52 53 - `change_signal` `(string: "")` - Specifies the signal to send to the task as a 54 string like `"SIGUSR1"` or `"SIGINT"`. This option is required if the 55 `change_mode` is `signal`. 56 57 - `data` `(string: "")` - Specifies the raw template to execute. One of `source` 58 or `data` must be specified, but not both. This is useful for smaller 59 templates, but we recommend using `source` for larger templates. 60 61 - `destination` `(string: <required>)` - Specifies the location where the 62 resulting template should be rendered, relative to the [task working 63 directory]. Only drivers without filesystem isolation (ex. `raw_exec`) or 64 that build a chroot in the task working directory (ex. `exec`) can render 65 templates outside of the `NOMAD_ALLOC_DIR`, `NOMAD_TASK_DIR`, or 66 `NOMAD_SECRETS_DIR`. For more details on how `destination` interacts with 67 task drivers, see the [Filesystem internals] documentation. 68 69 - `env` `(bool: false)` - Specifies the template should be read back in as 70 environment variables for the task ([see below](#environment-variables)). To 71 update the environment on changes, you must set `change_mode` to 72 `restart`. Setting `env` when the `change_mode` is `signal` will return a 73 validation error. Setting `env` when the `change_mode` is `noop` is 74 permitted but will not update the environment variables in the task. 75 76 - `left_delimiter` `(string: "{{")` - Specifies the left delimiter to use in the 77 template. The default is "{{" for some templates, it may be easier to use a 78 different delimiter that does not conflict with the output file itself. 79 80 - `perms` `(string: "644")` - Specifies the rendered template's permissions. 81 File permissions are given as octal of the Unix file permissions `rwxrwxrwx`. 82 83 - `right_delimiter` `(string: "}}")` - Specifies the right delimiter to use in the 84 template. The default is "}}" for some templates, it may be easier to use a 85 different delimiter that does not conflict with the output file itself. 86 87 - `source` `(string: "")` - Specifies the path to the template to be rendered. 88 One of `source` or `data` must be specified, but not both. This source can 89 optionally be fetched using an [`artifact`][artifact] resource. This template 90 must exist on the machine prior to starting the task; it is not possible to 91 reference a template inside of a Docker container, for example. 92 93 - `splay` `(string: "5s")` - Specifies a random amount of time to wait between 94 0 ms and the given splay value before invoking the change mode. This is 95 specified using a label suffix like "30s" or "1h", and is often used to 96 prevent a thundering herd problem where all task instances restart at the same 97 time. 98 99 - `vault_grace` `(string: "15s")` - [Deprecated](https://github.com/hashicorp/consul-template/issues/1268) 100 101 ## `template` Examples 102 103 The following examples only show the `template` stanzas. Remember that the 104 `template` stanza is only valid in the placements listed above. 105 106 ### Inline Template 107 108 This example uses an inline template to render a file to disk. This file watches 109 various keys in Consul for changes: 110 111 ```hcl 112 template { 113 data = "---\nkey: {{ key \"service/my-key\" }}" 114 destination = "local/file.yml" 115 } 116 ``` 117 118 It is also possible to use heredocs for multi-line templates, like: 119 120 ```hcl 121 template { 122 data = <<EOH 123 --- 124 bind_port: {{ env "NOMAD_PORT_db" }} 125 scratch_dir: {{ env "NOMAD_TASK_DIR" }} 126 node_id: {{ env "node.unique.id" }} 127 service_key: {{ key "service/my-key" }} 128 EOH 129 130 destination = "local/file.yml" 131 } 132 ``` 133 134 ### Remote Template 135 136 This example uses an [`artifact`][artifact] stanza to download an input template 137 before passing it to the template engine: 138 139 ```hcl 140 artifact { 141 source = "https://example.com/file.yml.tpl" 142 destination = "local/file.yml.tpl" 143 } 144 145 template { 146 source = "local/file.yml.tpl" 147 destination = "local/file.yml" 148 } 149 ``` 150 151 ### Node Variables 152 153 As of Nomad v0.5.6 it is possible to access the Node's attributes and metadata. 154 155 ```hcl 156 template { 157 data = <<EOH 158 --- 159 node_dc: {{ env "node.datacenter" }} 160 node_cores: {{ env "attr.cpu.numcores" }} 161 meta_key: {{ env "meta.node_meta_key" }} 162 EOH 163 164 destination = "local/file.yml" 165 } 166 ``` 167 168 ### Environment Variables 169 170 Since v0.6.0 templates may be used to create environment variables for tasks. 171 Env templates work exactly like other templates except once the templates are 172 written, they are parsed as `KEY=value` pairs. Those key value pairs are 173 included in the task's environment. 174 175 For example the following template stanza: 176 177 ```hcl 178 template { 179 data = <<EOH 180 # Lines starting with a # are ignored 181 182 # Empty lines are also ignored 183 LOG_LEVEL="{{key "service/geo-api/log-verbosity"}}" 184 API_KEY="{{with secret "secret/geo-api-key"}}{{.Data.value}}{{end}}" 185 EOH 186 187 destination = "secrets/file.env" 188 env = true 189 } 190 ``` 191 192 The task's environment would then have environment variables like the 193 following: 194 195 ``` 196 LOG_LEVEL=DEBUG 197 API_KEY=12345678-1234-1234-1234-1234-123456789abc 198 ``` 199 200 This allows [12factor app](https://12factor.net/config) style environment 201 variable based configuration while keeping all of the familiar features and 202 semantics of Nomad templates. 203 204 Secrets or certificates may contain a wide variety of characters such as 205 newlines, quotes, and backslashes which may be difficult to quote or escape 206 properly. 207 208 Whenever a templated variable may include special characters, use the `toJSON` 209 function to ensure special characters are properly parsed by Nomad: 210 211 ``` 212 CERT_PEM={{ file "path/to/cert.pem" | toJSON }} 213 ``` 214 215 The parser will read the JSON string, so the `$CERT_PEM` environment variable 216 will be identical to the contents of the file. 217 218 Likewise when evaluating a password that may contain quotes or `#`, use the 219 `toJSON` function to ensure Nomad passes the password to task unchanged: 220 221 ``` 222 # Passwords may contain any character including special characters like: 223 # \"'# 224 # Use toJSON to ensure Nomad passes them to the environment unchanged. 225 {{ with secret "secrets/data/application/backend" }} 226 DB_PASSWD={{ .Data.data.DB_PASSWD | toJSON }} 227 {{ end }} 228 ``` 229 230 For more details see [go-envparser's README][go-envparse]. 231 232 ### Template Destinations 233 234 Templates are rendered into the task working directory. Drivers without 235 filesystem isolation (such as `raw_exec`) or drivers that build a chroot in 236 the task working directory (such as `exec`) can have templates rendered to 237 arbitrary paths in the task. But task drivers such as `docker` can only access 238 templates rendered into the `NOMAD_ALLOC_DIR`, `NOMAD_TASK_DIR`, or 239 `NOMAD_SECRETS_DIR`. To workaround this restriction, you can create a mount 240 from the template `destination` to another location in the task. 241 242 ```hcl 243 task "task" { 244 driver = "docker" 245 246 config { 247 image = "redis:6.0" 248 mount { 249 type = "bind" 250 source = "local" 251 target = "/etc/redis.d" 252 } 253 } 254 255 template { 256 destination = "local/redis.conf" 257 } 258 } 259 ``` 260 261 ## Vault Integration 262 263 ### PKI Certificate 264 265 Vault is a popular open source tool for managing secrets. In addition to acting 266 as an encrypted KV store, Vault can also generate dynamic secrets, like PKI/TLS 267 certificates. 268 269 When generating PKI certificates with Vault, the certificate, private key, and 270 any intermediate certs are all returned as part of the same API call. Most 271 software requires these files be placed in separate files on the system. 272 273 ~> **Note**: `generate_lease` must be set to `true` (non-default) on the Vault PKI 274 role.<br /><br /> Failure to do so will cause the template to frequently render a new 275 certificate, approximately every minute. This creates a significant number of 276 certificates to be expired in Vault and could ultimately lead to Vault performance 277 impacts and failures. 278 279 #### As individual files 280 281 For templates, all dependencies are mapped into a single list. This means that 282 multiple templates watching the same path return the same data. 283 284 ```hcl 285 template { 286 data = <<EOH 287 {{ with secret "pki/issue/foo" "common_name=foo.service.consul" "ip_sans=127.0.0.1" }} 288 {{- .Data.certificate -}} 289 {{ end }} 290 EOH 291 destination = "${NOMAD_SECRETS_DIR}/certificate.crt" 292 change_mode = "restart" 293 } 294 295 template { 296 data = <<EOH 297 {{ with secret "pki/issue/foo" "common_name=foo.service.consul" "ip_sans=127.0.0.1" }} 298 {{- .Data.issuing_ca -}} 299 {{ end }} 300 EOH 301 destination = "${NOMAD_SECRETS_DIR}/ca.crt" 302 change_mode = "restart" 303 } 304 305 template { 306 data = <<EOH 307 {{ with secret "pki/issue/foo" "common_name=foo.service.consul" "ip_sans=127.0.0.1" }} 308 {{- .Data.private_key -}} 309 {{ end }} 310 EOH 311 destination = "${NOMAD_SECRETS_DIR}/private_key.key" 312 change_mode = "restart" 313 } 314 ``` 315 316 These are three different input templates, but when run under the Nomad job, 317 they are compressed into a single call, sharing the resulting data. 318 319 #### As a PEM formatted file 320 321 This example acquires a PKI certificate from Vault in PEM format, concatenates 322 the elements into a bundle, and stores it into your application's secret 323 directory. 324 325 ```hcl 326 template { 327 data = <<EOH 328 {{ with secret "pki/issue/foo" "common_name=foo.service.consul" "ip_sans=127.0.0.1" "format=pem" }} 329 {{ .Data.certificate }} 330 {{ .Data.issuing_ca }} 331 {{ .Data.private_key }}{{ end }} 332 EOH 333 destination = "${NOMAD_SECRETS_DIR}/bundle.pem" 334 change_mode = "restart" 335 } 336 ``` 337 338 ### Vault KV API v1 339 340 Under Vault KV API v1, paths start with `secret/`, and the response returns the 341 raw key/value data. This secret was set using 342 `vault kv put secret/aws/s3 aws_access_key_id=somekeyid`. 343 344 ```hcl 345 template { 346 data = <<EOF 347 AWS_ACCESS_KEY_ID = "{{with secret "secret/aws/s3"}}{{.Data.aws_access_key_id}}{{end}}" 348 EOF 349 } 350 ``` 351 352 Note that if the name of a secret includes the `-` character, you must access 353 it by index. This secret was set using `vault kv put secret/app db-password=somepassword`. 354 355 ```hcl 356 template { 357 data = <<EOF 358 DB_PASSWORD = "{{with secret "secret/app"}}{{index .Data "db-password"}}{{end}}" 359 EOF 360 } 361 ``` 362 363 ### Vault KV API v2 364 365 Under Vault KV API v2, paths start with `secret/data/`, and the response returns 366 metadata in addition to key/value data. This secret was set using 367 `vault kv put secret/aws/s3 aws_access_key_id=somekeyid`. 368 369 ```hcl 370 template { 371 data = <<EOF 372 AWS_ACCESS_KEY_ID = "{{with secret "secret/data/aws/s3"}}{{.Data.data.aws_access_key_id}}{{end}}" 373 EOF 374 } 375 ``` 376 377 Notice the addition of `data` in both the path and the field accessor string. 378 Additionally, when using the Vault v2 API, the Vault policies applied to your 379 Nomad jobs will need to grant permissions to `read` under `secret/data/...` 380 rather than `secret/...`. 381 382 Similar to KV API v1, if the name of a secret includes the `-` character, you 383 must access it by index. This secret was set using `vault kv put secret/app db-password=somepassword`. 384 385 ```hcl 386 template { 387 data = <<EOF 388 DB_PASSWORD = "{{with secret "secret/data/app"}}{{index .Data.data "db-password"}}{{end}}" 389 EOF 390 } 391 ``` 392 393 ## Client Configuration 394 395 The `template` block has the following [client configuration 396 options](/docs/configuration/client#options): 397 398 - `function_denylist` `([]string: ["plugin"])` - Specifies a list of template 399 rendering functions that should be disallowed in job specs. By default the 400 `plugin` function is disallowed as it allows running arbitrary commands on 401 the host as root (unless Nomad is configured to run as a non-root user). 402 403 - `disable_file_sandbox` `(bool: false)` - Allows templates access to arbitrary 404 files on the client host via the `file` function. By default templates can 405 access files only within the [task working directory]. 406 407 [ct]: https://github.com/hashicorp/consul-template 'Consul Template by HashiCorp' 408 [artifact]: /docs/job-specification/artifact 'Nomad artifact Job Specification' 409 [env]: /docs/runtime/environment 'Nomad Runtime Environment' 410 [nodevars]: /docs/runtime/interpolation#interpreted_node_vars 'Nomad Node Variables' 411 [go-envparse]: https://github.com/hashicorp/go-envparse#readme 'The go-envparse Readme' 412 [task working directory]: /docs/runtime/environment#task-directories 'Task Directories' 413 [filesystem internals]: /docs/internals/filesystem#templates-artifacts-and-dispatch-payloads