github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/website/pages/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 directory.
    63  
    64  - `env` `(bool: false)` - Specifies the template should be read back in as
    65    environment variables for the task. ([See below](#environment-variables))
    66  
    67  - `left_delimiter` `(string: "{{")` - Specifies the left delimiter to use in the
    68    template. The default is "{{" for some templates, it may be easier to use a
    69    different delimiter that does not conflict with the output file itself.
    70  
    71  - `perms` `(string: "644")` - Specifies the rendered template's permissions.
    72    File permissions are given as octal of the Unix file permissions `rwxrwxrwx`.
    73  
    74  - `right_delimiter` `(string: "}}")` - Specifies the right delimiter to use in the
    75    template. The default is "}}" for some templates, it may be easier to use a
    76    different delimiter that does not conflict with the output file itself.
    77  
    78  - `source` `(string: "")` - Specifies the path to the template to be rendered.
    79    One of `source` or `data` must be specified, but not both. This source can
    80    optionally be fetched using an [`artifact`][artifact] resource. This template
    81    must exist on the machine prior to starting the task; it is not possible to
    82    reference a template inside of a Docker container, for example.
    83  
    84  - `splay` `(string: "5s")` - Specifies a random amount of time to wait between
    85    0 ms and the given splay value before invoking the change mode. This is
    86    specified using a label suffix like "30s" or "1h", and is often used to
    87    prevent a thundering herd problem where all task instances restart at the same
    88    time.
    89  
    90  - `vault_grace` `(string: "15s")` - [Deprecated](https://github.com/hashicorp/consul-template/issues/1268)
    91  
    92  ## `template` Examples
    93  
    94  The following examples only show the `template` stanzas. Remember that the
    95  `template` stanza is only valid in the placements listed above.
    96  
    97  ### Inline Template
    98  
    99  This example uses an inline template to render a file to disk. This file watches
   100  various keys in Consul for changes:
   101  
   102  ```hcl
   103  template {
   104    data        = "---\nkey: {{ key \"service/my-key\" }}"
   105    destination = "local/file.yml"
   106  }
   107  ```
   108  
   109  It is also possible to use heredocs for multi-line templates, like:
   110  
   111  ```hcl
   112  template {
   113    data = <<EOH
   114    ---
   115      bind_port:   {{ env "NOMAD_PORT_db" }}
   116      scratch_dir: {{ env "NOMAD_TASK_DIR" }}
   117      node_id:     {{ env "node.unique.id" }}
   118      service_key: {{ key "service/my-key" }}
   119    EOH
   120  
   121    destination = "local/file.yml"
   122  }
   123  ```
   124  
   125  ### Remote Template
   126  
   127  This example uses an [`artifact`][artifact] stanza to download an input template
   128  before passing it to the template engine:
   129  
   130  ```hcl
   131  artifact {
   132    source      = "https://example.com/file.yml.tpl"
   133    destination = "local/file.yml.tpl"
   134  }
   135  
   136  template {
   137    source      = "local/file.yml.tpl"
   138    destination = "local/file.yml"
   139  }
   140  ```
   141  
   142  ### Node Variables
   143  
   144  As of Nomad v0.5.6 it is possible to access the Node's attributes and metadata.
   145  
   146  ```hcl
   147  template {
   148    data = <<EOH
   149    ---
   150      node_dc:    {{ env "node.datacenter" }}
   151      node_cores: {{ env "attr.cpu.numcores" }}
   152      meta_key:   {{ env "meta.node_meta_key" }}
   153    EOH
   154  
   155    destination = "local/file.yml"
   156  }
   157  ```
   158  
   159  ### Environment Variables
   160  
   161  Since v0.6.0 templates may be used to create environment variables for tasks.
   162  Env templates work exactly like other templates except once the templates are
   163  written, they are parsed as `KEY=value` pairs. Those key value pairs are
   164  included in the task's environment.
   165  
   166  For example the following template stanza:
   167  
   168  ```hcl
   169  template {
   170    data = <<EOH
   171  # Lines starting with a # are ignored
   172  
   173  # Empty lines are also ignored
   174  LOG_LEVEL="{{key "service/geo-api/log-verbosity"}}"
   175  API_KEY="{{with secret "secret/geo-api-key"}}{{.Data.value}}{{end}}"
   176  EOH
   177  
   178    destination = "secrets/file.env"
   179    env         = true
   180  }
   181  ```
   182  
   183  The task's environment would then have environment variables like the
   184  following:
   185  
   186  ```
   187  LOG_LEVEL=DEBUG
   188  API_KEY=12345678-1234-1234-1234-1234-123456789abc
   189  ```
   190  
   191  This allows [12factor app](https://12factor.net/config) style environment
   192  variable based configuration while keeping all of the familiar features and
   193  semantics of Nomad templates.
   194  
   195  Secrets or certificates may contain a wide variety of characters such as
   196  newlines, quotes, and backslashes which may be difficult to quote or escape
   197  properly.
   198  
   199  Whenever a templated variable may include special characters, use the `toJSON`
   200  function to ensure special characters are properly parsed by Nomad:
   201  
   202  ```
   203  CERT_PEM={{ file "path/to/cert.pem" | toJSON }}
   204  ```
   205  
   206  The parser will read the JSON string, so the `$CERT_PEM` environment variable
   207  will be identical to the contents of the file.
   208  
   209  Likewise when evaluating a password that may contain quotes or `#`, use the
   210  `toJSON` function to ensure Nomad passes the password to task unchanged:
   211  
   212  ```
   213  # Passwords may contain any character including special characters like:
   214  #   \"'#
   215  # Use toJSON to ensure Nomad passes them to the environment unchanged.
   216  {{ with secret "secrets/data/application/backend" }}
   217  DB_PASSWD={{ .Data.data.DB_PASSWD | toJSON }}
   218  {{ end }}
   219  ```
   220  
   221  For more details see [go-envparser's README][go-envparse].
   222  
   223  ## Vault Integration
   224  
   225  ### PKI Certificate
   226  
   227  Vault is a popular open source tool for managing secrets. In addition to acting
   228  as an encrypted KV store, Vault can also generate dynamic secrets, like PKI/TLS
   229  certificates.
   230  
   231  When generating PKI certificates with Vault, the certificate, private key, and
   232  any intermediate certs are all returned as part of the same API call. Most
   233  software requires these files be placed in separate files on the system.
   234  
   235  ~> **Note**: `generate_lease` must be set to `true` (non-default) on the Vault PKI
   236  role.<br /><br /> Failure to do so will cause the template to frequently render a new
   237  certificate, approximately every minute. This creates a significant number of
   238  certificates to be expired in Vault and could ultimately lead to Vault performance
   239  impacts and failures.
   240  
   241  #### As individual files
   242  
   243  For templates, all dependencies are mapped into a single list. This means that
   244  multiple templates watching the same path return the same data.
   245  
   246  ```hcl
   247  template {
   248    data = <<EOH
   249  {{ with secret "pki/issue/foo" "common_name=foo.service.consul" "ip_sans=127.0.0.1" }}
   250  {{- .Data.certificate -}}
   251  {{ end }}
   252  EOH
   253    destination   = "${NOMAD_SECRETS_DIR}/certificate.crt"
   254    change_mode   = "restart"
   255  }
   256  
   257  template {
   258    data = <<EOH
   259  {{ with secret "pki/issue/foo" "common_name=foo.service.consul" "ip_sans=127.0.0.1" }}
   260  {{- .Data.issuing_ca -}}
   261  {{ end }}
   262  EOH
   263    destination   = "${NOMAD_SECRETS_DIR}/ca.crt"
   264    change_mode   = "restart"
   265  }
   266  
   267  template {
   268    data = <<EOH
   269  {{ with secret "pki/issue/foo" "common_name=foo.service.consul" "ip_sans=127.0.0.1" }}
   270  {{- .Data.private_key -}}
   271  {{ end }}
   272  EOH
   273    destination   = "${NOMAD_SECRETS_DIR}/private_key.key"
   274    change_mode   = "restart"
   275  }
   276  ```
   277  
   278  These are three different input templates, but when run under the Nomad job,
   279  they are compressed into a single call, sharing the resulting data.
   280  
   281  #### As a PEM formatted file
   282  
   283  This example acquires a PKI certificate from Vault in PEM format, concatenates
   284  the elements into a bundle, and stores it into your application's secret
   285  directory.
   286  
   287  ```hcl
   288  template {
   289    data = <<EOH
   290  {{ with secret "pki/issue/foo" "common_name=foo.service.consul" "ip_sans=127.0.0.1" "format=pem" }}
   291  {{ .Data.certificate }}
   292  {{ .Data.issuing_ca }}
   293  {{ .Data.private_key }}{{ end }}
   294  EOH
   295    destination   = "${NOMAD_SECRETS_DIR}/bundle.pem"
   296    change_mode   = "restart"
   297  }
   298  ```
   299  
   300  ### Vault KV API v1
   301  
   302  Under Vault KV API v1, paths start with `secret/`, and the response returns the
   303  raw key/value data. This secret was set using
   304  `vault kv put secret/aws/s3 aws_access_key_id=somekeyid`.
   305  
   306  ```hcl
   307    template {
   308      data = <<EOF
   309        AWS_ACCESS_KEY_ID = "{{with secret "secret/aws/s3"}}{{.Data.aws_access_key_id}}{{end}}"
   310      EOF
   311    }
   312  ```
   313  
   314  ### Vault KV API v2
   315  
   316  Under Vault KV API v2, paths start with `secret/data/`, and the response returns
   317  metadata in addition to key/value data. This secret was set using
   318  `vault kv put secret/aws/s3 aws_access_key_id=somekeyid`.
   319  
   320  ```hcl
   321    template {
   322      data = <<EOF
   323        AWS_ACCESS_KEY_ID = "{{with secret "secret/data/aws/s3"}}{{.Data.data.aws_access_key_id}}{{end}}"
   324      EOF
   325    }
   326  ```
   327  
   328  Notice the addition of `data` in both the path and the field accessor string.
   329  Additionally, when using the Vault v2 API, the Vault policies applied to your
   330  Nomad jobs will need to grant permissions to `read` under `secret/data/...`
   331  rather than `secret/...`.
   332  
   333  ## Client Configuration
   334  
   335  The `template` block has the following [client configuration
   336  options](/docs/configuration/client#options):
   337  
   338  - `template.allow_host_source` - Allows templates to specify their source
   339    template as an absolute path referencing host directories. Defaults to `true`.
   340  
   341  [ct]: https://github.com/hashicorp/consul-template 'Consul Template by HashiCorp'
   342  [artifact]: /docs/job-specification/artifact 'Nomad artifact Job Specification'
   343  [env]: /docs/runtime/environment 'Nomad Runtime Environment'
   344  [nodevars]: /docs/runtime/interpolation#interpreted_node_vars 'Nomad Node Variables'
   345  [go-envparse]: https://github.com/hashicorp/go-envparse#readme 'The go-envparse Readme'