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