github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/website/content/docs/job-specification/template.mdx (about) 1 --- 2 layout: docs 3 page_title: template Stanza - Job Specification 4 description: |- 5 The "template" block instantiates an instance of a template renderer. This 6 creates a convenient way to ship configuration files that are populated from 7 environment variables, Consul data, Vault secrets, or just general 8 configurations within a Nomad task. 9 --- 10 11 # `template` Stanza 12 13 <Placement groups={['job', 'group', 'task', 'template']} /> 14 15 The `template` block instantiates an instance of a template renderer. This 16 creates a convenient way to ship configuration files that are populated from 17 environment variables, Consul data, Vault secrets, or just general 18 configurations within a Nomad task. 19 20 ```hcl 21 job "docs" { 22 group "example" { 23 task "server" { 24 template { 25 source = "local/redis.conf.tpl" 26 destination = "local/redis.conf" 27 change_mode = "signal" 28 change_signal = "SIGINT" 29 } 30 } 31 } 32 } 33 ``` 34 35 Nomad utilizes [Go template][gt] and a tool called [Consul Template][ct], which 36 adds a set of new functions that can be used to retrieve data from Consul and 37 Vault. Nomad templates can reference [Nomad's runtime 38 environment variables][env], [node attributes and metadata][nodevars], 39 [Nomad service registrations][ct_api_nsvc], and [Nomad variables][nvars]. 40 Templates can also be used to provide environment variables to your workload. 41 42 For a full list of the API template functions, please refer to the [Consul 43 Template documentation][ct_api]. For a an introduction to Go templates, please 44 refer to the [Learn Go Template Syntax][gt_learn] guide. 45 46 ## `template` Parameters 47 48 - `change_mode` `(string: "restart")` - Specifies the behavior Nomad should take 49 if the rendered template changes. Nomad will always write the new contents of 50 the template to the specified destination. The following possible values describe 51 Nomad's action after writing the template to disk. 52 53 - `"noop"` - take no action (continue running the task) 54 - `"restart"` - restart the task 55 - `"signal"` - send a configurable signal to the task 56 - `"script"` - run a script 57 58 - `change_signal` `(string: "")` - Specifies the signal to send to the task as a 59 string like `"SIGUSR1"` or `"SIGINT"`. This option is required if the 60 `change_mode` is `signal`. 61 62 - `change_script` <code>([`ChangeScript`][]: nil)</code> - Configures the script 63 triggered on template change. This option is required if the `change_mode` is 64 `script`. 65 66 - `data` `(string: "")` - Specifies the raw template to execute. One of `source` 67 or `data` must be specified, but not both. This is useful for smaller 68 templates, but we recommend using `source` for larger templates. 69 70 - `destination` `(string: <required>)` - Specifies the location where the 71 resulting template should be rendered, relative to the [task working 72 directory]. Only drivers without filesystem isolation (ex. `raw_exec`) or 73 that build a chroot in the task working directory (ex. `exec`) can render 74 templates outside of the `NOMAD_ALLOC_DIR`, `NOMAD_TASK_DIR`, or 75 `NOMAD_SECRETS_DIR`. For more details on how `destination` interacts with 76 task drivers, see the [Filesystem internals] documentation. 77 78 - `env` `(bool: false)` - Specifies the template should be read back in as 79 environment variables for the task ([example](#environment-variables)). To 80 update the environment on changes, you must set `change_mode` to 81 `restart`. Setting `env` when the `change_mode` is `signal` will return a 82 validation error. Setting `env` when the `change_mode` is `noop` is 83 permitted but will not update the environment variables in the task. 84 85 - `error_on_missing_key` `(bool: false)` - Specifies how the template behaves 86 when attempting to index a map key that does not exist in the map. 87 88 - When `true`, the template engine will return an error, which will cause the 89 task to fail. 90 91 - When `false`, the template engine will do nothing and continue executing the 92 template. If printed, the result of the index operation is the string 93 "<no value\>". 94 95 - `left_delimiter` `(string: "{{")` - Specifies the left delimiter to use in the 96 template. The default is "{{" for some templates, it may be easier to use a 97 different delimiter that does not conflict with the output file itself. 98 99 - `perms` `(string: "644")` - Specifies the rendered template's permissions. 100 File permissions are given as octal of the Unix file permissions `rwxrwxrwx`. 101 102 - `uid` `(int: nil)` - Specifies the rendered template owner's user ID. If 103 negative or not specified (`nil`) the ID of the Nomad agent user will be used. 104 105 ~> **Caveat:** Works only on Unix-based systems. Be careful when using 106 containerized drivers, such as `docker` or `podman`, as groups and users 107 inside the container may have different IDs than on the host system. This 108 feature will also **not** work with Docker Desktop. 109 110 - `gid` `(int: nil)` - Specifies the rendered template owner's group ID. If 111 negative or not specified (`nil`) the ID of the Nomad agent group will be 112 used. 113 114 ~> **Caveat:** Works only on Unix-based systems. Be careful when using 115 containerized drivers, such as `docker` or `podman`, as groups and users 116 inside the container may have different IDs than on the host system. This 117 feature will also **not** work with Docker Desktop. 118 119 - `right_delimiter` `(string: "}}")` - Specifies the right delimiter to use in the 120 template. The default is "}}" for some templates, it may be easier to use a 121 different delimiter that does not conflict with the output file itself. 122 123 - `source` `(string: "")` - Specifies the path to the template to be rendered. 124 One of `source` or `data` must be specified, but not both. This source can 125 optionally be fetched using an [`artifact`][artifact] resource. This template 126 must exist on the machine prior to starting the task; it is not possible to 127 reference a template that's source is inside a Docker container, for example. 128 129 - `splay` `(string: "5s")` - Specifies a random amount of time to wait between 130 0 ms and the given splay value before invoking the change mode. This is 131 specified using a label suffix like "30s" or "1h", and is often used to 132 prevent a thundering herd problem where all task instances restart at the same 133 time. 134 135 - `wait` `(Code: nil)` - Defines the minimum and maximum amount of time to wait 136 for the Consul cluster to reach a consistent state before rendering a template. 137 This is useful to enable in systems where network connectivity to Consul is degraded, 138 because it will reduce the number of times a template is rendered. This setting 139 can be overridden by the [`client.template.wait_bounds`]. If the template 140 configuration has a `min` lower than `client.template.wait_bounds.min` or a `max` 141 greater than `client.template.wait_bounds.max`, the client's bounds will be enforced, 142 and the template `wait` will be adjusted before being sent to the template 143 engine. 144 145 ```hcl 146 wait { 147 min = "5s" 148 max = "10s" 149 } 150 ``` 151 152 - `vault_grace` `(string: "15s")` - [Deprecated](https://github.com/hashicorp/consul-template/issues/1268) 153 154 ## `template` Examples 155 156 The following examples only show the `template` stanzas. Remember that the 157 `template` stanza is only valid in the placements listed above. 158 159 ### Inline Template 160 161 This example uses an inline template to render a file to disk. This file watches 162 various keys in Consul for changes: 163 164 ```hcl 165 template { 166 data = "---\nkey: {{ key \"service/my-key\" }}" 167 destination = "local/file.yml" 168 } 169 ``` 170 171 It is also possible to use heredocs for multi-line templates, like: 172 173 ```hcl 174 template { 175 data = <<EOH 176 --- 177 bind_port: {{ env "NOMAD_PORT_db" }} 178 scratch_dir: {{ env "NOMAD_TASK_DIR" }} 179 node_id: {{ env "node.unique.id" }} 180 service_key: {{ key "service/my-key" }} 181 EOH 182 183 destination = "local/file.yml" 184 } 185 ``` 186 187 ### Remote Template 188 189 This example uses an [`artifact`][artifact] stanza to download an input template 190 before passing it to the template engine: 191 192 ```hcl 193 artifact { 194 source = "https://example.com/file.yml.tpl" 195 destination = "local/file.yml.tpl" 196 } 197 198 template { 199 source = "local/file.yml.tpl" 200 destination = "local/file.yml" 201 } 202 ``` 203 204 ### Task `meta` values 205 206 To render values from a task's `meta` config, use the environment variable form 207 of the meta variable name. 208 209 ```hcl 210 meta { 211 mykey = "some_value" 212 } 213 214 template { 215 data = <<EOH 216 {{ env "NOMAD_META_mykey" }} 217 EOH 218 } 219 ``` 220 221 ### Node Variables 222 223 Use the `env` function to access the Node's attributes and metadata inside a 224 template. Note the `meta.` syntax here applies only to node meta fields. 225 226 ```hcl 227 template { 228 data = <<EOH 229 --- 230 node_dc: {{ env "node.datacenter" }} 231 node_cores: {{ env "attr.cpu.numcores" }} 232 meta_key: {{ env "meta.node_meta_key" }} 233 EOH 234 235 destination = "local/file.yml" 236 } 237 ``` 238 239 ### Environment Variables 240 241 Templates may be used to create environment variables for tasks. These templates 242 work exactly like other templates except once the templates are written, they 243 are parsed as `KEY=value` pairs. Those key value pairs are included in the 244 task's environment. 245 246 For example the following template stanza: 247 248 ```hcl 249 template { 250 data = <<EOH 251 # Lines starting with a # are ignored 252 253 # Empty lines are also ignored 254 LOG_LEVEL="{{key "service/geo-api/log-verbosity"}}" 255 API_KEY="{{with secret "secret/geo-api-key"}}{{.Data.value}}{{end}}" 256 EOH 257 258 destination = "secrets/file.env" 259 env = true 260 } 261 ``` 262 263 The task's environment would then have environment variables like the 264 following: 265 266 ```text 267 LOG_LEVEL=DEBUG 268 API_KEY=12345678-1234-1234-1234-1234-123456789abc 269 ``` 270 271 This allows [12factor app](https://12factor.net/config) style environment 272 variable based configuration while keeping all the familiar features and 273 semantics of Nomad templates. 274 275 Secrets or certificates may contain a wide variety of characters such as 276 newlines, quotes, and backslashes which may be difficult to quote or escape 277 properly. 278 279 Whenever a templated variable may include special characters, use the `toJSON` 280 function to ensure special characters are properly parsed by Nomad. 281 282 ```hcl 283 CERT_PEM={{ file "path/to/cert.pem" | toJSON }} 284 ``` 285 286 The parser will read the JSON string, so the `$CERT_PEM` environment variable 287 will be identical to the contents of the file. 288 289 Likewise, when evaluating a password that may contain quotes or `#`, use the 290 `toJSON` function to ensure Nomad passes the password to the task unchanged. 291 292 ```hcl 293 # Passwords may contain any character including special characters like: 294 # \"'# 295 # Use toJSON to ensure Nomad passes them to the environment unchanged. 296 {{ with secret "secrets/data/application/backend" }} 297 DB_PASSWD={{ .Data.data.DB_PASSWD | toJSON }} 298 {{ end }} 299 ``` 300 301 For more details see [go-envparser's README][go-envparse]. 302 303 ### Template Destinations 304 305 Templates are rendered into the task working directory. Drivers without 306 filesystem isolation (such as `raw_exec`) or drivers that build a chroot in 307 the task working directory (such as `exec`) can have templates rendered to 308 arbitrary paths in the task. But task drivers such as `docker` can only access 309 templates rendered into the `NOMAD_ALLOC_DIR`, `NOMAD_TASK_DIR`, or 310 `NOMAD_SECRETS_DIR`. To work around this restriction, you can create a mount 311 from the template `destination` to another location in the task. 312 313 ```hcl 314 task "task" { 315 driver = "docker" 316 317 config { 318 image = "redis:6.0" 319 mount { 320 type = "bind" 321 source = "local" 322 target = "/etc/redis.d" 323 } 324 } 325 326 template { 327 destination = "local/redis.conf" 328 } 329 } 330 ``` 331 332 ## Nomad Integration 333 334 ### Nomad Services 335 336 ~> Nomad Services are new in Nomad 1.3. 337 338 Nomad service registrations can be queried using the `nomadService` and 339 `nomadServices` functions. The requests are tied to the same namespace as the 340 job which contains the template stanza. 341 342 ```hcl 343 template { 344 data = <<EOF 345 # Configuration for a single NGINX upstream service. 346 upstream my_app { 347 {{- range nomadService "my-app" }} 348 server {{ .Address }}:{{ .Port }};{{- end }} 349 } 350 351 # Configuration for all services registered in Nomad as an NGINX upstream 352 # service. 353 {{ range nomadServices }} 354 # Configuration for service {{ .Name }}. 355 upstream {{ .Name | toLower }} { 356 {{- range nomadService .Name }} 357 server {{ .Address}}:{{ .Port }};{{- end }} 358 } 359 {{ end -}} 360 EOF 361 362 destination = "local/nginx.conf" 363 } 364 ``` 365 366 ### Simple Load Balancing with Nomad Services 367 368 ~> Simple load balancing with Nomad Services is new in Nomad 1.3.2. 369 370 The `nomadService` function now supports simple load balancing by selecting 371 instances of a service via [rendezvous hashing][rhash]. 372 To enable simple load balancing, the `nomadService` function requires 3 arguments. 373 374 - The number of services to select 375 - The hashing key (should be unique, but consistent per requester) 376 - The service name 377 378 By using `NOMAD_ALLOC_ID` as the hashing key, the selected instances will remain 379 mostly stable for the allocation. Each time the template is run, `nomadService` 380 will return the same set of instances for each allocation - unless N instances of 381 the service are added or removed, in which case there is a 1/N chance of a selected 382 instance being replaced. This helps maintain a more consistent output when rendering 383 configuration files, triggering fewer restarts and signaling of Nomad tasks. 384 385 ```hcl 386 template { 387 data = <<EOH 388 # Configuration for 1 redis instances, as assigned via rendezvous hashing. 389 {{$allocID := env "NOMAD_ALLOC_ID" -}} 390 {{range nomadService 1 $allocID "redis"}} 391 server {{ .Address }}:{{ .Port }};{{- end }} 392 {{- end}} 393 EOH 394 } 395 ``` 396 397 ### Nomad Variables 398 399 Nomad [variables] can be queried using the `nomadVar`, `nomadVarList`, 400 `nomadVarListSafe`, and `nomadVarExists` functions. 401 402 #### `nomadVarList` and `nomadVarListSafe` 403 404 These functions can be used to list the paths of Nomad variables available to 405 the task based on its [workload identity]. You can provide an optional prefix to 406 filter the path list by as a parameter. 407 408 The list functions return a slice of `NomadVarMeta` type: 409 410 ```golang 411 type NomadVarMeta struct { 412 Namespace, Path string 413 CreateIndex, ModifyIndex uint64 414 CreateTime, ModifyTime nanoTime 415 } 416 ``` 417 418 The `nanoTime` type contains Unix nanoseconds since the epoch. Its string method 419 prints it out as a formatted date/time value. It also has a `Time` method that 420 can be used to retrieve a Go [`time.Time`] for further manipulation. 421 422 `NomadVarMeta` objects print their `Path` value when used as a string. For 423 example, these two template blocks produce identical output. 424 425 ```hcl 426 template { 427 data = <<EOH 428 {{ range nomadVarList }} 429 {{ . }} 430 {{ end }} 431 } 432 EOH 433 } 434 435 template { 436 data = <<EOH 437 {{ range nomadVarList }} 438 {{ .Path }} 439 {{ end }} 440 } 441 EOH 442 } 443 ``` 444 445 You can provide a prefix to filter the path list as an optional parameter to the 446 `nomadVarList` function. 447 448 ```hcl 449 template { 450 data = <<EOH 451 {{ range nomadVarList "path/to/filter" }} 452 {{ . }} 453 {{ end }} 454 } 455 EOH 456 } 457 ``` 458 459 By default, the `nomadVarList` will list variables in the same namespace as the 460 task. The path filter can change the namespace by adding a suffix separated by 461 the `@` character: 462 463 ```hcl 464 template { 465 data = <<EOH 466 {{ range nomadVarList "path/to/filter@example_namespace" }} 467 {{ . }} 468 {{ end }} 469 } 470 EOH 471 } 472 ``` 473 474 The `nomadVarListSafe` function works identically to `nomadVarList`, but refuses 475 to render the template if the variable list query returns blank/empty data. 476 477 #### `nomadVar` 478 479 These functions can be used to a read Nomad variable, assuming the task has 480 access rights to the variable based on the task's [workload identity]. If the 481 path does not exist or the caller does not have access to it, the `template` 482 renderer will block until the path is available. To avoid blocking, wrap 483 `nomadVar` calls with [`nomadVarExists`](#nomadvarexists). 484 485 The `nomadVar` function returns a map of `string` to `NomadVarItems` 486 structs. Each member of the map corresponds to a member of the variable's 487 `Items` collection. 488 489 For example, given a variable exists at the path `nomad/jobs/redis`, with a 490 single key/value pair in its Items collection—`maxconns`:`15` 491 492 ```hcl 493 template { 494 data = <<EOH 495 {{ with nomadVar "nomad/jobs/redis" }}{{ .maxconns }}{{ end }} 496 EOH 497 } 498 ``` 499 500 renders 501 502 ```text 503 15 504 ``` 505 506 Each map value also contains helper methods to get the variable metadata and a 507 link to the parent variable: 508 509 - `Keys`: produces a sorted list of keys to this `NomadVarItems` map. 510 511 - `Values`: produces a key-sorted list. 512 513 - `Tuples`: produces a key-sorted list of K,V tuple structs. 514 515 - `Metadata`: returns this collection's parent metadata as a `NomadVarMeta` 516 517 - `Parent`: returns a parent object that has a Metadata field referring to the 518 `NomadVarMeta` and an Items field that refers to this `NomadVarItems` object. 519 520 For example, given a variable exists at the path `nomad/jobs/redis`, you could 521 render some of its metadata as follows: 522 523 ```hcl 524 template { 525 data = <<EOH 526 {{ with nomadVar "nomad/jobs/redis" }} 527 Path: {{ .Metadata.Path }} 528 Namespace: {{ .Metadata.Namespace }} 529 CreateTime: {{ .Metadata.CreateTime }} 530 ModifyTime: {{ .Metadata.ModifyTime }} 531 {{ end }} 532 EOH 533 } 534 ``` 535 536 By default, the `nomadVar` function reads a variable in the same namespace as 537 the task. The path filter can change the namespace by adding a suffix separated 538 by the `@` character. 539 540 ```hcl 541 template { 542 data = <<EOH 543 {{ with nomadVar "nomad/jobs/redis@example_namespace" }}{{ .maxconns }}{{ end }} 544 EOH 545 } 546 ``` 547 548 #### `nomadVarExists` 549 550 This function can be used to check if a Nomad variable exists at the provided 551 path, assuming the task has access rights to the variable based on the task's 552 [workload identity]. If a variable exists, this will return true, false 553 otherwise. Unlike [`nomadVar`](#nomadvar), this function will not block if the 554 variable does not exist, which can be useful for controlling flow. 555 556 For example: 557 558 ```hcl 559 template { 560 data = <<EOH 561 {{ if nomadVarExists "app/beta_active" }} 562 # ... 563 {{ else }} 564 # ... 565 {{ end }} 566 EOH 567 } 568 ``` 569 570 ## Consul Integration 571 572 ### Consul KV 573 574 Consul KV values can be accessed using the [`key`][ct_api_key] function to 575 retrieve a single value from a key path. The [`ls`][ct_api_ls] function can be 576 used to retrieve all keys in a path. For deeply nested paths, use the 577 [`tree`][ct_api_tree] function. 578 579 ```hcl 580 template { 581 data = <<EOF 582 # Read single key from Consul KV. 583 APP_NAME = "{{key "app/name"}}" 584 585 # Read all keys in the path `app/environment` from Consul KV. 586 {{range ls "app/environment"}} 587 {{.Key}}={{.Value}} 588 {{end}} 589 EOF 590 591 destination = "local/env" 592 env = true 593 } 594 ``` 595 596 ### Consul Services 597 598 The Consul service catalog can be queried using the [`service`][ct_api_service] 599 and [`services`][ct_api_services] functions. For Connect-capable services, use 600 the [`connect`][ct_api_connect] function. 601 602 ```hcl 603 template { 604 data = <<EOF 605 # Configuration for a single upstream service. 606 upstream my_app { 607 {{- range service "my-app" }} 608 server {{ .Address }}:{{ .Port }};{{- end }} 609 } 610 611 # Configuration for all services in the catalog. 612 {{ range services }} 613 # Configuration for service {{ .Name }}. 614 upstream {{ .Name | toLower }} { 615 {{- range service .Name }} 616 server {{ .Address}}:{{ .Port }};{{- end }} 617 } 618 {{ end -}} 619 EOF 620 621 destination = "local/nginx.conf" 622 } 623 ``` 624 625 ## Vault Integration 626 627 ### PKI Certificate 628 629 Vault is a popular open source tool for managing secrets. In addition to acting 630 as an encrypted KV store, Vault can also generate dynamic secrets, like PKI/TLS 631 certificates. 632 633 When generating PKI certificates with Vault, the certificate, private key, and 634 any intermediate certs are all returned as part of the same API call. Most 635 software requires these files be placed in separate files on the system. 636 637 ~> **Note**: `generate_lease` must be set to `true` (non-default) on the Vault 638 PKI role.<br /><br /> Failure to do so will cause the template to frequently 639 render a new certificate, approximately every minute. This creates a significant 640 number of certificates to be expired in Vault and could ultimately lead to Vault 641 performance impacts and failures. 642 643 #### As individual files 644 645 For templates, all dependencies are mapped into a single list. This means that 646 multiple templates watching the same path return the same data. 647 648 ```hcl 649 template { 650 data = <<EOH 651 {{ with secret "pki/issue/foo" "common_name=foo.service.consul" "ip_sans=127.0.0.1" }} 652 {{- .Data.certificate -}} 653 {{ end }} 654 EOH 655 destination = "${NOMAD_SECRETS_DIR}/certificate.crt" 656 change_mode = "restart" 657 } 658 659 template { 660 data = <<EOH 661 {{ with secret "pki/issue/foo" "common_name=foo.service.consul" "ip_sans=127.0.0.1" }} 662 {{- .Data.issuing_ca -}} 663 {{ end }} 664 EOH 665 destination = "${NOMAD_SECRETS_DIR}/ca.crt" 666 change_mode = "restart" 667 } 668 669 template { 670 data = <<EOH 671 {{ with secret "pki/issue/foo" "common_name=foo.service.consul" "ip_sans=127.0.0.1" }} 672 {{- .Data.private_key -}} 673 {{ end }} 674 EOH 675 destination = "${NOMAD_SECRETS_DIR}/private_key.key" 676 change_mode = "restart" 677 } 678 ``` 679 680 These are three different input templates, but when run under the Nomad job, 681 they are compressed into a single call, sharing the resulting data. 682 683 #### As a PEM formatted file 684 685 This example acquires a PKI certificate from Vault in PEM format, concatenates 686 the elements into a bundle, and stores it into your application's secret 687 directory. 688 689 ```hcl 690 template { 691 data = <<EOH 692 {{ with secret "pki/issue/foo" "common_name=foo.service.consul" "ip_sans=127.0.0.1" "format=pem" }} 693 {{ .Data.certificate }} 694 {{ .Data.issuing_ca }} 695 {{ .Data.private_key }}{{ end }} 696 EOH 697 destination = "${NOMAD_SECRETS_DIR}/bundle.pem" 698 change_mode = "restart" 699 } 700 ``` 701 702 ### Vault KV API v1 703 704 Under Vault KV API v1, paths start with `secret/`, and the response returns the 705 raw key/value data. This secret was set using 706 `vault kv put secret/aws/s3 aws_access_key_id=somekeyid`. 707 708 ```hcl 709 template { 710 data = <<EOF 711 AWS_ACCESS_KEY_ID = "{{with secret "secret/aws/s3"}}{{.Data.aws_access_key_id}}{{end}}" 712 EOF 713 } 714 ``` 715 716 Note that if the name of a secret includes the `-` character, you must access 717 it by index. This secret was set using `vault kv put secret/app db-password=somepassword`. 718 719 ```hcl 720 template { 721 data = <<EOF 722 DB_PASSWORD = "{{with secret "secret/app"}}{{index .Data "db-password"}}{{end}}" 723 EOF 724 } 725 ``` 726 727 ### Vault KV API v2 728 729 Under Vault KV API v2, paths start with `secret/data/`, and the response returns 730 metadata in addition to key/value data. This secret was set using 731 `vault kv put secret/aws/s3 aws_access_key_id=somekeyid`. 732 733 ```hcl 734 template { 735 data = <<EOF 736 AWS_ACCESS_KEY_ID = "{{with secret "secret/data/aws/s3"}}{{.Data.data.aws_access_key_id}}{{end}}" 737 EOF 738 } 739 ``` 740 741 Notice the addition of `data` in both the path and the field accessor string. 742 Additionally, when using the Vault v2 API, the Vault policies applied to your 743 Nomad jobs will need to grant permissions to `read` under `secret/data/...` 744 rather than `secret/...`. 745 746 Like KV API v1, if the name of a secret includes the `-` character, you must 747 access it by index. This secret was set using 748 `vault kv put secret/app db-password=somepassword`. 749 750 ```hcl 751 template { 752 data = <<EOF 753 DB_PASSWORD = "{{with secret "secret/data/app"}}{{index .Data.data "db-password"}}{{end}}" 754 EOF 755 } 756 ``` 757 758 ## Client Configuration 759 760 The `template` block has the following [client configuration 761 options](/docs/configuration/client#options): 762 763 - `function_denylist` `([]string: ["plugin"])` - Specifies a list of template 764 rendering functions that should be disallowed in job specs. By default, the 765 `plugin` function is disallowed as it allows running arbitrary commands on 766 the host as root (unless Nomad is configured to run as a non-root user). 767 768 - `disable_file_sandbox` `(bool: false)` - Allows templates access to arbitrary 769 files on the client host via the `file` function. By default, templates can 770 access files only within the [task working directory]. 771 772 [`changescript`]: /docs/job-specification/change_script 'Nomad change_script Job Specification' 773 [ct]: https://github.com/hashicorp/consul-template 'Consul Template by HashiCorp' 774 [ct_api]: https://github.com/hashicorp/consul-template/blob/master/docs/templating-language.md 'Consul Template API by HashiCorp' 775 [ct_api_connect]: https://github.com/hashicorp/consul-template/blob/master/docs/templating-language.md#connect 'Consul Template API by HashiCorp - connect' 776 [ct_api_key]: https://github.com/hashicorp/consul-template/blob/master/docs/templating-language.md#key 'Consul Template API by HashiCorp - key' 777 [ct_api_ls]: https://github.com/hashicorp/consul-template/blob/master/docs/templating-language.md#ls 'Consul Template API by HashiCorp - ls' 778 [ct_api_service]: https://github.com/hashicorp/consul-template/blob/master/docs/templating-language.md#service 'Consul Template API by HashiCorp - service' 779 [ct_api_services]: https://github.com/hashicorp/consul-template/blob/master/docs/templating-language.md#services 'Consul Template API by HashiCorp - services' 780 [ct_api_nsvc]: https://github.com/hashicorp/consul-template/blob/master/docs/templating-language.md#nomadService 'Consul Template API by HashiCorp - nomadService' 781 [nvars]: /docs/concepts/variablesr 'Nomad Variables' 782 [ct_api_tree]: https://github.com/hashicorp/consul-template/blob/master/docs/templating-language.md#tree 'Consul Template API by HashiCorp - tree' 783 [gt]: https://pkg.go.dev/text/template 'Go template package' 784 [gt_learn]: https://learn.hashicorp.com/tutorials/nomad/go-template-syntax 785 [artifact]: /docs/job-specification/artifact 'Nomad artifact Job Specification' 786 [env]: /docs/runtime/environment 'Nomad Runtime Environment' 787 [nodevars]: /docs/runtime/interpolation#interpreted_node_vars 'Nomad Node Variables' 788 [go-envparse]: https://github.com/hashicorp/go-envparse#readme 'The go-envparse Readme' 789 [task working directory]: /docs/runtime/environment#task-directories 'Task Directories' 790 [filesystem internals]: /docs/concepts/filesystem#templates-artifacts-and-dispatch-payloads 791 [`client.template.wait_bounds`]: /docs/configuration/client#wait_bounds 792 [rhash]: https://en.wikipedia.org/wiki/Rendezvous_hashing 793 [variables]: /docs/concepts/variables 794 [workload identity]: /docs/concepts/workload-identity 795 [`time.Time`]: https://pkg.go.dev/time#Time