mirror of
https://github.com/kemko/nomad.git
synced 2026-01-07 10:55:42 +03:00
* Move commands from docs to its own root-level directory * temporarily use modified dev-portal branch with nomad ia changes * explicitly clone nomad ia exp branch * retrigger build, fixed dev-portal broken build * architecture, concepts and get started individual pages * fix get started section destinations * reference section * update repo comment in website-build.sh to show branch * docs nav file update capitalization * update capitalization to force deploy * remove nomad-vs-kubernetes dir; move content to what is nomad pg * job section * Nomad operations category, deploy section * operations category, govern section * operations - manage * operations/scale; concepts scheduling fix * networking * monitor * secure section * remote auth-methods folder and move up pages to sso; linkcheck * Fix install2deploy redirects * fix architecture redirects * Job section: Add missing section index pages * Add section index pages so breadcrumbs build correctly * concepts/index fix front matter indentation * move task driver plugin config to new deploy section * Finish adding full URL to tutorials links in nav * change SSO to Authentication in nav and file system * Docs NomadIA: Move tutorials into NomadIA branch (#26132) * Move governance and policy from tutorials to docs * Move tutorials content to job-declare section * run jobs section * stateful workloads * advanced job scheduling * deploy section * manage section * monitor section * secure/acl and secure/authorization * fix example that contains an unseal key in real format * remove images from sso-vault * secure/traffic * secure/workload-identities * vault-acl change unseal key and root token in command output sample * remove lines from sample output * fix front matter * move nomad pack tutorials to tools * search/replace /nomad/tutorials links * update acl overview with content from deleted architecture/acl * fix spelling mistake * linkcheck - fix broken links * fix link to Nomad variables tutorial * fix link to Prometheus tutorial * move who uses Nomad to use cases page; move spec/config shortcuts add dividers * Move Consul out of Integrations; move namespaces to govern * move integrations/vault to secure/vault; delete integrations * move ref arch to docs; rename Deploy Nomad back to Install Nomad * address feedback * linkcheck fixes * Fixed raw_exec redirect * add info from /nomad/tutorials/manage-jobs/jobs * update page content with newer tutorial * link updates for architecture sub-folders * Add redirects for removed section index pages. Fix links. * fix broken links from linkcheck * Revert to use dev-portal main branch instead of nomadIA branch * build workaround: add intro-nav-data.json with single entry * fix content-check error * add intro directory to get around Vercel build error * workound for emtpry directory * remove mdx from /intro/ to fix content-check and git snafu * Add intro index.mdx so Vercel build should work --------- Co-authored-by: Tu Nguyen <im2nguyen@gmail.com>
1344 lines
37 KiB
Plaintext
1344 lines
37 KiB
Plaintext
---
|
|
layout: docs
|
|
page_title: Use workload identities with Vault
|
|
description: |-
|
|
Configure Vault to accept Nomad workload identities, run a Nomad job to read
|
|
secrets from Vault, configure dynamic secrets in Vault, and run a job with a
|
|
custom Vault ACL role.
|
|
---
|
|
|
|
# Use workload identities with Vault
|
|
|
|
Nomad integrates with Vault to retrieve [static][vault_static] and
|
|
[dynamic][vault_dyn] secrets for workloads.
|
|
|
|
Production deployments of Nomad and Vault must always run with the Access
|
|
Control List (ACL) system enabled since it protects against unauthorized
|
|
access to the cluster. When ACLs are enabled, both Nomad and Vault must be
|
|
properly configured in order for their integrations to work.
|
|
|
|
Nomad can generate [workload identities][nomad_wid] for tasks, which are
|
|
represented as [JSON Web Tokens (JWT)][jwt] signed by Nomad. These identities
|
|
can be used as proof to third parties that a workload was actually created and
|
|
is managed by Nomad. If the third party is configured to trust Nomad, it can
|
|
automatically grant specific access and permissions to Nomad workloads.
|
|
|
|
In this guide, you will:
|
|
|
|
- Start a Nomad and Vault agent with ACL enabled.
|
|
- Generate ACL tokens to access Nomad and Vault.
|
|
- Configure Vault to accept workload identities from Nomad.
|
|
- Configure Nomad to automatically generate and sign workload identities for
|
|
tasks that need access to Vault.
|
|
- Deploy sample Nomad jobs that interact with Vault.
|
|
|
|
## Prerequisites
|
|
|
|
This guide requires you to have basic familiarity with Nomad and Vault. If
|
|
you are new to these tools, complete the [Nomad Get Started][nomad_gs]
|
|
and [Vault Get Started][vault_gs] tutorials before following this one.
|
|
|
|
You will need the following tools installed:
|
|
|
|
- [Nomad 1.7 or later installed locally][nomad_install]
|
|
- [Vault 1.12 or later installed locally][vault_install]
|
|
- [Docker installed and running locally][docker_install]
|
|
|
|
## Start the Vault agent
|
|
|
|
Start a Vault dev server.
|
|
|
|
```shell-session
|
|
$ vault server -dev
|
|
==> Vault server configuration:
|
|
|
|
Administrative Namespace:
|
|
Api Address: http://127.0.0.1:8200
|
|
Cgo: disabled
|
|
Cluster Address: https://127.0.0.1:8201
|
|
Environment Variables: CLICOLOR, COLORTERM, COMMAND_MODE, EDITOR, GODEBUG, GOPATH, HOME, LANG, LC_ALL, LOGNAME, LSCOLORS, LaunchInstanceID, OLDPWD, PATH, PWD, SECURITYSESSIONID, SHELL, SHLVL, SSH_AUTH_SOCK, TERM, TERM_PROGRAM, TERM_PROGRAM_VERSION, TMPDIR, USER, WINDOWID, XPC_FLAGS, XPC_SERVICE_NAME, _, __CFBundleIdentifier, __CF_USER_TEXT_ENCODING
|
|
Go Version: go1.21.3
|
|
Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
|
|
Log Level:
|
|
Mlock: supported: false, enabled: false
|
|
Recovery Mode: false
|
|
Storage: inmem
|
|
Version: Vault v1.15.2, built 2023-11-06T11:33:28Z
|
|
Version Sha: cf1b5cafa047bc8e4a3f93444fcb4011593b92cb
|
|
|
|
==> Vault server started! Log data will stream in below:
|
|
|
|
2023-11-20T20:08:27.583-0500 [INFO] proxy environment: http_proxy="" https_proxy="" no_proxy=""
|
|
2023-11-20T20:08:27.583-0500 [INFO] incrementing seal generation: generation=1
|
|
...
|
|
WARNING! dev mode is enabled! In this mode, Vault runs entirely in-memory
|
|
and starts unsealed with a single unseal key. The root token is already
|
|
authenticated to the CLI, so you can immediately begin using Vault.
|
|
|
|
You may need to set the following environment variables:
|
|
|
|
$ export VAULT_ADDR='http://127.0.0.1:8200'
|
|
|
|
...
|
|
```
|
|
|
|
<Note title="Dev Agents">
|
|
|
|
This guide uses development agents for Vault and [Nomad][nomad_dev] as a
|
|
quick way to get started. Dev agents have ephemeral state and should not be
|
|
used in production environments. They also run in the foreground of your
|
|
terminal so do not close the terminal window or you will need to rerun the
|
|
agent configuration steps again.
|
|
|
|
</Note>
|
|
|
|
Copy the value for `Root Token`.
|
|
|
|
Open another terminal window in the same directory and set the root token as
|
|
the environment variable `VAULT_TOKEN`. This terminal will act as the main
|
|
terminal session where you will run commands.
|
|
|
|
<Tabs>
|
|
<Tab heading="Linux" group="linux">
|
|
|
|
```shell-session
|
|
$ export VAULT_TOKEN=...
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="macOS" group="mac">
|
|
|
|
```shell-session
|
|
$ export VAULT_TOKEN=...
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="Windows" group="win">
|
|
|
|
```shell-session
|
|
$ $Env:VAULT_TOKEN = "..."
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
Set the environment variable `VAULT_ADDR`.
|
|
|
|
<Tabs>
|
|
<Tab heading="Linux" group="linux">
|
|
|
|
```shell-session
|
|
$ export VAULT_ADDR='http://127.0.0.1:8200'
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="macOS" group="mac">
|
|
|
|
```shell-session
|
|
$ export VAULT_ADDR='http://127.0.0.1:8200'
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="Windows" group="win">
|
|
|
|
```shell-session
|
|
$ $Env:VAULT_ADDR = "http://127.0.0.1:8200"
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
## Start the Nomad agent
|
|
|
|
Create a file named `nomad.hcl`. Add the following contents to it and save the
|
|
file.
|
|
|
|
<Tabs>
|
|
<Tab heading="Linux" group="linux">
|
|
<CodeBlockConfig filename="nomad.hcl">
|
|
|
|
```hcl
|
|
acl {
|
|
enabled = true
|
|
}
|
|
|
|
vault {
|
|
enabled = true
|
|
address = "http://127.0.0.1:8200"
|
|
|
|
default_identity {
|
|
aud = ["vault.io"]
|
|
ttl = "1h"
|
|
}
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
</Tab>
|
|
<Tab heading="macOS" group="mac">
|
|
<CodeBlockConfig filename="nomad.hcl">
|
|
|
|
```hcl
|
|
acl {
|
|
enabled = true
|
|
}
|
|
|
|
vault {
|
|
enabled = true
|
|
address = "http://127.0.0.1:8200"
|
|
|
|
default_identity {
|
|
aud = ["vault.io"]
|
|
ttl = "1h"
|
|
}
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
</Tab>
|
|
<Tab heading="Windows" group="win">
|
|
<CodeBlockConfig filename="nomad.hcl">
|
|
|
|
```hcl
|
|
acl {
|
|
enabled = true
|
|
}
|
|
|
|
vault {
|
|
enabled = true
|
|
address = "http://127.0.0.1:8200"
|
|
|
|
default_identity {
|
|
aud = ["vault.io"]
|
|
ttl = "1h"
|
|
}
|
|
}
|
|
|
|
plugin "docker" {
|
|
config {
|
|
allow_caps = [
|
|
"CHOWN", "DAC_OVERRIDE", "FSETID", "FOWNER", "MKNOD",
|
|
"SETGID", "SETUID", "SETFCAP", "SETPCAP", "NET_BIND_SERVICE",
|
|
"SYS_CHROOT", "KILL", "AUDIT_WRITE", "NET_RAW",
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
The [`vault`][nomad_config_vault] block in this configuration file provides
|
|
the information necessary for Nomad to connect to Vault.
|
|
|
|
It also defines a default workload identity, `default_identity`, that is
|
|
automatically added to jobs that need access to Vault. Without this identity,
|
|
you would need to define an `identity` block in your jobs for every task that
|
|
needs access to Vault.
|
|
|
|
Open another terminal window in the same directory and start the Nomad dev
|
|
agent.
|
|
|
|
<Tabs>
|
|
<Tab heading="Linux" group="linux">
|
|
|
|
```shell-session
|
|
$ sudo nomad agent -dev -config 'nomad.hcl'
|
|
==> Loaded configuration from nomad.hcl
|
|
==> Starting Nomad agent...
|
|
==> Nomad agent configuration:
|
|
|
|
Advertise Addrs: HTTP: 127.0.0.1:4646; RPC: 127.0.0.1:4647; Serf: 127.0.0.1:4648
|
|
Bind Addrs: HTTP: [127.0.0.1:4646]; RPC: 127.0.0.1:4647; Serf: 127.0.0.1:4648
|
|
Client: true
|
|
Log Level: DEBUG
|
|
Node Id: af9bef00-2e83-b704-2d6c-c62bc005431f
|
|
Region: global (DC: dc1)
|
|
Server: true
|
|
Version: 1.7.0
|
|
|
|
==> Nomad agent started! Log data will stream in below:
|
|
...
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="macOS" group="mac">
|
|
|
|
```shell-session
|
|
$ nomad agent -dev -config 'nomad.hcl' -network-interface '{{GetDefaultInterfaces | attr "name"}}'
|
|
==> Loaded configuration from nomad.hcl
|
|
==> Starting Nomad agent...
|
|
==> Nomad agent configuration:
|
|
|
|
Advertise Addrs: HTTP: 127.0.0.1:4646; RPC: 127.0.0.1:4647; Serf: 127.0.0.1:4648
|
|
Bind Addrs: HTTP: [127.0.0.1:4646]; RPC: 127.0.0.1:4647; Serf: 127.0.0.1:4648
|
|
Client: true
|
|
Log Level: DEBUG
|
|
Node Id: af9bef00-2e83-b704-2d6c-c62bc005431f
|
|
Region: global (DC: dc1)
|
|
Server: true
|
|
Version: 1.7.0
|
|
|
|
==> Nomad agent started! Log data will stream in below:
|
|
...
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="Windows" group="win">
|
|
|
|
```shell-session
|
|
$ nomad agent -dev -config 'nomad.hcl' -network-interface '{{GetDefaultInterfaces | attr \"name\"}}'
|
|
==> Loaded configuration from nomad.hcl
|
|
==> Starting Nomad agent...
|
|
==> Nomad agent configuration:
|
|
|
|
Advertise Addrs: HTTP: 127.0.0.1:4646; RPC: 127.0.0.1:4647; Serf: 127.0.0.1:4648
|
|
Bind Addrs: HTTP: [127.0.0.1:4646]; RPC: 127.0.0.1:4647; Serf: 127.0.0.1:4648
|
|
Client: true
|
|
Log Level: DEBUG
|
|
Node Id: af9bef00-2e83-b704-2d6c-c62bc005431f
|
|
Region: global (DC: dc1)
|
|
Server: true
|
|
Version: 1.7.0
|
|
|
|
==> Nomad agent started! Log data will stream in below:
|
|
...
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
Return to your main terminal window and bootstrap the Nomad ACL system.
|
|
|
|
```shell-session
|
|
$ nomad acl bootstrap
|
|
Accessor ID = d1de8625-8556-0932-a25c-3aa71bfc0134
|
|
Secret ID = 7f10099a-936c-3f3a-8783-f0980493e54b
|
|
Name = Bootstrap Token
|
|
Type = management
|
|
Global = true
|
|
Create Time = 2023-11-16 01:09:26.565422 +0000 UTC
|
|
Expiry Time = <none>
|
|
Create Index = 23
|
|
Modify Index = 23
|
|
Policies = n/a
|
|
Roles = n/a
|
|
```
|
|
|
|
Copy the value of `Secret ID` and set it as the environment variable
|
|
`NOMAD_TOKEN`.
|
|
|
|
<Tabs>
|
|
<Tab heading="Linux" group="linux">
|
|
|
|
```shell-session
|
|
$ export NOMAD_TOKEN=...
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="macOS" group="mac">
|
|
|
|
```shell-session
|
|
$ export NOMAD_TOKEN=...
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="Windows" group="win">
|
|
|
|
```shell-session
|
|
$ $Env:NOMAD_TOKEN = "..."
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
<Note title="Using Bootstrap Tokens">
|
|
|
|
The initial ACL bootstrap tokens from Vault and Nomad have full access to the
|
|
cluster and should not be used for regular day-to-day operations in a
|
|
production environment. They are used in this guide as an illustration.
|
|
We recommend creating [ACL policies][nomad_acl_policies] and
|
|
[tokens][nomad_acl_tokens] with only a level of access necessary to perform the
|
|
required operations.
|
|
|
|
</Note>
|
|
|
|
## Configure Vault to accept Nomad workload identities
|
|
|
|
### Create a Vault ACL auth method
|
|
|
|
Enable a `jwt` [auth method][vault_auth_method] in Vault under the path
|
|
`jwt-nomad`.
|
|
|
|
```shell-session
|
|
$ vault auth enable -path 'jwt-nomad' 'jwt'
|
|
Success! Enabled jwt auth method at: jwt-nomad/
|
|
```
|
|
|
|
The JWT auth method creates an endpoint that Nomad clients use to exchange
|
|
Nomad workload identity JWTs for Vault ACL tokens.
|
|
|
|
Create a file named `vault-auth-method-jwt-nomad.json`. Add the following
|
|
contents to it and save the file.
|
|
|
|
<CodeBlockConfig filename="vault-auth-method-jwt-nomad.json">
|
|
|
|
```json
|
|
{
|
|
"jwks_url": "http://127.0.0.1:4646/.well-known/jwks.json",
|
|
"jwt_supported_algs": ["RS256", "EdDSA"],
|
|
"default_role": "nomad-workloads"
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
This configuration file contains important information.
|
|
|
|
* `jwks_url` is the URL that Vault uses to contact Nomad and retrieve the data
|
|
necessary to validate Nomad workload identities. In a production environment,
|
|
this should resolve to multiple Nomad agents via a reverse proxy, load
|
|
balancer, or DNS entry to prevent a single point of failure.
|
|
* `default_role` is the Vault ACL role applied by default to tokens generated
|
|
by this auth method. You will create the `nomad-workloads` role in the next
|
|
section.
|
|
|
|
Apply the configuration file `vault-auth-method-jwt-nomad.json` to the
|
|
`jwt-nomad` auth method.
|
|
|
|
```shell-session
|
|
$ vault write auth/jwt-nomad/config '@vault-auth-method-jwt-nomad.json'
|
|
Success! Data written to: auth/jwt-nomad/config
|
|
```
|
|
|
|
### Create a Vault ACL role
|
|
|
|
Create a file named `vault-role-nomad-workloads.json`. Add the following
|
|
contents to it and save the file.
|
|
|
|
<CodeBlockConfig filename="vault-role-nomad-workloads.json">
|
|
|
|
```json
|
|
{
|
|
"role_type": "jwt",
|
|
"bound_audiences": ["vault.io"],
|
|
"user_claim": "/nomad_job_id",
|
|
"user_claim_json_pointer": true,
|
|
"claim_mappings": {
|
|
"nomad_namespace": "nomad_namespace",
|
|
"nomad_job_id": "nomad_job_id",
|
|
"nomad_task": "nomad_task"
|
|
},
|
|
"token_type": "service",
|
|
"token_policies": ["nomad-workloads"],
|
|
"token_period": "30m",
|
|
"token_explicit_max_ttl": 0
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
It defines properties for the Vault ACL tokens that are used for Nomad tasks.
|
|
|
|
* `bound_audiences` configures Vault to only accept JWTs that have an audience
|
|
value of `vault.io`. It must match the `aud` value present in the Nomad agent
|
|
configuration and jobs.
|
|
* `claim_mappings` are values from the Nomad workload identity. You will
|
|
reference them when creating the Vault ACL policy for this role.
|
|
* `token_period` determines how long the token is valid for before it expires.
|
|
Nomad automatically renews tokens before they expire.
|
|
* `token_explicit_max_ttl` is the maximum amount of time the token is valid. It
|
|
must be set to `0` so Nomad can renew them for as long as the workload runs.
|
|
* `token_policies` are the ACL policies applied to the tokens. They specify the
|
|
permissions that tokens with this role have. You will create the policy
|
|
`nomad-workloads` policy in the next section.
|
|
|
|
Create a Vault ACL role named `nomad-workloads` using the
|
|
`vault-role-nomad-workloads.json` file.
|
|
|
|
```shell-session
|
|
$ vault write auth/jwt-nomad/role/nomad-workloads '@vault-role-nomad-workloads.json'
|
|
Success! Data written to: auth/jwt-nomad/role/nomad-workloads
|
|
```
|
|
|
|
This role is applied by default to Vault ACL tokens generated from the auth
|
|
method `jwt-nomad`.
|
|
|
|
### Create a Vault ACL policy
|
|
|
|
List all of the auth methods registered in Vault.
|
|
|
|
```shell-session
|
|
$ vault auth list
|
|
Path Type Accessor Description Version
|
|
---- ---- -------- ----------- -------
|
|
jwt-nomad/ jwt auth_jwt_d34481ad n/a n/a
|
|
token/ token auth_token_510d42ca token based credentials n/a
|
|
```
|
|
|
|
Copy the `Accessor` value for the auth method in the `jwt-nomad/` path.
|
|
|
|
Create a file named `vault-policy-nomad-workloads.hcl`. Add the following
|
|
contents to it, replace all the instances of the `AUTH_METHOD_ACCESSOR`
|
|
placeholder with the `Accessor` value from the output, and save the file. There
|
|
are five occurrences to update.
|
|
|
|
<CodeBlockConfig filename="vault-policy-nomad-workloads.hcl">
|
|
|
|
```hcl
|
|
path "kv/data/{{identity.entity.aliases.AUTH_METHOD_ACCESSOR.metadata.nomad_namespace}}/{{identity.entity.aliases.AUTH_METHOD_ACCESSOR.metadata.nomad_job_id}}/*" {
|
|
capabilities = ["read"]
|
|
}
|
|
|
|
path "kv/data/{{identity.entity.aliases.AUTH_METHOD_ACCESSOR.metadata.nomad_namespace}}/{{identity.entity.aliases.AUTH_METHOD_ACCESSOR.metadata.nomad_job_id}}" {
|
|
capabilities = ["read"]
|
|
}
|
|
|
|
path "kv/metadata/{{identity.entity.aliases.AUTH_METHOD_ACCESSOR.metadata.nomad_namespace}}/*" {
|
|
capabilities = ["list"]
|
|
}
|
|
|
|
path "kv/metadata/*" {
|
|
capabilities = ["list"]
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
This file is a [templated Vault ACL policy][vault_tpl_policy] that
|
|
automatically grants Nomad workloads access to secrets based on the
|
|
properties mapped in the `claim_mappings` of the Vault ACL role.
|
|
|
|
More specifically, this policy grants access to secrets in the path
|
|
`kv/data/<job namespace>/<job name>/*` where `<job namespace>` and `<job name>`
|
|
are dynamically set for each workload.
|
|
|
|
Create a Vault ACL policy named `nomad-workloads` using the file
|
|
`vault-policy-nomad-workloads.hcl`.
|
|
|
|
```shell-session
|
|
$ vault policy write 'nomad-workloads' 'vault-policy-nomad-workloads.hcl'
|
|
Success! Uploaded policy: nomad-workloads
|
|
```
|
|
|
|
## Run a Nomad job to read secrets from Vault
|
|
|
|
Start a MongoDB database with a root password that is read from Vault using the
|
|
Nomad workload identity for the task.
|
|
|
|
Enable the `kv` secret engine.
|
|
|
|
```shell-session
|
|
$ vault secrets enable -version '2' 'kv'
|
|
Success! Enabled the kv secrets engine at: kv/
|
|
```
|
|
|
|
Write a secret in Vault for the database root password in the path
|
|
`default/mongo/config`.
|
|
|
|
```shell-session
|
|
$ vault kv put -mount 'kv' 'default/mongo/config' 'root_password=secret-password'
|
|
======== Secret Path ========
|
|
kv/data/default/mongo/config
|
|
|
|
======= Metadata =======
|
|
Key Value
|
|
--- -----
|
|
created_time 2023-11-21T02:52:42.061092Z
|
|
custom_metadata <nil>
|
|
deletion_time n/a
|
|
destroyed false
|
|
version 1
|
|
```
|
|
|
|
Create a file named `mongo.nomad.hcl`. Add the following contents to it and
|
|
save the file.
|
|
|
|
<Tabs>
|
|
<Tab heading="Linux" group="linux">
|
|
<CodeBlockConfig filename="mongo.nomad.hcl">
|
|
|
|
```hcl
|
|
job "mongo" {
|
|
namespace = "default"
|
|
|
|
group "db" {
|
|
network {
|
|
port "db" {
|
|
static = 27017
|
|
}
|
|
}
|
|
|
|
service {
|
|
provider = "nomad"
|
|
name = "mongo"
|
|
port = "db"
|
|
}
|
|
|
|
task "mongo" {
|
|
driver = "docker"
|
|
|
|
config {
|
|
image = "mongo:7"
|
|
ports = ["db"]
|
|
}
|
|
|
|
vault {}
|
|
|
|
template {
|
|
data = <<EOF
|
|
MONGO_INITDB_ROOT_USERNAME=root
|
|
MONGO_INITDB_ROOT_PASSWORD={{with secret "kv/data/default/mongo/config"}}{{.Data.data.root_password}}{{end}}
|
|
EOF
|
|
destination = "secrets/env"
|
|
env = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
</Tab>
|
|
<Tab heading="macOS" group="mac">
|
|
<CodeBlockConfig filename="mongo.nomad.hcl">
|
|
|
|
```hcl
|
|
job "mongo" {
|
|
namespace = "default"
|
|
|
|
group "db" {
|
|
network {
|
|
port "db" {
|
|
static = 27017
|
|
}
|
|
}
|
|
|
|
service {
|
|
provider = "nomad"
|
|
name = "mongo"
|
|
port = "db"
|
|
}
|
|
|
|
task "mongo" {
|
|
driver = "docker"
|
|
|
|
config {
|
|
image = "mongo:7"
|
|
ports = ["db"]
|
|
}
|
|
|
|
vault {}
|
|
|
|
template {
|
|
data = <<EOF
|
|
MONGO_INITDB_ROOT_USERNAME=root
|
|
MONGO_INITDB_ROOT_PASSWORD={{with secret "kv/data/default/mongo/config"}}{{.Data.data.root_password}}{{end}}
|
|
EOF
|
|
destination = "secrets/env"
|
|
env = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
</Tab>
|
|
<Tab heading="Windows" group="win">
|
|
<CodeBlockConfig filename="mongo.nomad.hcl">
|
|
|
|
```hcl
|
|
job "mongo" {
|
|
namespace = "default"
|
|
|
|
group "db" {
|
|
network {
|
|
port "db" {
|
|
static = 27017
|
|
}
|
|
}
|
|
|
|
service {
|
|
provider = "nomad"
|
|
name = "mongo"
|
|
port = "db"
|
|
}
|
|
|
|
task "mongo" {
|
|
driver = "docker"
|
|
|
|
config {
|
|
image = "mongo:7"
|
|
ports = ["db"]
|
|
|
|
mount {
|
|
type = "bind"
|
|
target = "C:\\mongosh"
|
|
source = "local/mongosh/mongosh-2.1.0-win32-x64/"
|
|
}
|
|
}
|
|
|
|
vault {}
|
|
|
|
template {
|
|
data = <<EOF
|
|
MONGO_INITDB_ROOT_USERNAME=root
|
|
MONGO_INITDB_ROOT_PASSWORD={{with secret "kv/data/default/mongo/config"}}{{.Data.data.root_password}}{{end}}
|
|
EOF
|
|
destination = "secrets/env"
|
|
env = true
|
|
}
|
|
|
|
artifact {
|
|
source = "https://downloads.mongodb.com/compass/mongosh-2.1.0-win32-x64.zip"
|
|
destination = "local/mongosh"
|
|
}
|
|
|
|
resources {
|
|
memory = 1000
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
* The `vault` block indicates that the task needs access to Vault and that
|
|
Nomad should use the task workload identity to get a Vault ACL token.
|
|
* The `template` block reads the root password secret from Vault under the
|
|
path `kv/data/default/mongo/config`.
|
|
* The job runs in the Nomad `default` namespace and the job name is `mongo`.
|
|
The `nomad-workloads` Vault role grants access to secrets in the path
|
|
`kv/data/default/mongo/*`, which is where the root password exists.
|
|
* The job does not specify any identity for Vault, so Nomad uses the
|
|
`default_identity` from the agent configuration.
|
|
|
|
Run the job with the `mongo.nomad.hcl` file and wait for the deployment to
|
|
complete.
|
|
|
|
```shell-session
|
|
$ nomad job run 'mongo.nomad.hcl'
|
|
==> 2023-11-20T22:09:16-05:00: Monitoring evaluation "34e72e7a"
|
|
2023-11-20T22:09:16-05:00: Evaluation triggered by job "mongo"
|
|
2023-11-20T22:09:17-05:00: Evaluation within deployment: "919f658b"
|
|
2023-11-20T22:09:17-05:00: Allocation "49fc68d8" created: node "b8db12d2", group "db"
|
|
2023-11-20T22:09:17-05:00: Evaluation status changed: "pending" -> "complete"
|
|
==> 2023-11-20T22:09:17-05:00: Evaluation "34e72e7a" finished with status "complete"
|
|
==> 2023-11-20T22:09:17-05:00: Monitoring deployment "919f658b"
|
|
✓ Deployment "919f658b" successful
|
|
|
|
2023-11-20T22:09:28-05:00
|
|
ID = 919f658b
|
|
Job ID = mongo
|
|
Job Version = 0
|
|
Status = successful
|
|
Description = Deployment completed successfully
|
|
|
|
Deployed
|
|
Task Group Desired Placed Healthy Unhealthy Progress Deadline
|
|
db 1 1 1 0 2023-11-20T22:19:26-05:00
|
|
```
|
|
|
|
<Tabs>
|
|
<Tab heading="Linux" group="linux">
|
|
|
|
Verify that you are able to execute a query against the database using the
|
|
`root` user credentials.
|
|
|
|
```shell-session
|
|
$ nomad alloc exec "$(nomad job allocs -t '{{with (index . 0)}}{{.ID}}{{end}}' 'mongo')" mongosh --username 'root' --password 'secret-password' --eval 'db.runCommand({connectionStatus : 1})' --quiet
|
|
{
|
|
authInfo: {
|
|
authenticatedUsers: [ { user: 'root', db: 'admin' } ],
|
|
authenticatedUserRoles: [ { role: 'root', db: 'admin' } ]
|
|
},
|
|
ok: 1
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="macOS" group="mac">
|
|
|
|
Verify that you are able to execute a query against the database using the
|
|
`root` user credentials.
|
|
|
|
```shell-session
|
|
$ nomad alloc exec "$(nomad job allocs -t '{{with (index . 0)}}{{.ID}}{{end}}' 'mongo')" mongosh --username 'root' --password 'secret-password' --eval 'db.runCommand({connectionStatus : 1})' --quiet
|
|
{
|
|
authInfo: {
|
|
authenticatedUsers: [ { user: 'root', db: 'admin' } ],
|
|
authenticatedUserRoles: [ { role: 'root', db: 'admin' } ]
|
|
},
|
|
ok: 1
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="Windows" group="win">
|
|
|
|
Create the `root` user, reading the credentials from the environment variables
|
|
set in the job from the Vault secret.
|
|
|
|
```shell-session
|
|
$ nomad alloc exec "$(nomad job allocs -t '{{with (index . 0)}}{{.ID}}{{end}}' 'mongo')" powershell -command 'C:\mongosh\bin\mongosh.exe mongodb://localhost:27017/admin --quiet --eval ""db.createUser({user: ''$Env:MONGO_INITDB_ROOT_USERNAME'', pwd: ''$Env:MONGO_INITDB_ROOT_PASSWORD'', roles: [{role: ''root'', db: ''admin''}]})""'
|
|
{ ok: 1 }
|
|
```
|
|
|
|
Verify that you are able to execute a query against the database using the
|
|
`root` user credentials.
|
|
|
|
```shell-session
|
|
$ nomad alloc exec "$(nomad job allocs -t '{{with (index . 0)}}{{.ID}}{{end}}' 'mongo')" C:\mongosh\bin\mongosh.exe 'mongodb://localhost:27017' --username 'root' --password 'secret-password' --eval 'db.runCommand({connectionStatus : 1})' --quiet
|
|
{
|
|
authInfo: {
|
|
authenticatedUsers: [ { user: 'root', db: 'admin' } ],
|
|
authenticatedUserRoles: [ { role: 'root', db: 'admin' } ]
|
|
},
|
|
ok: 1
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
|
|
Retrieve the job definition from Nomad and filter the output to only display
|
|
its task.
|
|
|
|
```shell-session
|
|
$ nomad job inspect -t '{{sprig_toPrettyJson (index (index .TaskGroups 0).Tasks 0)}}' 'mongo'
|
|
{
|
|
"Name": "mongo",
|
|
"Driver": "docker",
|
|
"User": "",
|
|
"Lifecycle": null,
|
|
"Config": {
|
|
"image": "mongo:7",
|
|
"ports": [
|
|
"db"
|
|
]
|
|
},
|
|
...
|
|
```
|
|
|
|
The `Identities` list contains the workload identity that Nomad injects
|
|
following the specification in the `default_identity` block from the Nomad
|
|
server configuration file.
|
|
|
|
<CodeBlockConfig highlight="13-26" hideClipboard>
|
|
|
|
```json
|
|
{
|
|
"Name": "mongo",
|
|
"Driver": "docker",
|
|
"User": "",
|
|
"Lifecycle": null,
|
|
"Config": {
|
|
"image": "mongo:7",
|
|
"ports": [
|
|
"db"
|
|
]
|
|
},
|
|
...
|
|
"Identities": [
|
|
{
|
|
"Name": "vault_default",
|
|
"Audience": [
|
|
"vault.io"
|
|
],
|
|
"ChangeMode": "",
|
|
"ChangeSignal": "",
|
|
"Env": false,
|
|
"File": false,
|
|
"ServiceName": "",
|
|
"TTL": 3600000000000
|
|
}
|
|
],
|
|
"Actions": null
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
By configuring Vault to accept workload identities from Nomad, the Nomad task
|
|
was able to automatically receive a Vault ACL token scoped to the level of
|
|
access defined by the auth method default role. With this method, Nomad agents
|
|
no longer require long-lived, highly permissive Vault tokens.
|
|
|
|
## Configure Vault dynamic secrets for MongoDB
|
|
|
|
The MongoDB database reads a secret from Vault using the permissions in the
|
|
default Vault ACL role.
|
|
|
|
In some situations, it may be necessary to customize the permissions granted to
|
|
a task to be different from this default. This is done by creating additional
|
|
Vault ACL roles for Nomad jobs.
|
|
|
|
Configure Vault with a [dynamic secret][vault_dyn] for a non-root MongoDB user
|
|
that the default Vault ACL policy does not grant access to then run a Nomad job
|
|
using a custom Vault ACL role to be able to access the dynamic secret.
|
|
|
|
Enable the Vault database secrets engine.
|
|
|
|
```shell-session
|
|
$ vault secrets enable database
|
|
Success! Enabled the database secrets engine at: database/
|
|
```
|
|
|
|
<Tabs>
|
|
<Tab heading="Linux" group="linux">
|
|
|
|
Create a file named `vault-dynamic-secret-mongo.json`. Add the following
|
|
contents to it and save the file.
|
|
|
|
<CodeBlockConfig filename="vault-dynamic-secret-mongo.json">
|
|
|
|
```json
|
|
{
|
|
"plugin_name": "mongodb-database-plugin",
|
|
"allowed_roles": "mongo",
|
|
"connection_url": "mongodb://{{username}}:{{password}}@127.0.0.1:27017/admin",
|
|
"username": "root",
|
|
"password": "secret-password"
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
</Tab>
|
|
<Tab heading="macOS" group="mac">
|
|
|
|
Retrieve the IP address for MongoDB from Nomad.
|
|
|
|
```shell-session
|
|
$ nomad service info mongo
|
|
Job ID Address Tags Node ID Alloc ID
|
|
mongo 192.168.0.171:27017 [] b8db12d2 49fc68d8
|
|
```
|
|
|
|
Create a file named `vault-dynamic-secret-mongo.json`. Add the following
|
|
contents to it, replace the placeholder `MONGO_IP` text with the IP address
|
|
from the Nomad `service info` command, and save the file.
|
|
|
|
<CodeBlockConfig filename="vault-dynamic-secret-mongo.json">
|
|
|
|
```json
|
|
{
|
|
"plugin_name": "mongodb-database-plugin",
|
|
"allowed_roles": "mongo",
|
|
"connection_url": "mongodb://{{username}}:{{password}}@MONGO_IP:27017/admin",
|
|
"username": "root",
|
|
"password": "secret-password"
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
</Tab>
|
|
<Tab heading="Windows" group="win">
|
|
|
|
Retrieve the IP address for MongoDB from Nomad.
|
|
|
|
```shell-session
|
|
$ nomad service info mongo
|
|
Job ID Address Tags Node ID Alloc ID
|
|
mongo 192.168.0.171:27017 [] b8db12d2 49fc68d8
|
|
```
|
|
|
|
Create a file named `vault-dynamic-secret-mongo.json`. Add the following
|
|
contents to it, replace the placeholder `MONGO_IP` text with the IP address
|
|
from the Nomad `service info` command, and save the file.
|
|
|
|
<CodeBlockConfig filename="vault-dynamic-secret-mongo.json">
|
|
|
|
```json
|
|
{
|
|
"plugin_name": "mongodb-database-plugin",
|
|
"allowed_roles": "mongo",
|
|
"connection_url": "mongodb://{{username}}:{{password}}@MONGO_IP:27017/admin",
|
|
"username": "root",
|
|
"password": "secret-password"
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
Write the `vault-dynamic-secret-mongo.json` configuration for the MongoDB
|
|
dynamic secret to connect to the database.
|
|
|
|
```shell-session
|
|
$ vault write 'database/config/mongo' '@vault-dynamic-secret-mongo.json'
|
|
Success! Data written to: database/config/mongo
|
|
```
|
|
|
|
Create a file named `vault-database-role-mongo.json`. Add the following
|
|
contents to it and save the file.
|
|
|
|
<CodeBlockConfig filename="vault-database-role-mongo.json">
|
|
|
|
```json
|
|
{
|
|
"db_name": "mongo",
|
|
"creation_statements": "{ \"db\": \"admin\", \"roles\": [{ \"role\": \"readWrite\" }, {\"role\": \"read\", \"db\": \"foo\"}] }",
|
|
"default_ttl": "1h",
|
|
"max_ttl": "24h"
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
Create a Vault database role using the `vault-database-role-mongo.json` file.
|
|
|
|
```shell-session
|
|
$ vault write 'database/roles/mongo' '@vault-database-role-mongo.json'
|
|
Success! Data written to: database/roles/mongo
|
|
```
|
|
|
|
### Create a Vault ACL role to access the dynamic secret
|
|
|
|
Create a file named `vault-role-mongo-dynamic-secret.json`. Add the following
|
|
contents to it and save the file.
|
|
|
|
<CodeBlockConfig filename="vault-role-mongo-dynamic-secret.json">
|
|
|
|
```json
|
|
{
|
|
"role_type": "jwt",
|
|
"bound_audiences": ["vault.io"],
|
|
"bound_claims": {
|
|
"nomad_namespace": "default",
|
|
"nomad_job_id": "mongo-query"
|
|
},
|
|
"user_claim": "/nomad_job_id",
|
|
"user_claim_json_pointer": true,
|
|
"claim_mappings": {
|
|
"nomad_namespace": "nomad_namespace",
|
|
"nomad_job_id": "nomad_job_id",
|
|
"nomad_task": "nomad_task"
|
|
},
|
|
"token_type": "service",
|
|
"token_policies": ["mongo-dynamic-secret"],
|
|
"token_period": "30m",
|
|
"token_explicit_max_ttl": 0
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
This role is similar to the one from earlier in the guide but this one uses
|
|
a different policy, called `mongo-dynamic-secret`, which you will create in the
|
|
next section.
|
|
|
|
It also defines a set of `bound_claims` to restrict which workload identities
|
|
from Nomad are able to use this role. In this example, the role only allows the
|
|
job `mongo-query` in the Nomad namespace `default` to use it.
|
|
|
|
Create the `mongo-dynamic-secret` ACL role using the
|
|
`vault-role-mongo-dynamic-secret.json` file.
|
|
|
|
```shell-session
|
|
$ vault write 'auth/jwt-nomad/role/mongo-dynamic-secret' '@vault-role-mongo-dynamic-secret.json'
|
|
Success! Data written to: auth/jwt-nomad/role/mongo-dynamic-secret
|
|
```
|
|
|
|
Create a file named `vault-policy-mongo-dynamic-secret.hcl`. Add the following
|
|
contents to it and save the file.
|
|
|
|
<CodeBlockConfig filename="vault-policy-mongo-dynamic-secret.hcl">
|
|
|
|
```hcl
|
|
path "database/creds/mongo" {
|
|
capabilities = ["read"]
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
This ACL policy only grants access to the specific path `database/creds/mongo`,
|
|
which is not included in the default role used by the `jwt-nomad` auth method.
|
|
|
|
Create the `mongo-dynamic-secret` ACL policy using the
|
|
`vault-policy-mongo-dynamic-secret.hcl` file.
|
|
|
|
```shell-session
|
|
$ vault policy write 'mongo-dynamic-secret' 'vault-policy-mongo-dynamic-secret.hcl'
|
|
Success! Uploaded policy: mongo-dynamic-secret
|
|
```
|
|
|
|
## Run a Nomad job with a custom Vault ACL role
|
|
|
|
Create a file named `mongo-query.nomad.hcl`. Add the following contents to it
|
|
and save the file.
|
|
|
|
<Tabs>
|
|
<Tab heading="Linux" group="linux">
|
|
<CodeBlockConfig filename="mongo-query.nomad.hcl">
|
|
|
|
```hcl
|
|
job "mongo-query" {
|
|
namespace = "default"
|
|
type = "batch"
|
|
|
|
group "mongo-query" {
|
|
task "mongo-query" {
|
|
driver = "docker"
|
|
|
|
config {
|
|
image = "mongo:7"
|
|
command = "mongosh"
|
|
args = [
|
|
"--username", "${MONGO_USERNAME}",
|
|
"--password", "${MONGO_PASSWORD}",
|
|
"--eval", "db.runCommand({connectionStatus : 1})",
|
|
"--quiet",
|
|
"${MONGO_URL}",
|
|
]
|
|
}
|
|
|
|
vault {
|
|
role = "mongo-dynamic-secret"
|
|
}
|
|
|
|
template {
|
|
data = <<EOF
|
|
{{with secret "database/creds/mongo"}}
|
|
MONGO_USERNAME={{.Data.username}}
|
|
MONGO_PASSWORD={{.Data.password}}
|
|
{{end}}
|
|
{{range nomadService 1 (env "NOMAD_ALLOC_ID") "mongo"}}
|
|
MONGO_URL=mongodb://{{.Address}}:{{.Port}}
|
|
{{end}}
|
|
EOF
|
|
destination = "secrets/env"
|
|
env = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
</Tab>
|
|
<Tab heading="macOS" group="mac">
|
|
<CodeBlockConfig filename="mongo-query.nomad.hcl">
|
|
|
|
```hcl
|
|
job "mongo-query" {
|
|
namespace = "default"
|
|
type = "batch"
|
|
|
|
group "mongo-query" {
|
|
task "mongo-query" {
|
|
driver = "docker"
|
|
|
|
config {
|
|
image = "mongo:7"
|
|
command = "mongosh"
|
|
args = [
|
|
"--username", "${MONGO_USERNAME}",
|
|
"--password", "${MONGO_PASSWORD}",
|
|
"--eval", "db.runCommand({connectionStatus : 1})",
|
|
"--quiet",
|
|
"${MONGO_URL}",
|
|
]
|
|
}
|
|
|
|
vault {
|
|
role = "mongo-dynamic-secret"
|
|
}
|
|
|
|
template {
|
|
data = <<EOF
|
|
{{with secret "database/creds/mongo"}}
|
|
MONGO_USERNAME={{.Data.username}}
|
|
MONGO_PASSWORD={{.Data.password}}
|
|
{{end}}
|
|
{{range nomadService 1 (env "NOMAD_ALLOC_ID") "mongo"}}
|
|
MONGO_URL=mongodb://{{.Address}}:{{.Port}}
|
|
{{end}}
|
|
EOF
|
|
destination = "secrets/env"
|
|
env = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
</Tab>
|
|
<Tab heading="Windows" group="win">
|
|
<CodeBlockConfig filename="mongo-query.nomad.hcl">
|
|
|
|
```hcl
|
|
job "mongo-query" {
|
|
namespace = "default"
|
|
type = "batch"
|
|
|
|
group "mongo-query" {
|
|
task "mongo-query" {
|
|
driver = "docker"
|
|
|
|
config {
|
|
image = "mongo:7"
|
|
command = "C:\\mongosh\\bin\\mongosh.exe"
|
|
args = [
|
|
"--username", "${MONGO_USERNAME}",
|
|
"--password", "${MONGO_PASSWORD}",
|
|
"--eval", "db.runCommand({connectionStatus : 1})",
|
|
"--quiet",
|
|
"${MONGO_URL}",
|
|
]
|
|
|
|
mount {
|
|
type = "bind"
|
|
target = "C:\\mongosh"
|
|
source = "local/mongosh/mongosh-2.1.0-win32-x64/"
|
|
}
|
|
}
|
|
|
|
vault {
|
|
role = "mongo-dynamic-secret"
|
|
}
|
|
|
|
template {
|
|
data = <<EOF
|
|
{{with secret "database/creds/mongo"}}
|
|
MONGO_USERNAME={{.Data.username}}
|
|
MONGO_PASSWORD={{.Data.password}}
|
|
{{end}}
|
|
{{range nomadService 1 (env "NOMAD_ALLOC_ID") "mongo"}}
|
|
MONGO_URL=mongodb://{{.Address}}:{{.Port}}
|
|
{{end}}
|
|
EOF
|
|
destination = "secrets/env"
|
|
env = true
|
|
}
|
|
|
|
artifact {
|
|
source = "https://downloads.mongodb.com/compass/mongosh-2.1.0-win32-x64.zip"
|
|
destination = "local/mongosh"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
Note that the `vault` block specifies the `mongo-dynamic-secret` role. The task
|
|
can only access the dynamic credentials for MongoDB.
|
|
|
|
The `template` block reads these credentials and exposes them as environment
|
|
variables to the task so it can use them.
|
|
|
|
Run the Nomad job from the file `mongo-query.nomad.hcl`.
|
|
|
|
```shell-session
|
|
$ nomad job run 'mongo-query.nomad.hcl'
|
|
==> 2023-11-20T23:11:35-05:00: Monitoring evaluation "5fa56c67"
|
|
2023-11-20T23:11:35-05:00: Evaluation triggered by job "mongo-query"
|
|
2023-11-20T23:11:36-05:00: Allocation "909f0184" created: node "b8db12d2", group "mongo-query"
|
|
2023-11-20T23:11:36-05:00: Evaluation status changed: "pending" -> "complete"
|
|
==> 2023-11-20T23:11:36-05:00: Evaluation "5fa56c67" finished with status "complete"
|
|
```
|
|
|
|
Retrieve the allocation information and wait until the status is `complete`.
|
|
You may need to run the command a few times before the status changes to
|
|
`complete`.
|
|
|
|
```shell-session
|
|
$ nomad job allocs 'mongo-query'
|
|
ID Node ID Task Group Version Desired Status Created Modified
|
|
909f0184 b8db12d2 mongo-query 0 run complete 25s ago 24s ago
|
|
```
|
|
|
|
Retrieve the query result to confirm the job was able to connect to the MongoDB
|
|
database.
|
|
|
|
```shell-session
|
|
$ nomad alloc logs $(nomad job allocs -t '{{with (index . 0)}}{{.ID}}{{end}}' mongo-query)
|
|
{
|
|
authInfo: {
|
|
authenticatedUsers: [
|
|
{
|
|
user: 'v-jwt-nomad-mongo-mongo-QbF7HWHjwOi6PJWmNo1x-1700544973',
|
|
db: 'admin'
|
|
}
|
|
],
|
|
authenticatedUserRoles: [ { role: 'readWrite', db: 'admin' }, { role: 'read', db: 'foo' } ]
|
|
},
|
|
ok: 1
|
|
}
|
|
```
|
|
|
|
Note that the authenticated user is now a dynamic user credential.
|
|
|
|
Templated Vault ACL policies provide great flexibility when defining access
|
|
rules, but a single policy, or a specific group of policies, may not be enough
|
|
to cover all use cases.
|
|
|
|
Creating additional Vault ACL roles for specific Nomad jobs can help better
|
|
manage access control to Vault secrets.
|
|
|
|
## Next steps
|
|
|
|
In this guide, you configured Nomad and Vault to communicate with ACL
|
|
enabled. You also configured Nomad to automatically add workload identities for
|
|
tasks that need access to Vault.
|
|
|
|
You then deployed Nomad jobs to read static and dynamic secrets from Vault
|
|
using different Vault ACL roles and policies. Both jobs used their workload
|
|
identities to receive a Vault ACL token properly scoped to the work they
|
|
needed to do.
|
|
|
|
This process required several steps, with certain values having to match each
|
|
other in order for everything to work properly.
|
|
|
|
There are two resources available to help you automate these steps.
|
|
|
|
* The Nomad CLI command `nomad setup vault` can be useful for a quick setup
|
|
with default values for a development or test cluster.
|
|
* The [`hashicorp-modules/nomad-setup/vault`][tf_module] Terraform module
|
|
provides a basis for applying these steps with a infrastructure-as-code
|
|
approach, which is more suitable for a production environment. The
|
|
[`hashicorp-guides/nomad-workload-identity-terraform-demo`][tf_demo]
|
|
repository demonstrates how this module can be used.
|
|
|
|
You may continue exploring additional integrations between Nomad and Vault or
|
|
learn how to similarly [integrate Nomad and Consul][nomad_consul_acl] with ACL
|
|
enabled.
|
|
|
|
- [Nomad and Vault Integration][nomad_integrations_vault]
|
|
- [Nomad Workload Identity][nomad_wid]
|
|
- [Nomad Agent `vault` Configuration][nomad_config_vault]
|
|
- [Vault ACL policies tutorial][vault_tutorial_policies]
|
|
|
|
[docker_install]: https://www.docker.com/get-started/
|
|
[jwt]: https://jwt.io/
|
|
[nomad_acl_policies]: /nomad/docs/secure/acl/policies
|
|
[nomad_acl_tokens]: /nomad/docs/secure/acl/tokens
|
|
[nomad_config_vault]: /nomad/docs/configuration/vault
|
|
[nomad_consul_acl]: /nomad/tutorials/integrate-consul/consul-acl
|
|
[nomad_dev]: /nomad/commands/agent#dev
|
|
[nomad_gs]: /nomad/tutorials/get-started
|
|
[nomad_install]: /nomad/install
|
|
[nomad_integrations_vault]: /nomad/docs/secure/vault
|
|
[nomad_wid]: /nomad/docs/concepts/workload-identity
|
|
[tf_demo]: https://github.com/hashicorp-guides/nomad-workload-identity-terraform-demo
|
|
[tf_module]: https://registry.terraform.io/modules/hashicorp-modules/nomad-setup/vault
|
|
[vault_auth_method]: /vault/docs/auth
|
|
[vault_dyn]: /vault/docs/use-cases#dynamic-secrets
|
|
[vault_gs]: /vault/tutorials/get-started
|
|
[vault_install]: /vault/install
|
|
[vault_static]: /vault/docs/use-cases#static-secrets
|
|
[vault_tpl_policy]: /vault/docs/concepts/policies#templated-policies
|
|
[vault_tutorial_policies]: /vault/tutorials/policies
|