vault Block
Placement | job -> vault job -> group -> vault job -> group -> task -> vault |
The vault
block allows a task to specify that it requires a token from a
HashiCorp Vault server. Nomad will automatically retrieve a Vault token
for the task and handle token renewal for the task. If specified at the group
level, the configuration will apply to all tasks within the group. If specified
at the job
level, the configuration will apply to all tasks within the job. If
multiple vault
blocks are specified, they are merged with the task
block
taking the highest precedence, then the group
, then the job
.
job "docs" {
group "example" {
task "server" {
vault {
cluster = "default"
role = "prod"
change_mode = "signal"
change_signal = "SIGUSR1"
}
}
}
}
The Nomad client will make the Vault token available to the task by writing it
to the secret directory at secrets/vault_token
and by injecting a VAULT_TOKEN
environment variable. If the Nomad cluster is configured
to use Vault Namespaces,
a VAULT_NAMESPACE
environment variable will be injected whenever VAULT_TOKEN
is set.
This behavior can be altered using the env
and file
parameters.
If Nomad is unable to renew the Vault token (perhaps due to a Vault outage or
network error), the client will attempt to retrieve a new Vault token. If successful, the
contents of the secrets file are updated on disk, and action will be taken
according to the value set in the change_mode
parameter.
If a vault
block is specified, the template
block can interact
with Vault as well.
vault
Parameters
allow_token_expiration
(bool: false)
- Specifies that Nomad clients should not attempt to renew a task's Vault token, allowing it to expire. This should only be used when a secret is requested from Vault once at the start of a task or in a short-lived prestart task. Long-running tasks should never setallow_token_expiration=true
if they obtain Vault secrets viatemplate
blocks, as the Vault token will expire and the template runner will continue to make failing requests to Vault until itsvault_retry
attempts are exhausted, at which point the task will fail.When Nomad has been configured to use Workload Identity with Vault, Nomad clients will automatically detect when tokens cannot be refreshed (for example, when the Vault auth method is configured to issue batch tokens). In this case, the
allow_token_expiration
option will be implicitly set totrue
by the client. The legacy Vault authentication workflow cannot automatically detect this.change_mode
(string: "restart")
- Specifies the behavior Nomad should take if the Vault token changes. The possible values are:change_signal
(string: "")
- Specifies the signal to send to the task as a string like"SIGUSR1"
or"SIGINT"
. This option is required if thechange_mode
issignal
.cluster
(string: "default")
Enterprise - Specifies the Vault cluster to use. The Nomad client will retrieve a Vault token from the cluster configured in the agent configuration with the samevault.name
. In Nomad Community Edition, this field is ignored.env
(bool: true)
- Specifies if theVAULT_TOKEN
andVAULT_NAMESPACE
environment variables should be set when starting the task.disable_file
(bool: false)
- Specifies if the Vault token should be written tosecrets/vault_token
.namespace
(string: "")
Enterprise - Specifies the Vault Namespace to use for the task. The Nomad client will retrieve a Vault token that is scoped to this particular namespace.policies
(array<string>: [])
- Specifies the set of Vault policies that the task requires. The Nomad client will retrieve a Vault token that is limited to those policies. This field may only be used with the legacy Vault authentication workflow and not with JWT and workload identity. It is deprecated in favor of therole
field and will be removed in Nomad 1.9.role
(string: "")
- Specifies the Vault role used when retrieving a token from Vault using JWT and workload identity. If not specified the client'screate_from_role
value is used.
vault
Examples
The following examples only show the vault
blocks. Remember that the
vault
block is only valid in the placements listed above.
Retrieve Token
This example tells the Nomad client to retrieve a Vault token. The token is
available to the task via the canonical environment variable VAULT_TOKEN
and
written to disk at secrets/vault_token
. The resulting token will have the
Vault policies from the "prod" role attached.
vault {
role = "prod"
}
Signal Task
This example shows signaling the task instead of restarting it.
vault {
role = "prod"
change_mode = "signal"
change_signal = "SIGINT"
}
Private Token and Change Modes
This example retrieves a Vault token that is not shared with the task when using
a driver that provides image
isolation like Docker.
This allows Nomad to use a powerful Vault token that interacts with the task's
template
stanzas to issue all kinds of secrets (e.g., database
secrets, other vault tokens, etc.), without sharing that issuing power with
the task itself:
vault {
role = "prod"
change_mode = "noop"
env = false
file = false
}
template {
data = <<-EOH
{{with secret "auth/token/create/nomad-job" "policies=examplepolicy"}}{{.Auth.ClientToken}}{{ end }}
EOH
destination = "${NOMAD_SECRETS_DIR}/examplepolicy.token"
change_mode = "noop"
perms = "600"
}
template {
data = <<-EOH
{{ with secret "pki_int/issue/nomad-task"
"common_name=example.service.consul" "ttl=72h"
"alt_names=localhost" "ip_sans=127.0.0.1"}}
{{ .Data.certificate }}
{{ .Data.private_key }}
{{ end }}
EOH
destination = "${NOMAD_SECRETS_DIR}/client.crt"
change_mode = "restart"
perms = "600"
}
The example above uses change_mode = "noop"
in the template
stanza for
examplepolicy.token
, which means that the task's workload is responsible for
detecting and handling changes to that file. In contrast, the template
stanza
for client.crt
is configured so that Nomad will restart the task whenever
the certificate is reissued, as indicated by change_mode = "restart"
(which is the default value for change_mode
).
Vault Namespace
This example shows specifying a particular Vault namespace for a given task.
This feature requires Nomad Enterprise(opens in new tab).
vault {
role = "prod"
namespace = "engineering/frontend"
change_mode = "signal"
change_signal = "SIGINT"
}