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'