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